mardi 28 juin 2016

Consuming JSON Object with Spring MVC

I have trouble consuming a JSON object from within my Spring MVC app. I have the following Spring controller

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

and the JSON object sent to the server is something like the following:

{
   "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"
}

With MailResponse being a simple bean (only 2 attributes for testing for now...):

package de.pma.webservice.model;

public class MailResponse {

    private String event;
    private String time;

    public MailResponse() {
    }

// + getters and setters        

}

However, when I try to post that JSON object to my controller via Postman, I always get the following exception:

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]

I tried finding solutions but so far nothing I found really helped (I am not very experienced with Spring :-( ) so maybe someone out there could help me with this?

Thanks in advance Jens

Edit 1: Jackson bean configuration

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

Edit 2: Jackson object mapper

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

Aucun commentaire:

Enregistrer un commentaire