Reputation: 175
I am new to spring rest and am having problem to map JSON object from jquery to controller. My jquery JSON object have some field absent which are present in java object on controller. Do I have to create new class to map such object or is there any way to map these objects without creating new class?
Here are the code
Controller:
@RequestMapping(value = "/createTest", method = RequestMethod.POST,consumes="application/json")
@ResponseBody
public String createTest(@RequestBody TestJsonDTO testJson)
throws JsonProcessingException, IOException {
//....
TestJsonDTO:
public class TestJsonDTO {
private TestSet testSet;
private List<MainQuestion> questionsInTest;
//gettters and setters
TestSet:
public class TestSet implements Serializable {
public TestSet() {
}
@Id
@GeneratedValue
private int id;
private String name;
private int fullmark;
private int passmark;
String duration;
Date createDate = new Date();
Date testDate;
boolean isNegativeMarking;
boolean negativeMarkingValue;
MainQuestion:
public class MainQuestion implements Serializable {
private static final long serialVersionUID = 1L;
public MainQuestion() {
}
@Id
@GeneratedValue
private int id;
private String name;
and my jquery post method
function createTest() {
$.ajax({
type : 'POST',
url : "http://localhost:8085/annotationBased/admin/createTest",
dataType : "json",
contentType : "application/json",
data : testToJSON(),
success : function() {
alert("success")
},
error : function(msg) {
alert("error while saving test");
}
});
}
function testToJSON() {
listOfQuestionForTest = questionToAdd;//array of ids of questions
return JSON.stringify({
"testSet.name" : $('#testname').val(),
"testSet.fullmark" : parseInt($('#fullmark').val()),
"testSet.passmark" : parseInt($('#passmark').val()),
"questionsInTest" : listOfQuestionForTest
// "testDate":$('#testDate').value()
})
}
In JSON.stringify
I am not sending all the fields in TestJsonDto
. How can I map this?
Upvotes: 4
Views: 4166
Reputation: 34460
You should configure Spring this way:
@Configuration
public class ServiceContext
extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = this.getMappingJackson2HttpMessageConverter();
converters.add(converter);
}
@Bean
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = this.getObjectMapper();
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
return mappingJackson2HttpMessageConverter;
}
@Bean
public ObjectMapper getObjectMapper() {
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // this is what you need
objectMapper.setSerializationInclusion(Include.NON_NULL); // this is to not serialize unset properties
return objectMapper;
}
}
Here Spring is configured with an ObjectMapper
that doesn't serialize properties whose value is null
and that doesn't fail on deserialization if some property is missing.
EDIT: (Added some background and explanations)
Spring converts what comes in HTTP request's body into a POJO (that's what @RequestBody
actually tells Spring to do). This conversion is performed by a HttpMessageConverter
, which is an abstraction. Spring provides default specific message converters for common media types, such as String
s, JSON, form fields, etc.
In your case, you need to tell Spring how to deserialize the incoming JSON, i.e. how to read the JSON that you're sending from jQuery and how to convert this JSON into the POJO you're expecting to receive in your @Controller
(TestJsonDTO
in your question).
Jackson 2 is a JSON serialization/deserialization library that is widely used. It's most important class is ObjectMapper, which is used to perform the actual serialization and deserialization. Spring has a specific HttpMessageConverter
that uses Jackson in order to serialize and deserialize JSON. This is MappingJackson2HttpMessageConverter
, which can receive a Jackson's ObjectMapper
instance that you can configure if you want to override default behavior.
This ObjectMapper
is configured to not serialize properties that are null
in your POJO (i.e. your JSON won't contain these properties as fields), and more important, when deserializing, it is configured to not fail with an exception if there is a missing property in either your JSON or your POJO. This is what objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
actually does.
Upvotes: 2