我在使用我的应用程序运行Errai-jaxrs时遇到了一个问题,我从GWT开发人员模式中收到此错误:
org.jboss.errai.enterprise.client.jaxrs.api.ResponseException: Bad Request
at org.jboss.errai.enterprise.client.jaxrs.AbstractJaxrsProxy$1.onResponseReceived(AbstractJaxrsProxy.java:132)
at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:474)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
at sun.reflect.GeneratedMethodAccessor56.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:474)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
at java.lang.Thread.run(Thread.java:722)
在服务器端:
[INFO] Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "^EncodedType" (Class com.mycompany.client.shared.Customer), not marked as ignorable
[INFO] at [Source: org.mortbay.jetty.HttpParser$Input@115194d; line: 1, column: 18] (through reference chain: com.mycompany.client.shared.Customer["^EncodedType"])
[INFO] at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
[INFO] at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
[INFO] at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
[INFO] at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
[INFO] at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
[INFO] at org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725)
[INFO] at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703)
[INFO] at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
[INFO] at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704)
从堆栈跟踪中,它看起来像一个错误请求。这个的后端是RestEasy + Guice,它配置正确,因为在我尝试使用errai-jaxrs之前,我只是使用可以正常工作的普通GWT RequestBuilder。我不确定问题出在哪里,但这是我的代码:
CustomerService.java
@Path("/customerservice")
public interface CustomerService {
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Customer getCustomer(String id);
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String createCustomer(Customer Customer);
}
CustomerServiceImpl.java
@Singleton
public class CustomerServiceImpl implements CustomerService {
@Override
public Customer getCustomer(String id) {
return new Customer();
}
@Override
public String createCustomer(Customer Customer) {
return "1";
}
}
在客户端:
@Inject
private Caller<CustomerService> customerService;
@EventHandler("submit")
public void createCustomer(ClickEvent event) {
event.preventDefault();
Customer customer = new Customer();
customerService.call(new RemoteCallback<String>() {
@Override
public void callback(String response) {
Window.alert("Customer created: " + response);
}
}).createCustomer(customer);
}
可能是什么问题呢?
最佳答案
从堆栈跟踪中可以看到,您在服务器端使用Jackson来编组请求和响应数据,但是客户端使用的是Errai的默认编组格式。
您将必须决定要使用Errai的编组格式还是Jackson。
Errai编组
Errai的编组格式的优点是它在线路上包含更多类型信息(例如您看到Jackson解析器抱怨的“ ^ EncodedType”属性)。当您的JAX-RS API主要用于Errai客户端时,这是最佳选择。这也是通过电线发送这样的对象的唯一方法:
@Portable class TypeWithPolymorphicField {
private Object foo = new Foo();
}
要在服务器端启用Errai编组(而不是Jackson),您需要在应用程序中部署
errai-jaxrs-provider-[version].jar
。从Errai Reference Guide:<dependency>
<groupId>org.jboss.errai</groupId>
<artifactId>errai-jaxrs-provider</artifactId>
<version>${errai.version}</version>
</dependency>
杰克逊·马歇尔
另一方面,如果非Errai客户打算使用您的JAX-RS API,他们可能会发现Jackson编组更加愉快和熟悉。如果选择该选项,则需要告诉客户端使用杰克逊编组而不是默认设置。从Errai Reference guide:
以下选项可用于激活Jackson编组
在客户端上。请注意,这是一个客户端配置,
假定JAX-RS端点已经返回了Jackson表示
(所有JAX-RS实现都支持Jackson)。的
不必将errai-jaxrs-provider.jar部署在
这个案例!
<script type="text/javascript">
erraiJaxRsJacksonMarshallingActive = true;
</script>
或使用JSNI方法:
private native void setJacksonMarshallingActive(boolean active) /*-{
$wnd.erraiJaxRsJacksonMarshallingActive = active;
}-*/;
或通过简单地调用:
RestClient.setJacksonMarshallingActive(true);
最后说明:不要同时执行以上两项,否则您将陷入相反的问题!您必须将客户端或服务器配置为其自然默认设置。