'Unable to get different Content-Types in request mapping using Spring Framework
Here is my controller class:
@Controller
@RequestMapping("/actuator")
public class HealthController {
@RequestMapping(value = "/metrics", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON)
@ResponseBody
public HealthModel getDump() throws JsonProcessingException {
return new HealthModel();
//return mapper.writeValueAsString(metrics.invoke());
}
@RequestMapping(value = "/metrics", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN)
@ResponseBody
public String getHealth() {
return "HEALTHY";
}
}
Model:
public class HealthModel {
@JsonProperty
private String status;
@JsonProperty
private int id;
public HealthModel(){
this.status="WARN";
this.id=2;
}
}
Note I have mapped /metrics
to return json
or plain-text
depending on the Accept Header
in the request
When I make request at
curl -v -H "Accept: application/json" http://localhost:8080/myapp/actuator/metrics
I get expected response in json
{"status":"WARN","id":2}
.
However, when I try
curl -v -H "Accept: text/plain" http://localhost:8080/myapp/actuator/metrics
I get HTTP/1.1 406 Not Acceptable
.
EDIT
@EnableWebMvc
@Configuration
public class AppMvcConfig extends WebMvcConfigurerAdapter {
@Resource(name = "appObjectMapper")
private ObjectMapper appObjectMapper;
@Resource(name = "modelObjectMapper")
private ObjectMapper modelObjectMapper;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final MappingJackson2HttpMessageConverter inputConverter = new MappingJackson2HttpMessageConverter();
inputConverter.setObjectMapper(appObjectMapper);
final MappingJackson2HttpMessageConverter outputConverter = new MappingJackson2HttpMessageConverter();
outputConverter.setObjectMapper(modelObjectMapper);
converters.add(new JacksonDualMapperConverter(appObjectMapper, modelObjectMapper));
super.configureMessageConverters(converters);
}
}
Solution 1:[1]
Since you're adding a custom MessageConverter configureMessageConverters
, this turns off default converter registration (see JavaDoc).
So when content negotiation kicks in, you only have one message converter (the Jackson one) that only supports JSON media types and does not know how to handle text/plain
.
You should add a StringHttpMessageConverter to the list in order to support text/plain
.
converters.add(new StringHttpMessageConverter());
Solution 2:[2]
Just in case anyone still gets the Type mismatch: cannot convert from MediaType to String[]
error:
The solution is to use MediaType.APPLICATION_JSON_VALUE
instead of MediaType.APPLICATION_JSON
Regards
Solution 3:[3]
According to the documentation, @ResponseBody
indicates that indicates that the return type should be written straight to the HTTP response body (and not placed in a Model, or interpreted as a view name). So annotation should be there. On the second look, your produces annotation does not seem to be correct.
It should be produces = MediaType.TEXT_PLAIN_VALUE
and not produces = MediaType.TEXT_PLAIN
.
I tried the following and it worked for me:
@RequestMapping(value = "/metrics", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String getHealth() {
return "HEALTHY";
}
You also might have to add StringHttpMessageConverter.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Camilo |
Solution 3 |