Tengo una aplicación web creada con Spring Boot con Apache Camel y estoy implementando una interfaz REST. Actualmente, utilizando el componente predeterminado Servlet o Restlet de Camel, no obtengo el motivo del código de estado HTTP en la respuesta.

Aquí hay una respuesta de ejemplo que obtengo al configurar el código de estado HTTP en 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

Como debería ser:

< 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

¿Cómo puedo configurar Camel / Restlet / Servlet para incluir el motivo en el código de estado HTTP?

Mi configuración actual:

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());
    }

}

Configuración de ruta:

@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();
    }
}

También intenté agregar .setHeader(Exchange.HTTP_RESPONSE_TEXT, constant("Forbidden")) pero el resultado fue el mismo.

0
Tiago Ferreira 19 feb. 2018 a las 13:23

2 respuestas

La mejor respuesta

¿Cómo puedo configurar Camel / Restlet / Servlet para incluir el motivo en el código de estado HTTP?

Sin un núcleo personalizado, creo que no puede:

La respuesta se envía a org.restlet.engine.adapter.ServerCall.sendResponse (), donde el encabezado y el cuerpo de la respuesta son escrito en OutputStream:

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

... y writeResponseHead (respuesta) no hace nada de forma predeterminada , compruébalo:

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

Actualización: ... el HttpStatus (value, reasonPhrase) tiene reasonPhrase, pero no está acostumbrado a stringify:

HttpStatus(int value, String reasonPhrase) {
    this.value = value;
    this.reasonPhrase = reasonPhrase;
}
...
@Override
public String toString() {
    return Integer.toString(this.value);
}

Actualización 2: ... el DefaultRestletBinding. populateRestletResponseFromExchange hace lo siguiente:

// get response code
Integer responseCode = out.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
if (responseCode != null) {
    response.setStatus(Status.valueOf(responseCode));
}

... solo usa Estado. valueOf.

Aunque hay un Status.reasonPhrase, no es accesible.


Respuesta:

Sin un núcleo personalizado, (creo) ¡no puedes!


... lo que no es inapropiado, dado que:

¿Necesita saber el significado de un código de estado?

Consulte la lista completa de códigos de estado mantenidos por IANA.

3
mo7ty 11 abr. 2018 a las 23:19
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
.setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
.setBody(constant("Forbidden"))
3
codebrane 19 feb. 2018 a las 11:49