Non Required JSON attribute in Spring (Jackson Mapping) - json

I have this function in a Spring controller:
#RequestMapping(value = "/*", method = RequestMethod.POST)
#ResponseBody
#Consumes("application/json")
public JSONresponse alta(#RequestBody JSONrequest parametros, HttpServletRequest request) {
some code...}
JSON request is a JavaClass like this:
public class JSONrequest {
private String code;
private String message;
//getters and setter}
I'm using Jackson to map this, and works correctly. But my question is: It's possible make message attribute non required? I would like the web service to accept JSON with both attributes or only with the "code" attribute

You can use required property of JsonProperty. But this property is available from 2.7.x or higher versions.
public class JSONrequest {
#JsonProperty(value ="CODE",required = true)
private String code;
#JsonProperty(value ="MESSAGE",required = false)
private String message;
Above example makes code attribute as mandatory while message as an optional field for deserialization.

Related

JSON parse error: Cannot deserialize when using spring RestTemplate.exhange

I am new to JSON and spring. Was able to write simple examples consuming REST webservices. But as I apply to realtime scenario, the JSON is nested, and I don't have control in changing the structure.
Below code giving me Parse Error. Cannot deserialize instance of pg.domain.LookupDo[] out of START_OBJECT token
LookupDo[] lookupDos = template.exchange(url, HttpMethod.GET, request, LookupDo[].class).getBody();
How do I structure domain object?
#JsonIgnoreProperties
public class LookupDo {
private String companyCode;
private String plant;
private String category;
private String value;
private String descr;
You need to match your class with your JSON structure
Response res = template.exchange(url, HttpMethod.GET, request, Response.class).getBody();
LookupDo[] lookupDos = res.getD().getResults();
public class Response{
private Data d;
...
}
public class Data{
private LookupDo[] results;
...
}

Spring Boot REST multi part request (file + json) throwing 415 Unsupported Media Type exception

I am using spring boot version = 1.5.2.RELEASE.
When I am sending multi part file with json object to upload file in postman, It throwing 415 Unsupported Media Type exception.
This is my controller class.
#RestController
#RequestMapping("/service/promotion/")
public class JobController {
....
....
....
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> createJobTest(#Valid #RequestBody JobRequest jobRequest,
#RequestParam(value = "file", required = false) MultipartFile multiPartFile) throws Exception {
My json request class.
public class JobRequest {
private String campaignKey;
private String communicationId;
private Integer channelId;
private String templateType;
private String subject;
private String frequencyControl;
private Integer leadsRequested;
private String keywordRelavance;
private String scheduledAt;
private String file;
private String updatedBy;
//getter and setter
}
Json request in postman
Multipart file request in postman
Header Content-type
But when I removed consumes from controller class and from postman as well like
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json")
then debugger coming in controller class but multi part file value coming
null in request object like
I googled a lot there are many similar questions which already posted but none of them helped me.
Please help me to sort out this mystery.
Thank you.
Check this File upload along with other object in Jersey restful web service
Another way is you can pass whole object in text like you are passing file in form-data and convert in object.
#RequestMapping(value = "/uploadDocs", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> methodName(#RequestParam("files") MultipartFile file, #RequestParam("anyKeyName") String objectString)
Than you can convert string to object using
Class object = new ObjectMapper().readValue(objectString, Class.class);

Post request with json string as body and add validation to it

I am trying to add string input to spring boot application. The content type is json and I am trying to add validation to it.
#RestController
#RequestMapping(value = "/entries")
public class SampleController {
#RequestMapping(method = RequestMethod.DELETE)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void delete(#RequestBody #NotBlank(message = "{field.required}") String username) throws Exception {
//some logic
}
}
For some reasons, #Notblank annotation does not work.
Is it right way to do it.
one way to go would be creating a model/dto class and defining your #NotBlank on a String in this class. then just change your controller-code like this:
#RequestMapping(method = RequestMethod.DELETE)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void delete(#RequestBody #Valid MyClass myClass) throws Exception {
...
}
For more insights, look here
You can't use those validations on method parameters.
You need to bind your parameter onto an object if you want validation. Then, you just have to add #Valid annotation.
See this example.

how do you define custom serializer for list of object before adding it to modelAttribute in Spring 4?

#Controller
public class ManageEmployee{
#ModelAttribute("employeeForm")
public EmployeeForm createEmployeeForm(Model model, HttpSession session){
EmployeeForm eform = new EmployeeForm ();
List<EmployeeDTO> eList = employeeService.getEmployeeList(employeeId)//employeeId comes from session
eform.setEmployeeDTO(eList );
model.addAttribute("empoyeeList",eList );
return eform;
}
#RequestMapping(value = LogInUris.MANAGE_EMPLOYEE, method = RequestMethod.GET)
public String showEmployee(Model model, ModelMap map) throws ServiceException{
return "employeeView";
}
}
public class EmployeeDTO{
private String eId;
private String eName;
private String eLastName;
private String positon;
private String role;
//getter//setter
}
when user calls MANAGE_EMPLOYEE url then I return employeeView(jsp) where I have to display list of employees so that user can edit and save it back again. I know I can user #JsonSerialize(using=EmployeeDTOSerializer.class) at my DTO with http request to Controller and annotating #ResponseBody but here I am adding it to model attribute so i want to know how to serialize list of object before i send it to JSP.
You'll have to do it yourself using one of the libraries. For example you could use ObjectMapper from Jackson :
// In configuration:
ObjectMapper mapper=new ObjectMapper();
and
//In Controller
#ModelAttribute("employeeForm")
public EmployeeForm createEmployeeForm(Model model, HttpSession session){
EmployeeForm eform = new EmployeeForm ();
List<EmployeeDTO> eList = employeeService.getEmployeeList(employeeId)//employeeId comes from session
eform.setEmployeeDTO(eList );
model.addAttribute("empoyeeList", mapper.writeValueAsString(eList) );
return eform;
}
This (probably with some modifications) will write json string to the model. However I would not recommend this. I suggest adding an AJAX call to your jsp which would retrieve the list of employees. Then you'll have to add a method to your controller which would return a list and annotate it with #ResponseBody.

Is the a mechanism in Spring MVC to rename bean for JSON

is there a way to rename bean properties in a Spring MVC response, I'm using content negotiation and the response is returned is JSON.
For example, if I have a class with field called 'title'
public class Entity {
#XmlAttribute
private String title;
}
in the JSON that is created I would like it to be displayed as so:
"entity":{
"myCompany:title": "this is the title"
}
#XmlAttribute annotation has name attribute, so I suggest to try with it:-
public class Entity {
#XmlAttribute(name = "myCompany:title")
private String title;
}
Updated: My answer looks wrong. Try following:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Entity {
#XmlElement(name = "myCompany:title")
private String title;
}