How to handle Request with JSON and Multipart File in spring boot - java

I am trying to create a REST API in the format which will accept request data with both JSON and MultipartFile type.
THis is my request which will be in following format in POSTMAN:
My POJO classes are as follows:
Class:Organisation
public class Organisation
{
priavet int org_id;
private MultipartFile organisationRegistrationDocument;
private Teachers[]
// getters and setters
}
Class: Teachers
class Teachers{
private String teacherId;
private MultipartFile teacherPhoto;
// getters and setters
}
My controller Class is as follows:
#RequestMapping(value="/test",method=RequestMethod.POST,headers = {"content-type=multipart/mixed","content-type=multipart/form-data"})
private ResponseEntity<Object> testUpload(#RequestBody Organisation org) {
return null;
}
Error Thrown from POSTMAN:
{
"timestamp": "2018-10-03T07:38:30.439+0000",
"status": 400,
"error": "Bad Request",
"message": "Required request part 'org' is not present",
"path": "/test"
}
So anyone can kindly guide me what can I am doing wrong due to which I am not able to achieve the desired result to process request of the above form?

Related

How Deserialize data time for response handler REST TEMPLATE?

I am using ResponseErrorHandler interface to handle the server error and client error
I get this response from an external API
{
"timestamp": "2021-08-02T12:04:45.332+0000",
"status": 400,
"error": "Bad Request",
"message": "Null Value Exception",
}
Now I have class where I am deserializing
public class ApplicationPayload {
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime timestamp;
private HttpStatus status;
private String error;
private String message;
//getter and setter
}
#Override
public void handleError(ClientHttpResponse response) throws IOException {}
I am getting this error in handleError method
Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2021-08-02T12:04:45.332+0000' could not be parsed, unparsed text found at index 23

Adding additional field in Response Object

I am getting below response when I am calling an API.
Response postRequestResponse = ConnectionUtil.getwebTarget()
.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true)
.path("bots")
.path(ReadSkillID.readSkillId())
.path("dynamicEntities").path(dynamicEntityID)
.path("pushRequests").path(pushRequestID).path(operation)
.request()
.header("Authorization", "Bearer " + ConnectionUtil.getToken())
.get();
Below output I am getting.
{
"createdOn": "2020-08-17T12:19:13.541Z",
"updatedOn": "2020-08-17T12:19:23.421Z",
"id": "C84B058A-C8F9-41F5-A353-EC2CFE7A1BD9",
"status": "TRAINING",
"statusMessage": "Request Pushed into training, on user request"
}
I have to return this output to client with an additional field in the response. How can modify the above response and make it
{
"EntityName": "NewEntity", //New field
"createdOn": "2020-08-17T12:19:13.541Z",
"updatedOn": "2020-08-17T12:19:23.421Z",
"id": "C84B058A-C8F9-41F5-A353-EC2CFE7A1BD9",
"status": "TRAINING",
"statusMessage": "Request Pushed into training, on user request"
}
I am adding this additional field here
"EntityName": "NewEntity"
How can I do that. many things I tried but got exception.
get JSON from postRequestResponse (i have no idea what framework you are using, so you have to figer it out on your own, but the Response datatype will probably have a getResponseBody or similar method returing the JSON)
add EntityName
serialize it again to json.
class YourBean {
#Autowired
private ObjectMapper objectMapper;
public void yourMethod() {
// 1
final InputStream jsonFromResponse = ...
// 2
Map dataFromResponse = objectMapper.readValue(jsonFromResponse, Map.class);
dataFromResponse.put("EntityName", "NewEntity");
// 3
final String enrichedJson = objectMapper.writeValueAsString(dataFromResponse);
}
}
enrichedJson contains EntityName and whatever comes from the API.

Spring Boot 406 status code for PUT Request

