Spring @RestController 不返回纯文本响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20575369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:24:45  来源:igfitidea点击:

Spring @RestController not returning plain text response

springrestspring-mvcspring-4

提问by Marcel Overdijk

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

我正在尝试使用新的 Spring 4.0 @RestController 从控制器返回一个简单的文本响应:

@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:

当我访问 /heartbeat 然后我回来:

"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.

当我访问 /heartbeat/test 时,我得到一个空的响应,但我希望我还活着!文本。

UPDATE

更新

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

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

HTTP/1.1 200 OK 内容类型:application/json;charset=UTF-8 服务器:Development/1.0 日期:2013 年 12 月 17 日星期二 18:59:08 GMT 缓存控制:无缓存过期:1990 年 1 月 1 日星期五00:00:00 GMT 内容长度:12

"I'm Alive!"

“我还活着!”

curl -i -H "Accept: application/json" http://myserver.com/rest/heartbeatHTTP/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

curl -i -H "Accept: application/json" http://myserver.com/rest/heartbeatHTTP/1.1 200 OK 内容类型:application/json;charset=UTF-8 服务器:Development/1.0 日期:周二, 2013 年 12 月 17 日 19:01:12 GMT 缓存控制:无缓存过期:1990 年 1 月 1 日星期五 00:00:00 GMT 内容长度:12

"I'm Alive!"

“我还活着!”

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

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

HTTP/1.1 406 不可接受服务器:Development/1.0 日期:2013 年 12 月 17 日星期二 19:00:13 GMT 缓存控制:no-cache 过期:1990 年 1 月 1 日星期五 00:00:00 GMT 内容长度:0

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

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

HTTP/1.1 406 不可接受服务器:Development/1.0 日期:2013 年 12 月 17 日星期二 19:02:06 GMT 缓存控制:no-cache 过期:1990 年 1 月 1 日星期五 00:00:00 GMT 内容长度:0

回答by Marcel Overdijk

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

我发现我的 WebConfig 的 configureMessageConverters 中缺少 StringHttpMessageConverter。我正在配置消息转换器来控制 Hymanson ObjectMapper。

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

回答by englishteeth

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

@RestController 是一个方便的注释,这意味着您不再需要在方法上指定 @ResponseBody 注释。

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

但这意味着您的响应类型默认为 JSON,因此用引号括起来以正确形成。

回答by Brian Clozel

@RestControllercombines @Controllerand @ResponseBodyon your Controller class, as stated in the documentation.

@RestController文档中所述,结合@Controller@ResponseBody在您的 Controller 类上。

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

当您使用 注释方法/控制器时@ResponseBody,Spring 会使用AcceptHTTP 请求标头和produces注释上的属性帮助您进行内容协商。

In your case:

在你的情况下:

  • You get an application/jsonresponse 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/plainas a produces Content-Type on your Controller, whereas your HTTP client probably lists only application/jsonin its Acceptrequest header.
  • 您会收到application/json心跳操作的响应,因为您的 HTTP 客户端可能会要求提供该 Content-Type,而 Spring 进行了内容协商。
  • 您的 heartbeat2 操作会收到 HTTP 406,因为内容协商失败。您text/plain在控制器上指定了一个生产内容类型,而您的 HTTP 客户端可能仅application/json在其Accept请求标头中列出。

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?

更新:我使用了完全相同的 curl 请求,但没有得到相同的结果。也许过滤器或 HTTP 代理缓存正在修改 HTTP 标头?

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/plainattribute:

并带有一个produces text/plain属性:

? 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 applicationdoes the same thing and get good results.

此示例应用程序执行相同的操作并获得良好的结果。

回答by F?rat Kü?üK

This solution worked for me. Please check the followings.

这个解决方案对我有用。请检查以下内容。

  1. Ensure your DTO is serializable and has serializable fields, getters and setters
  2. Check the dependencies for Hymanson. You should have
    • com.fasterxml.Hymanson.core:Hymanson-core:2.4.1
    • com.fasterxml.Hymanson.core:Hymanson-databind:2.4.1
    • com.fasterxml.Hymanson.core:Hymanson-annotations:2.4.1
    • com.fasterxml.Hymanson.datatype:Hymanson-datatype-joda:2.4.1
    • com.fasterxml.Hymanson.datatype:Hymanson-datatype-jsr310:2.4.1
  3. Fix the RequesMapping Annotation:

    @RequestMapping(value = "/test", consumes = "*/*")

  4. Check you have <mvc:annotation-driven />directive

  1. 确保您的 DTO 是可序列化的并且具有可序列化的字段、getter 和 setter
  2. 检查 Hymanson 的依赖项。你应该有
    • com.fasterxml.Hymanson.core:Hymanson-core:2.4.1
    • com.fasterxml.Hymanson.core:Hymanson-databind:2.4.1
    • com.fasterxml.Hymanson.core:Hymanson-annotations:2.4.1
    • com.fasterxml.Hymanson.datatype:Hymanson-datatype-joda:2.4.1
    • com.fasterxml.Hymanson.datatype:Hymanson-datatype-jsr310:2.4.1
  3. 修复 RequesMapping 注解:

    @RequestMapping(value = "/test", consumes = "*/*")

  4. 检查你有<mvc:annotation-driven />指令

回答by cn123h

This works for me:

这对我有用:

  1. add this in maven

    com.fasterxml.Hymanson.core Hymanson-databind 2.4.4

  2. make sure <mvc:annotation-driven />is configured in spring

  1. 在 Maven 中添加这个

    com.fasterxml.Hymanson.core Hyman逊数据绑定 2.4.4

  2. 确保<mvc:annotation-driven />在 spring 中配置