2016-06-20 121 views
0

我在使用Spring MVC应用程序时无法使用JSON对象。我有以下的春天控制器使用Spring MVC消费JSON对象

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": "[email protected]", 
    "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   

} 

然而,当我尝试张贴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: [email protected]; 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] 

我试图找到解决办法,但到目前为止没有发现我真的帮了(我不是很有经验的春天:-(),所以也许有人在那里可以帮助我吗?

预先感谢 延

编辑1:杰克逊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()); 
    } 
} 
+0

这是因为控制器认为每个字段是根级字段。预计JSON将被包装如下:'“MailResponse”:{......}' – jr593

+0

你能分享你的杰克逊bean配置吗? – Mithun

+0

我添加了jackson bean配置和对象映射器。希望这可以帮助。我怎样才能使用JSON而不将其包装在MailResponse对象中? – JGreven

回答

0

貌似

DeserializationFeature.UNWRAP_ROOT_VALUE, false 

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

好像现在看起来,你不能告诉ObjectMapper根据Spring Controller的不同来处理这个特性。或者至少我找不到方法:-)