使用Spring MVC使用JSON对象

时间:2016-06-20 15:25:55

标签: java json spring spring-mvc

我在Spring MVC应用程序中使用JSON对象时遇到问题。我有以下Spring控制器

package de.pma.webservice.controller;

@Api(description = "Callback-Schnittstelle zu Mailjet")
@Controller
public class MailjetCallbackController extends BasicController {

    @RequestMapping(
        value = RestURIConstants.MAILJET_CALLBACK, // "mailjet/callback"
        method = RequestMethod.POST) // "The event data is sent in the POST request body using a JSON object. Its content depends on the event."
    public
    @ResponseBody
    ResponseEntity<?>
    mailjetCallback(@RequestBody MailResponse response) {
        try {
            System.out.println(response.toString());
            // TODO business logic
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseEntity(HttpStatus.OK);
    }
}

并且发送到服务器的JSON对象如下所示:

{
   "event": "open",
   "time": 1433103519,
   "MessageID": 19421777396190490,
   "email": "api@mailjet.com",
   "mj_campaign_id": 7173,
   "mj_contact_id": 320,
   "customcampaign": "",
   "CustomID": "helloworld",
   "Payload": "",
   "ip": "127.0.0.1",
   "geo": "US",
   "agent": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0"
}

MailResponse是一个简单的bean(现在只测试2个属性......):

package de.pma.webservice.model;

public class MailResponse {

    private String event;
    private String time;

    public MailResponse() {
    }

// + getters and setters        

}

但是,当我尝试通过Postman将JSON对象发布到我的控制器时,我总是得到以下异常:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Root name 'event' does not match expected ('MailResponse') for type [simple type, class de.pma.webservice.model.MailResponse]
 at [Source: java.io.PushbackInputStream@48429b77; line: 2, column: 4]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Root name 'event' does not match expected ('MailResponse') for type [simple type, class de.pma.webservice.model.MailResponse]

我尝试找到解决方案,但到目前为止我没有发现任何真正的帮助(我对Spring不是很有经验:-()所以也许有人可以帮助我吗?

提前致谢 延

编辑1:Jackson bean配置

package de.pma.webservice.config;

import ....

@ComponentScan("de.pma.webservice.controller")
@Configuration
@EnableWebMvc
@Import(SwaggerConfig.class)
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(converter());
        converters.add(new org.springframework.http.converter.ResourceHttpMessageConverter());
        converters.add(new org.springframework.http.converter.ByteArrayHttpMessageConverter());
    }

    @Bean
    public MappingJackson2HttpMessageConverter converter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(mapper());
        return converter;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public ObjectMapper mapper() {
        return new CustomJacksonObjectMapper();
    }
}

编辑2:杰克逊对象映射器

package de.pma.webservice.mapper;

import ...

public class CustomJacksonObjectMapper extends ObjectMapper {

    public CustomJacksonObjectMapper() {
        super();
        this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        this.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
        this.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.NONE);
        this.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
        this.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);

        this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        setDateFormat(new ISO8601DateFormat());
    }
}

1 个答案:

答案 0 :(得分:0)

看起来像

DeserializationFeature.UNWRAP_ROOT_VALUE, false

真有效。但由于我们的项目中有多个第三方服务,因此无法在全球范围内进行更改。我现在的想法是创建一个单独的Web应用程序来使用mailjet回调并保持Web应用程序的其余部分不受影响。

现在看来,你不能告诉ObjectMapper以不同的方式处理这个功能,而不依赖于Spring Controller。或者至少我找不到方法: - )