创建供 GWT 客户端使用的 cxf REST json-p 服务的最佳方法
我们正在实现一个使用 CXF 和 Spring 返回 json-p 的 REST api。该服务应与 GWT 客户端配合使用。 GWT 客户端使用 JsonpRequestBuilder 调用服务。它传入两个函数名称,一个在成功的情况下应将响应包装在其中,另一个在失败的情况下应包装在响应中。
调用 URL 可能如下所示: http://our.server.com /restservice?parameter=value...parameter=value&_jsonp=success_callback&_jsonp_failure=failure_callback
时服务抛出异常(服务失败) 我想返回状态为 200 的 HTTP 响应,其中包含异常消息。我不使用标准 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();
}
}
我有一个流内拦截器,它将成功和失败回调名称存储在 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);
}
}
在预流拦截器中,我会就像设置回调包装器一样,具体取决于是否抛出异常。不幸的是我想不出办法来做到这一点。我似乎无法读取预流拦截器中的消息内容。我也无法读取 HTTP 状态。非常感谢对此的一些帮助。要么如何具体解决我的问题,要么有更好的方法来解决它。
We're implementing a REST api that returns json-p using CXF and Spring. The service should work with a GWT client. The GWT client calls the service using JsonpRequestBuilder. It passes in two function names, one that the response should be wrapped in in case of success and one if it's a failure.
The call url can look something like this:
http://our.server.com/restservice?parameter=value...parameter=value&_jsonp=success_callback&_jsonp_failure=failure_callback
When an exception is cast by a service (service failure) I'd like to return an HTTP response with status 200 that contains the exception message. The reason I'm not using the standard jsonp interceptors (JsonpPreStreamInterceptor and JsonpPostStreamInterceptor) is that I'd like to wrap the response body in a different function if an exception has been thrown. This is so that my client (built using GWT) can recognise that an error has occured.
I've written a mapper to convert the exception into a response that looks like this:
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();
}
}
I've got an instream interceptor that stores the success and failure callback names in the exchange parts of the Message object, so that they can be accessed by the output interceptors. It looks like this:
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);
}
}
I've got a pre-stream interceptor with a handleMessage method that looks like this:
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);
}
}
I've got a post-stream interceptor with a handleMessage method that looks like this:
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);
}
}
In the pre-stream interceptor, I would like to set the callback wrapper, depending on whether an exception has been thrown or not. Unfortunately I can't figure out a way to do this. I can't seem to read the content of the message in the pre-stream interceptor. Neither can I read the HTTP status. Would really appreciate some help with this. Either how to specifically solve my problem or better ways to go about it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是否有任何特定原因让服务即使在异常情况下也发送 200?我的意思是服务可以返回 500 并且消息可以由 GWT 客户端解析。
Is there any specific reason for service to send 200 even in case of exception. I mean the service can return 500 and the message can be parsed by GWT Client.