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
Spring @RestController not returning plain text response
提问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 onlyapplication/jsonin itsAcceptrequest 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.
这个解决方案对我有用。请检查以下内容。
- Ensure your DTO is serializable and has serializable fields, getters and setters
- 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
Fix the RequesMapping Annotation:
@RequestMapping(value = "/test", consumes = "*/*")Check you have
<mvc:annotation-driven />directive
- 确保您的 DTO 是可序列化的并且具有可序列化的字段、getter 和 setter
- 检查 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
修复 RequesMapping 注解:
@RequestMapping(value = "/test", consumes = "*/*")检查你有
<mvc:annotation-driven />指令
回答by cn123h
This works for me:
这对我有用:
add this in maven
com.fasterxml.Hymanson.core Hymanson-databind 2.4.4
make sure
<mvc:annotation-driven />is configured in spring
在 Maven 中添加这个
com.fasterxml.Hymanson.core Hyman逊数据绑定 2.4.4
确保
<mvc:annotation-driven />在 spring 中配置

