How can I configure a Spring Boot RestController to accept YAML uploads?
The following results in a 415. I can see from debugging that the MappingJackson2HttpMessageConverter
instances in my Spring context only support [application/json;charset=UTF-8, application/*+json;charset=UTF-8]
. I can't be the only Spring Boot user trying to do this, and I'm surprised it doesn't just work - most things do in Spring Boot!
I've got the YAML dataformat in my POM:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
My RestController has a method thus:
@RequestMapping(method=RequestMethod.POST, value="/", consumes="application/yaml")
public String upload(@RequestBody Declaration declaration) {
//Do stuff
}
And my test:
@Test
public void triggersConvergence() throws Exception {
ClassPathResource fixture = new ClassPathResource("declaration.yml");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Content-Type", "application/yaml");
requestHeaders.add("Accept", "application/json");
URI uri = new URI("http://127.0.0.1:"+port);
byte[] bytes = new byte[(int)fixture.contentLength()];
fixture.getInputStream().read(bytes);
RequestEntity<byte[]> postRequest = new RequestEntity<byte[]>(bytes, requestHeaders, HttpMethod.POST, uri);
ResponseEntity<String> response = rest.exchange(postRequest, String.class);
assertThat(response.getStatusCode(), is(HttpStatus.OK));
assertThat(response.getBody(), is("Converged org my-lovely-org"));
}
Spring RestController annotation is used to create RESTful web services using Spring MVC. Spring RestController takes care of mapping request data to the defined request handler method. Once response body is generated from the handler method, it converts it to JSON or XML response.
In @RestController, we can not return a view. @Controller annotation indicates that the class is a “controller” like a web controller.
Advantages of Spring Boot:It avoids writing lots of boilerplate Code, Annotations and XML Configuration. It is very easy to integrate Spring Boot Application with its Spring Ecosystem like Spring JDBC, Spring ORM, Spring Data, Spring Security etc.
While this functionality is not available in Spring it's easy to add using YAMLMapper
it in 2 simple steps:
Define your own HttpMessageConverter
that supports Content-Type: application/x-yaml
:
final class YamlJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
YamlJackson2HttpMessageConverter() {
super(new YAMLMapper(), MediaType.parseMediaType("application/x-yaml"));
}
}
Register your converter:
@Configuration
public class YamlConfiguration extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new YamlJackson2HttpMessageConverter());
}
}
Enjoy controller methods consuming and producing application/x-yaml
from POJOs.
Yes, you can do that.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.5.4</version>
</dependency>
@RequestMapping(value = "/my/endpoint", method = RequestMethod.POST, consumes = "application/x-yaml")
@ResponseBody
public ResponseEntity<MyResponse> receiveYaml(@RequestBody final String yaml) {
//unserialize yaml
}
curl -X POST --header "Content-Type: application/x-yaml" --header "Accept: */*" -d "invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to: *id001
product:
- sku : BL394D
quantity : 4
description : Basketball
price : 450.00
- sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
tax : 251.42
total: 4443.52
comments: >
Late afternoon is best.
Backup contact is Nancy
Billsmer @ 338-4338."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With