java - 我们是否必须发布与 Controller 中的 pojo 对象具有完全相同字段的 json 对象?

标签 java javascript jquery json spring

我是 spring rest 的新手,在将 JSON 对象从 jquery 映射到 Controller 时遇到问题。我的 jquery JSON 对象缺少一些字段,这些字段存在于 Controller 上的 java 对象中。我是否必须创建新类来映射此类对象,或者有什么方法可以在不创建新类的情况下映射这些对象?

代码如下

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

测试集:

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;

主要问题:

public class MainQuestion implements Serializable {

private static final long serialVersionUID = 1L;
public MainQuestion() {

}
@Id
@GeneratedValue
private int id;
private String name;

和我的 jquery post 方法

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()
    })

}

JSON.stringify 中,我没有发送 TestJsonDto 中的所有字段。我如何映射它?

最佳答案

你应该这样配置Spring:

@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;
    }
}

这里 Spring 配置了一个 ObjectMapper,它不会序列化值为 null 的属性,如果某些属性丢失,反序列化也不会失败。

编辑:(添加了一些背景和解释)

Spring 将 HTTP 请求主体中的内容转换为 POJO(这就是 @RequestBody 实际上告诉 Spring 要做的事情)。此转换由 HttpMessageConverter 执行,这是一个抽象。 Spring 为常见的媒体类型提供了默认的特定消息转换器,例如 String、JSON、表单字段等。

在您的情况下,您需要告诉 Spring 如何反序列化传入的 JSON,即如何读取您从 jQuery 发送的 JSON 以及如何将此 JSON 转换为您期望在 @Controller(TestJsonDTO 在你的问题中)。

Jackson 2是一个被广泛使用的JSON序列化/反序列化库。它最重要的类是 ObjectMapper ,用于执行实际的序列化和反序列化。 Spring 有一个特定的 HttpMessageConverter,它使用 Jackson 来序列化和反序列化 JSON。这是 MappingJackson2HttpMessageConverter ,它可以接收 Jackson 的 ObjectMapper 实例,如果您想覆盖默认行为,您可以配置该实例。

ObjectMapper 配置为不序列化 POJO 中为 null 的属性(即,您的 JSON 不会将这些属性作为字段包含),更重要的是,当反序列化,如果您的 JSON 或 POJO 中缺少属性,它被配置为不会失败并出现异常。这就是 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 的实际作用。

关于java - 我们是否必须发布与 Controller 中的 pojo 对象具有完全相同字段的 json 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28199272/

相关文章:

Javascript:检查用户是否通过表单提交或简单的链接单击导航离开

javascript - 通过 src 删除图像

javascript - 如何创建按钮并使其在幻灯片中工作?

java - 使用 JDBC 选择 "for update"?

java - 使用java套接字编程查询文件传输

javascript - AngularJS 将复选框绑定(bind)到模型属性

JQuery Mobile 删除幻灯片页面过渡

带有线性渐变的 Java Swing 哑光边框?

java - 使用 log4j 以编程方式创建不同的日志文件

javascript - 如何在 turn.js 中禁用剥离(悬停效果)?