簡體   English   中英

如何使用 Apache Camel REST DSL (Servlet/Restlet) 設置 HTTP 狀態代碼原因

[英]How to set HTTP Status code reason with Apache Camel REST DSL (Servlet/Restlet)

我有一個使用 Spring Boot 和 Apache Camel 構建的 Web 應用程序,並且我正在實現一個 REST 接口。 目前,使用 Camel 默認ServletRestlet組件,我沒有在響應中獲得 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 狀態代碼中包含原因?

我目前的配置:

應用程序.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"))

如何配置 Camel/Restlet/Servlet 以在 HTTP 狀態代碼中包含原因?

如果沒有自定義核心,我相信你不能:

響應被發送到org.restlet.engine.adapter.ServerCall.sendResponse() ,其中響應頭和正文被寫入 OutputStream

writeResponseHead(response); // <--
if (responseEntity != null) {
    responseEntityStream = getResponseEntityStream();
    writeResponseBody(responseEntity, responseEntityStream);
}

...並且writeResponseHead(response)默認情況下什么都不做檢查一下

protected void writeResponseHead(Response response) throws IOException {
    // Do nothing by default
}

更新: ... HttpStatus(value, reasonPhrase)reasonPhrase ,但不用於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 價值

盡管有一個Status.reasonPhrase ,但它是不可訪問的。


回答:

沒有自定義核心, 你不能!


...考慮到以下情況,這不是不合適的:

6.1.1 狀態碼和原因短語

(...) 客戶不需要檢查或顯示原因短語。

(...) 原因短語 (...) 可以替換為本地等效項,而不影響協議。

3.1.2。 狀態行

(...) 客戶端應該忽略原因短語內容。

8.1.2.4。 響應偽標頭字段

(...) HTTP/2 沒有定義攜帶包含在 HTTP/1.1 狀態行中的版本或原因短語的方法。

需要知道狀態碼的含義嗎?

請參閱IANA 維護的狀態代碼的完整列表

TLDR - 使用.setHeader(Exchange.HTTP_RESPONSE_CODE, 403)

我發現

.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))不起作用但

.setHeader(Exchange.HTTP_RESPONSE_CODE, 403)

注意constant的關鍵字差異。 直接在路由中設置值時需要使用constant ,但例如在處理器中則不需要。 因此,您可以在代碼中發生異常時設置響應狀態代碼,而不是在路由構建器配置中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM