Мы реализуем API REST, который возвращает json-p, используя CXF и Spring. Сервис должен работать с клиентом GWT. Клиент GWT вызывает сервис, используя JsonpRequestBuilder. Он передает два имени функции: одно, в которое должен быть включен ответ в случае успеха, и одно в случае сбоя.
URL-адрес вызова может выглядеть примерно так:
http://our.server.com/restservice?parameter=value...parameter=value&_jsonp=success_callback&_jsonp_failure=failure_callback
Когда служба вызывает исключение (сбой службы), я хочу вернуть HTTP-ответ со статусом 200, который содержит сообщение об исключении. Причина, по которой я не использую стандартные перехватчики jsonp (JsonpPreStreamInterceptor и JsonpPostStreamInterceptor), заключается в том, что я хотел бы обернуть тело ответа в другую функцию, если было сгенерировано исключение. Это сделано для того, чтобы мой клиент (созданный с использованием GWT) мог распознать ошибку.
Я написал преобразователь для преобразования исключения в ответ, который выглядит следующим образом:
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import cfpfelles.WebServiceException;
@Provider
public class WebServiceExceptionMapper implements ExceptionMapper<WebServiceException> {
public Response toResponse(WebServiceException arg0) {
return Response.status(Response.Status.OK).
type("application/x+javascript").
entity("Exception: " + arg0.getMessage()).
build();
}
}
У меня есть перехватчик instream, который хранит имена обратного вызова об успехе и сбое в частях обмена объекта Message, чтобы к ним могли обращаться выходные перехватчики. Это выглядит так:
public void handleMessage(Message message) throws Fault {
String callbackValue = getCallbackValue(message);
if (!callbackValue.isEmpty()) {
if (getAcceptType() != null)
{
message.put("Accept", getAcceptType());
}
message.getExchange().put(CALLBACK_KEY, callbackValue);
}
// failure callback value
String failureCallbackValue = getFailureCallbackValue(message);
if (!failureCallbackValue.isEmpty()) {
message.getExchange().put(FAILURE_CALLBACK_KEY, failureCallbackValue);
}
}
У меня есть перехватчик перед потоком с методом handleMessage, который выглядит следующим образом:
public void handleMessage(Message message) throws Fault {
HttpServletResponse response = (HttpServletResponse) message
.get("HTTP.RESPONSE");
try {
response.getOutputStream().write("callback(".getBytes("UTF-8"));
} catch (IOException e) {
throw new Fault(e);
}
}
У меня есть постпотоковый перехватчик с методом handleMessage, который выглядит следующим образом:
public void handleMessage(Message message) throws Fault {
HttpServletResponse response = (HttpServletResponse) message
.get("HTTP.RESPONSE");
try {
response.getOutputStream().write(");".getBytes("UTF-8"));
} catch (IOException e) {
throw new Fault(e);
}
}
В pre-stream interceptor я хотел бы установить оболочку обратного вызова в зависимости от того, было ли сгенерировано исключение или нет. К сожалению, я не могу найти способ сделать это. Я не могу прочитать содержание сообщения в перехватчике перед потоком. Также я не могу прочитать статус HTTP. Был бы очень признателен за помощь с этим. Или как конкретно решить мою проблему, или как лучше ее решить.