Spring @RestController not returning plain text response

I'm experimenting with the new Spring 4.0 @RestController to return a simple text response from a controller:

@RestController
@RequestMapping(value = "/heartbeat")
public class HeartbeatController {

    private static final Logger logger = LoggerFactory.getLogger(HeartbeatController.class);

    @RequestMapping
    public String heartbeat() {
        logger.info("Received heartbeat!");
        return "I'm Alive!";
    }

    @RequestMapping(value = "/test", produces = MediaType.TEXT_PLAIN_VALUE)
    public String heartbeat2() {
        logger.info("Received heartbeat!");
        return "I'm Alive!";
    }
}

When I access /heartbeat then I get back:

"I'm Alive!"

The result includes the double quotes, what I did not expect.

When I access /heartbeat/test then I get a empty response back, but I expect the I'm Alive! text.

UPDATE

curl -i http://myserver.com/rest/heartbeat

HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Server: Development/1.0 Date: Tue, 17 Dec 2013 18:59:08 GMT Cache-Control: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Content-Length: 12

"I'm Alive!"

curl -i -H "Accept: application/json" http://myserver.com/rest/heartbeat HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Server: Development/1.0 Date: Tue, 17 Dec 2013 19:01:12 GMT Cache-Control: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Content-Length: 12

"I'm Alive!"

curl -i http://myserver.com/rest/heartbeat/test

HTTP/1.1 406 Not Acceptable Server: Development/1.0 Date: Tue, 17 Dec 2013 19:00:13 GMT Cache-Control: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Content-Length: 0

curl -i -H "Accept: text/plain" http://myserver.com/rest/heartbeat/test

HTTP/1.1 406 Not Acceptable Server: Development/1.0 Date: Tue, 17 Dec 2013 19:02:06 GMT Cache-Control: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Content-Length: 0


I found out I was missing the StringHttpMessageConverter in my WebConfig's configureMessageConverters. I was configuring the message converters to control the Jackson ObjectMapper.

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    mappingJackson2HttpMessageConverter.setPrettyPrint(SystemProperty.environment.value() == Development);
    mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper());
    converters.add(mappingJackson2HttpMessageConverter);
    converters.add(new StringHttpMessageConverter()); // THIS WAS MISSING
}

@RestController is a convenience annotation that means you no longer need to specify @ResponseBody annotation on your methods.

But it will mean that your response type is being defaulted to JSON and therefore wrapped in quotes to be properly formed.


@RestController combines @Controller and @ResponseBody on your Controller class, as stated in the documentation.

When you annotate a method/a controller with @ResponseBody , Spring assists you with content negotiation, using the Accept HTTP request header and the produces attribute on your annotation.

In your case:

  • You get an application/json response for your heartbeat action, because your HTTP client probably asks for that Content-Type and Spring did the content negotiation.
  • You get a HTTP 406 for your hearbeat2 action, because content negotiation failed. You specified text/plain as a produces Content-Type on your Controller, whereas your HTTP client probably lists only application/json in its Accept request header.
  • Update : I've used the exact same curl requests but don't get the same results. Maybe a Filter or a HTTP proxy-cache is modifying HTTP headers?

    Default format is text/plain:

    ➜ curl -v http://localhost:8080/heartbeat
    > GET /heartbeat HTTP/1.1
    > User-Agent: curl/7.30.0
    > Host: localhost:8080
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Server: Apache-Coyote/1.1
    < Content-Type: text/plain;charset=ISO-8859-1
    < Content-Length: 13
    < Date: Wed, 18 Dec 2013 13:34:12 GMT
    <
    Hello, World!%
    

    And with a produces text/plain attribute:

    ➜ curl -H "Accept: text/plain" -v http://localhost:8080/heartbeat/test
    > GET /heartbeat/test HTTP/1.1
    > User-Agent: curl/7.30.0
    > Host: localhost:8080
    > Accept: text/plain
    >
    < HTTP/1.1 200 OK
    < Server: Apache-Coyote/1.1
    < Content-Type: text/plain
    < Content-Length: 13
    < Date: Wed, 18 Dec 2013 13:39:07 GMT
    <
    Hello, World!%
    

    This sample application does the same thing and get good results.

    链接地址: http://www.djcxy.com/p/48180.html

    上一篇: 标题类型更改为application / json不变

    下一篇: Spring @RestController不返回纯文本响应