Фильтр сервлета и перехватчик CXF для изменения содержимого запроса и ответа? - PullRequest
11 голосов
/ 07 февраля 2012

Мы создали несколько веб-сервисов REST (jax-rs) с использованием Apache CXF.Они возвращают ответ JSON.

Теперь мне нужно изменить некоторые параметры запроса и содержимое ответа.(По сути, нам необходимо кодировать / шифровать некоторые данные, возвращаемые службой; и декодировать / дешифровать те же данные, когда они используются в качестве параметра при последующем вызове службы.)

Кажется, у меня естьздесь как минимум 4 варианта:

  1. Использование фильтра сервлетов
  2. Использование перехватчика CXF
  3. Использование фильтра JAX-RS
  4. Неиспользовать любой конкретный шаблон и выполнять кодирование / декодирование в рамках действующей служебной логики.

Я уже использовал фильтры сервлетов и точно знаю, как изменить параметры запроса и тело ответа, поэтому ясклоняясь к этому.Тем не менее, я открыт для использования перехватчика CXF или фильтра JAX-RS, если это более «правильный» способ решить эту проблему при использовании CXF.Но на основании документации я не совсем понимаю, как сделать это.Например, могу ли я использовать метод setContent объекта Message для изменения ответа JSON?Что такое параметр формата в этом случае, просто String.class?

1 Ответ

9 голосов
/ 23 февраля 2012

Отвечая на мой собственный вопрос здесь ... В итоге я использовал фильтр JAX-RS, и он заработал хорошо, как только я справился с отсутствием документации.Я использовал (довольно редкую) документацию от http://cxf.apache.org/docs/jax-rs-filters.html.Обратите внимание, что, несмотря на свое название, фильтр JAX-RS является CXF-специфическим зверем, а не частью стандарта JAX-RS (насколько я могу судить).

Вот пример кода:

@Context
private HttpServletRequest httpRequest;
@Context
private UriInfo uriInfo;

/**
 * @see org.apache.cxf.jaxrs.ext.ResponseHandler#handleResponse(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.OperationResourceInfo, javax.ws.rs.core.Response)
 */
public Response handleResponse(Message message, OperationResourceInfo opResourceInfo, Response response) {
    try {

        // log the injected context data; useful for debugging CXF problems
        logContextData(httpRequest, uriInfo);

        OutputStream os = message.getContent(OutputStream.class);
        String relevantData = getDataFromRequest(httpRequest);
        message.setContent(OutputStream.class, new MyOutputStreamWrapper(os, relevantData));

    } catch (CustomException e) {
            // return some status that is related to CustomException
        return Response.status(Status.UNAUTHORIZED).build();
    } catch (Exception e) {
        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
    }

    return response;
}

/**
 * @see org.apache.cxf.jaxrs.ext.RequestHandler#handleRequest(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.ClassResourceInfo)
 */
public Response handleRequest(Message message, ClassResourceInfo classResourceInfo) {
    try {

        // log the injected context data; useful for debugging CXF problems
        logContextData();

        String updatedQueryString = buildNewQueryString(this.uriInfo, httpRequest);

        message.put(Message.QUERY_STRING, updatedQueryString);


        // returning null tells CXF to continue the request (i.e. a non-null value would halt the request)
        return null;

    } catch (CustomException e) {
        // return some status that is related to CustomException
        return Response.status(Status.UNAUTHORIZED).build();
    } catch (Exception e) {
        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
    }
}

Следует отметить, что реализация MyOutputStreamWrapper является важной частью при изменении содержимого ответа.Я не мог включить этот источник здесь (на самом деле моя реализация имеет другое имя) из соображений безопасности.

...