Building a REST Server with Spring MVC

Posted by {"name"=>"Palash Ray", "email"=>"paawak@gmail.com", "url"=>"https://www.linkedin.com/in/palash-ray/"} on April 07, 2016 · 3 mins read

We would like to build a REST server with Spring MVC. It should be very simple to support various formats like JSON and XML for the same request, just by changing the Content header. Example, I have the below url:
http://localhost:8090/simple-spring-rest/bank-detail
It should return me either json or xml or some other format depending on the Accept header to application/json or application/xml respectively.
Lets see how to achieve that.

Configuration of Spring MVC

We will use pure Java configuration:

@Configuration
@EnableWebMvc
@ComponentScan("com.swayam.demo.web.rest")
@PropertySource("classpath:jdbc.properties")
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List> converters) {
	Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
	converters.add(new MappingJackson2HttpMessageConverter(jackson2ObjectMapperBuilder.build()));
	Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter = new Jaxb2RootElementHttpMessageConverter();
	converters.add(jaxb2RootElementHttpMessageConverter);
    }
    @Bean
    public ViewResolver viewResolver() {
	InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
	viewResolver.setViewClass(JstlView.class);
	viewResolver.setPrefix("/WEB-INF/jsp/");
	viewResolver.setSuffix(".jsp");
	return viewResolver;
    }
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfig() {
	return new PropertySourcesPlaceholderConfigurer();
    }
}

Note the use of WebMvcConfigurerAdapter. It comes in handy when you want to work with Spring MVC. Especially note worthy is the configureMessageConverters() method. You would use that to configure a REST service. It would define how Spring handles the @ResponseBody or @RestController annotation, to translate a POJO to the response type: json, xml, etc. In the above example, we are using MappingJackson2HttpMessageConverter to convert our POJOs to JSON and Jaxb2RootElementHttpMessageConverter to convert them to XML.

Model

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class BankDetail {
    private int id;
    private int age;
    private String job;
    private String marital;
    private String education;
    private String defaulted;
    private BigDecimal balance;
    private String housing;
    private String loan;
    private String contact;
    private int day;
    private String month;
    private int duration;
    private int campaign;
    private int pdays;
    private int previous;
    private String poutcome;
    private String y;
....
}

Note the use of @XmlRootElement. This is absolutely necessary as we are using Jaxb2RootElementHttpMessageConverter to convert our POJOs to xml. If you omit this, you will get a "Error 406 Not Acceptable" error, the underlying cause being:

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

Controller

@RestController
public class SimpleBankDetailRestController {
    private final BankDetailService bankDetailService;
    @Autowired
    public SimpleBankDetailRestController(BankDetailService bankDetailService) {
	this.bankDetailService = bankDetailService;
    }
    @RequestMapping(path = { "/bank-detail" }, method = { RequestMethod.GET, RequestMethod.POST })
    public BankDetail getBankDetail() {
	return bankDetailService.getBankDetails().get(0);
    }
}

The controller is very simple, and returns the POJO. It is upto the HttpMessageConverter to make sense of it and convert that to either json or xml.
This makes the perfect sense, as the controller can just return the model, and the conversion can be a configuration detail.

Alternate ways of specifying the desired response type

Spring gives us the flexibility of doing away with the Accept header to specify the type of response. If we want json output, we can simply say:
http://localhost:8090/simple-spring-rest/bank-detail.json
For xml, we can similarly say:
http://localhost:8090/simple-spring-rest/bank-detail.xml

Sources

The sources can be found here:
https://github.com/paawak/blog/tree/master/code/simple-spring-rest