我有一个使用Sping Boot 和Apache Camel构建的Web应用程序,我正在实现一个REST接口。目前,使用Camel默认的Servlet
或Restlet
组件,我在响应中没有得到HTTP状态代码的原因。
下面是将HTTP状态代码设置为403时得到的响应示例:
< HTTP/1.1 403
< Date: Mon, 19 Feb 2018 10:01:21 GMT
< Server: Restlet-Framework/2.4.0
< Content-Type: application/json
< Content-Length: 75
它应该是:
< HTTP/1.1 403 Forbidden
< Date: Mon, 19 Feb 2018 10:01:21 GMT
< Server: Restlet-Framework/2.4.0
< Content-Type: application/json
< Content-Length: 75
如何配置Camel/Restlet/Servlet以在HTTP状态代码中包含原因?
我的当前配置:
Application.java
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static final Logger appLogger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
appLogger.info("--Application Started--");
}
@Bean
public ServletRegistrationBean servletRegistrationBean() {
SpringServerServlet serverServlet = new SpringServerServlet();
ServletRegistrationBean regBean = new ServletRegistrationBean(serverServlet, "/*");
Map<String,String> params = new HashMap<>();
params.put("org.restlet.component", "restletComponent");
regBean.setInitParameters(params);
return regBean;
}
@Bean
public Component restletComponent() {
return new Component();
}
@Bean
public RestletComponent restletComponentService() {
return new RestletComponent(restletComponent());
}
}
路由配置:
@Component
public class RestRouteBuilder extends RouteBuilder {
private static final Logger appLogger = LoggerFactory.getLogger(RestRouteBuilder.class);
private Predicate isAuthorizedRequest = header(HttpHeaders.AUTHORIZATION).isNotNull();
@Override
public void configure() throws Exception {
restConfiguration().component("restlet")
.contextPath("/overlay")
.bindingMode(RestBindingMode.json)
.skipBindingOnErrorCode(false)
.dataFormatProperty("prettyPrint", "true");
rest("/")
.get()
.route()
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
.setBody(constant("Forbidden"))
.endRest();
}
}
我也尝试添加.setHeader(Exchange.HTTP_RESPONSE_TEXT, constant("Forbidden"))
,但结果是一样的。
3条答案
按热度按时间pw9qyyiw1#
ws51t4hk2#
如何配置Camel/Restlet/Servlet以在HTTP状态代码中包含原因?
如果没有自定义内核,我相信您将无法:
响应是在org.restlet.engine.adapter.ServerCall.sendResponse()中发送的,其中响应头和主体被写入OutputStream:
...并且writeResponseHead(response)默认情况下不执行任何操作,请检查:
更新:... HttpStatus(value,reasonPhrase)具有reasonPhrase,但不用于字符串化:
更新2:...来自Exchange的DefaultRestletBinding.populateRestletResponseFromExchange执行以下操作:
...它只使用Status.值。
虽然有一个Status.reasonPhrase,但它是不可访问的。
答案:
没有自定义内核,
(I believe)
您无法实现!......考虑到以下情况,什么是不合适的:
6.1.1状态代码和原因说明
(...)客户端不需要检查或显示Reason-Phrase。
(...)原因短语(......)可替换为本地等效短语,而不会影响方案。
3.1.2.状态行
(...)客户端应该忽略原因短语的内容。
8.1.2.4.响应伪标头字段
(...)HTTP/2没有定义一种方式来携带版本或原因短语,而版本或原因短语包含在HTTP/1.1状态行中。
需要了解状态代码的含义?
请参阅complete list of status codes maintained by IANA。
kg7wmglp3#
TLDR-使用
.setHeader(Exchange.HTTP_RESPONSE_CODE, 403)
我发现
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
不工作,但.setHeader(Exchange.HTTP_RESPONSE_CODE, 403)
确实如此。请注意
constant
关键字的区别。直接在路由中设置值时,您需要使用constant
,但在处理器中则不需要。因此,只要代码中发生异常,您就可以设置响应状态代码,而不是在路由生成器配置中。