2016-06-20 28 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的不同來處理這個特性。或者至少我找不到方法:-)