How to return plain text in spring controller?

membersound picture membersound · Oct 29, 2015 · Viewed 15k times · Source

I want to return a simple plain text string as follows:

@RestController 
@RequestMapping("/test")
public class TestController {
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/my", method = RequestMethod.GET, produces="text/plain")
    public String test() {
        return "OK";
    }

Problem: I also have a global ContentNegotiation filter as follows:

@Configuration
public class ContentNegotiationAdapter extends WebMvcConfigurerAdapter {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false)
                .favorParameter(true)
                .ignoreAcceptHeader(true)
                .useJaf(false)
                .defaultContentType(MediaType.APPLICATION_XML);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
    }
}

Result: whenever I access the spring controller, I'm getting the error:

Could not find acceptable representation

Question: how can I force the controller to return plain text, even though only XML was configured within content negotation (which I have to keep)?

Answer

jny picture jny · Oct 29, 2015

If you remove produces="text/plain" from the mapping, it returns plain text but the header is set to "application/xml". This is probably not desirable. I tested with the latest version of Spring Boot.

If you are using the version of Spring >= 4.1.2, you can try to use defaultContentTypeStrategy instead of defaultContentType, to set the correct content type in the header:

   configurer.favorPathExtension(false)
            .favorParameter(true)
            .ignoreAcceptHeader(true)
            .useJaf(false)
            .defaultContentTypeStrategy(new ContentNegotiationStrategy() {
                @Override
                public List<MediaType> resolveMediaTypes(NativeWebRequest nativeWebRequest) throws
                        HttpMediaTypeNotAcceptableException {
                    System.out.println("Description:"+nativeWebRequest.getDescription(false));
                    if (nativeWebRequest.getDescription(false).endsWith("/test/my")) {
                        return Collections.singletonList(MediaType.TEXT_PLAIN);
                    }
                    else {
                        return Collections.singletonList(MediaType.APPLICATION_XML);
                    }
                }
            })
            //.defaultContentType(MediaType.APPLICATION_XML)
;