Code is
#RestController
#Component
#Slf4j
public class ServicesController {
#CrossOrigin
#PutMapping(
consumes = "multipart/form-data",
path = "/{id}/{route}/structure_article/{filename:.+}")
public ResponseEntity<ServiceResponse> updateStructureXMLFile(
#PathVariable("id") final String id,
#PathVariable("route") final String route,
#RequestParam("file") final MultipartFile uploadfile,
#PathVariable("filename") final String fileName) throws IOException {
(Some processing)
return new ResponseEntity<>(response, httpHeaders, HttpStatus.CREATED);
}
}
Here response is a POJO with public getters and setters.
enter image description here
When I am putting a file getting this error:
{
"timestamp": 1596783608973,
"status": 406,
"error": "Not Acceptable",
"exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
"message": "Could not find acceptable representation",
"path": "/7f3033d7-3979-45e0-9f0a-172b60568edb/articles/structure_article/manuscript.xml"
}
What can be solution for this?
Thank you
In my case, the Content Negotiation was configured like:
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorPathExtension(true)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
and just like you, I have a controller method with
#PutMapping("/user/{userId:.+}")
So, Spring tries to treat a request /user/email#domain.com for example with the Content-Type of .com file extension which does not exist in the Common MIME types, hence the 406 error.
I resolved it by turning off favorPathExtension.

Missing request param when it is included in body

I am posting a POJO where I get an error saying the field is not included.
Asset POJO
public class Asset {
private MultipartFile[] files;
private String name;
private String meta;
//Constructor/Getters n Setters
}
Resource Method
#PostMapping("asset")
public ResponseEntity uploadAsset(#RequestParam("asset") Asset asset) {
System.out.println(asset);
return new ResponseEntity(HttpStatus.ACCEPTED);
}
PostMan JSON Body
{
"asset" : {
"files": [
"#/home/Downloads/1.jpeg",
"#/home/Downloads/2.jpeg"
],
"name": "assetName",
"meta": "assetMeta"
}
}
PostMan JSON Response
{
"timestamp": "2019-10-29T20:46:19.536+0000",
"status": 400,
"error": "Bad Request",
"message": "Required Asset parameter 'asset' is not present",
"path": "/asset"
}
I don't understand why I get the Required Asset parameter 'asset' is not present message when I have it in the JSON body. Any ideas on this?
Use #RequestBody rather than #RequestParam
public ResponseEntity uploadAsset(#RequestBody Asset asset) {
Based on your payload, Spring is expecting an object that looks like this:
public class SomeClass {
private Asset asset;
}
Change your payload to look like this:
{
"files": [
"#/home/Downloads/1.jpeg",
"#/home/Downloads/2.jpeg"
],
"name": "assetName",
"meta": "assetMeta"
}
RequestParam
Annotation which indicates that a method parameter should be bound to a web request parameter.
RequestBody
Annotation indicating a method parameter should be bound to the body of the web request. The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request. Optionally, automatic validation can be applied by annotating the argument with #Valid.
HttpMessageConverter
Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
You need to check converter dependency. because you using application/json.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
Q : Missing request param when it is included in body
A : Use #RequestBody annotation.
I tried #Jordans answer and the endpoint was called with all values set to null :(
Doing more research I came across this statement https://stackoverflow.com/a/51982230/2199102 and tried it out.
Combining #Jordans answer and then the annotation change, I was able to get the answer I wanted

Spring boot controller - Download Multipart and JSON to DTO

I need get a JAVA Object (DTO) with a MultipartFile in a Spring Controller
I tried different ways, like use of produces = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE} but nothing works.
The "DTO" to get is:
public class TodoDTO {
private Long id;
private String description;
private Boolean status;
private MultipartFile image;
...
}
And the controller method is:
#GetMapping(produces = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<TodoDTO>> getAll() {
ResponseEntity<List<TodoDTO>> response;
try {
response = new ResponseEntity<List<TodoDTO>>(todoService.getAll(), HttpStatus.FOUND);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e);
}
return response;
}
I will expect to get entire object, with Multipart and the other properties. But the response in Postman is:
"status": 406,
"error": "Not Acceptable",
"message": "Could not find acceptable representation",

Categories

Resources