I'm building a Spring MVC service using Spring Boot and want to be able to return strings as plain text encoded in UTF-8. Following this description, I thought the only thing necessary should be to add the bean method
@Bean
public HttpMessageConverter<String> responseBodyConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8"))));
return converter;
}
But the root
method in
@Controller
public class RootController {
@RequestMapping(value="/"/*, produces="text/plain;charset=UTF-8"*/)
@ResponseBody
public String root() {
return "æøå";
}
}
responds the string æøå
in ISO-8859-1 instead of UTF-8, unless I uncomment the produces
part, in which case it actually returns UTF-8. The message converter doesn't seems to have any effect here.
Following this approach I confirm that the bean has actually been registered. Besides this bean, I also register an EmbeddedServletContainerFactory
and CharacterEncodingFilter
as described in another question, although I don't think that's relevant here.
Can someone explain what the registered HttpMessageConverter
actually does, and how to make @ResponseBody
-annotated controller methods return UTF-8 without having to provide produces
every time?
Edit
As discussed in the comments, for the accepted answer to work, I had to upgrade the version of Spring Boot from 0.5.0.M6
to 0.5.0.BUILD-SNAPSHOT
and, to prevent outputting a junk header, call converter.setWriteAcceptCharset(false)
on the StringHttpMessageConverter
.
The default character set for the
StringHttpMessageConverter
isISO-8859-1
. That means when a client does not request a specific character set, thenISO-8859-1
will be returned.If you want
UTF-8
to be the default character set then you pass it into the constructor:Calling
setSupportedMediaTypes()
is then no longer necessary either astext/plain; charset=default character set
is added automatically.