Подтвердить что ты не робот

Изменение типа контента в службе REST jax-rs

Простите меня, но я, возможно, не знаком со всем жаргоном, чтобы правильно задавать этот вопрос.

Я работаю над довольно простой веб-службой REST на Java, используя реализацию jax-rs org.apache.cxf.jaxrs.ext. Заголовок метода выглядит следующим образом:

@GET
@Path("json/{fullAlias}")
@Produces({"application/json"})
public String json(@PathParam("fullAlias") String fullAlias, @Context MessageContext req)

где MessageContext org.apache.cxf.jaxrs.ext.MessageContext.

Есть две вещи, которые я пытаюсь выполнить, я не могу понять:

  • Измените тип содержимого, если выполняются определенные условия (например, для ошибки)
  • Измените код состояния ответа

Я попытался изменить ответ, обратившись к нему через MessageContext:

HttpServletResponse response = req.getHttpServletResponse();
response.setContentType("text/plain")
response.setStatus("HttpServletResponse.SC_BAD_REQUEST);

Но эти изменения не влияют на отправленный ответ; с аннотацией @Produces или без нее, настройка типа содержимого внутри метода не влияет на фактический тип контента (с аннотацией он, конечно же, возвращает "application/json", без необходимости по умолчанию "text/html" ).

Я возвращаю простую строку как тело. Я развлекался, пытаясь вернуть объект javax.ws.rs.core.Response, чтобы делать то, что я хочу, но я мало знаю об этом.

Как изменить тип контента и/или коды состояния из этого метода?

4b9b3361

Ответ 1

Один из подходов заключается в том, чтобы бросить исключение WebApplicationException, как описано в Pace, которое будет работать, если вы хотите конкретно обработать условие ошибки. Если вы хотите изменить свой контент в любое время по какой-либо причине, то вам захочется взглянуть на возвращение ответа как результат вашего метода службы, а не строки. Возврат ответа дает вам наибольший контроль над тем, как ваш сервис отвечает на запрос клиента (для этого требуется больше кода, чем возврат простой строки).

Вот пример того, как вы могли бы использовать объект Response:

@GET
@Path("json/{fullAlias}")
public Response json(@PathParam("fullAlias") String fullAlias, @Context MessageContext req) {
    ...
    if (success) {
        ResponseBuilder rBuild = Response.ok(responseData, MediaType.APPLICATION_JSON);
        return rBuild.build();
    }
    else {
        ResponseBuilder rBuild = Response.status(Response.Status.BAD_REQUEST);
        return rBuild.type(MediaType.TEXT_PLAIN)
                     .entity("error message")
                     .build();
    }    
}

Ответ 2

Я не уверен, что это лучший подход, но я сделал следующее, чтобы решить ваш вопрос № 1.

public WebApplicationException createStatusException(String statusMessage) {
    ResponseBuilder rb = Response.noContent();
    rb = rb.type(MediaType.TEXT_PLAIN);
    rb = rb.status(Status.BAD_REQUEST);
    rb = rb.entity(statusMessage);
    return new WebApplicationException(rb.build());
}

РЕДАКТИРОВАТЬ: Затем я выбросил результирующий WebApplicationException.

Ответ 3

Вы можете написать свой собственный фильтр ответов, чтобы изменить заголовок содержимого.

@Provider
public class MimeAddingFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
        throws IOException {
        responseContext.getHeaders().add("Content-Type", "image/png");
    }

}

Этот фильтр добавит заголовок заголовка "image/png". Вы также можете изменить или удалить заголовки в фильтрах ответов JAX-RS.