如何使用 Apache Camel REST DSL 设置 HTTP 状态代码原因 (Servlet/Restlet)
How to set HTTP Status code reason with Apache Camel REST DSL (Servlet/Restlet)
我有一个使用 Spring Boot with 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"))
,但结果是一样的。
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
.setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
.setBody(constant("Forbidden"))
How can I configure Camel/Restlet/Servlet to include the reason on the HTTP Status code?
没有自定义内核,我相信你做不到:
正在 org.restlet.engine.adapter.ServerCall.sendResponse(), where the response head and body are written to the OutputStream 发送响应:
writeResponseHead(response); // <--
if (responseEntity != null) {
responseEntityStream = getResponseEntityStream();
writeResponseBody(responseEntity, responseEntityStream);
}
... 和 writeResponseHead(response) does nothing by default, check it:
protected void writeResponseHead(Response response) throws IOException {
// Do nothing by default
}
更新: ... HttpStatus(value, reasonPhrase) has the reasonPhrase, but isn't used to stringify:
HttpStatus(int value, String reasonPhrase) {
this.value = value;
this.reasonPhrase = reasonPhrase;
}
...
@Override
public String toString() {
return Integer.toString(this.value);
}
更新 2: ... DefaultRestletBinding.populateRestletResponseFromExchange 执行以下操作:
// get response code
Integer responseCode = out.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
if (responseCode != null) {
response.setStatus(Status.valueOf(responseCode));
}
虽然有 Status.reasonPhrase,但无法访问。
答案:
没有自定义核心,(我相信)你做不到!
...有什么不合适的,鉴于:
6.1.1 Status Code and Reason Phrase
(...) The client is not required to examine or display the Reason-Phrase.
(...) The reason phrases (...) MAY be replaced by local equivalents without affecting the protocol.
3.1.2. Status Line
(...) A client SHOULD ignore the reason-phrase content.
8.1.2.4. Response Pseudo-Header Fields
(...) HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status line.
需要了解状态代码的含义吗?
我有一个使用 Spring Boot with 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"))
,但结果是一样的。
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
.setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
.setBody(constant("Forbidden"))
How can I configure Camel/Restlet/Servlet to include the reason on the HTTP Status code?
没有自定义内核,我相信你做不到:
正在 org.restlet.engine.adapter.ServerCall.sendResponse(), where the response head and body are written to the OutputStream 发送响应:
writeResponseHead(response); // <--
if (responseEntity != null) {
responseEntityStream = getResponseEntityStream();
writeResponseBody(responseEntity, responseEntityStream);
}
... 和 writeResponseHead(response) does nothing by default, check it:
protected void writeResponseHead(Response response) throws IOException {
// Do nothing by default
}
更新: ... HttpStatus(value, reasonPhrase) has the reasonPhrase, but isn't used to stringify:
HttpStatus(int value, String reasonPhrase) {
this.value = value;
this.reasonPhrase = reasonPhrase;
}
...
@Override
public String toString() {
return Integer.toString(this.value);
}
更新 2: ... DefaultRestletBinding.populateRestletResponseFromExchange 执行以下操作:
// get response code
Integer responseCode = out.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
if (responseCode != null) {
response.setStatus(Status.valueOf(responseCode));
}
虽然有 Status.reasonPhrase,但无法访问。
答案:
没有自定义核心,(我相信)你做不到!
...有什么不合适的,鉴于:
6.1.1 Status Code and Reason Phrase
(...) The client is not required to examine or display the Reason-Phrase.
(...) The reason phrases (...) MAY be replaced by local equivalents without affecting the protocol.
3.1.2. Status Line
(...) A client SHOULD ignore the reason-phrase content.
8.1.2.4. Response Pseudo-Header Fields
(...) HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status line.