【问题标题】:Errai-jaxrs - Bad RequestErrai-jaxrs - 错误请求
【发布时间】:2013-05-04 23:12:54
【问题描述】:

我在使用我的应用程序运行 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,它的配置非常正确,因为在我尝试使用 erai-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);
}

可能是什么问题?

【问题讨论】:

    标签: java gwt resteasy errai


    【解决方案1】:

    我可以从堆栈跟踪中看到,您正在使用 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>
    

    杰克逊编组

    另一方面,如果您的 JAX-RS API 旨在供非 Errai 客户使用,他们可能会发现 Jackson 编组更令人愉快和熟悉。如果您选择,您需要告诉客户端使用杰克逊编组而不是默认值。来自Errai Reference guide

    以下选项可用于激活杰克逊编组 在客户端。请注意,这是一个客户端配置, 假定 JAX-RS 端点已返回 Jackson 表示 (所有 JAX-RS 实现都支持杰克逊)。这 errai-jaxrs-provider.jar 不必部署在服务器上 这个案子!

    <script type="text/javascript">
      erraiJaxRsJacksonMarshallingActive = true;
    </script>
    

    或使用 JSNI 方法:

    private native void setJacksonMarshallingActive(boolean active) /*-{  
      $wnd.erraiJaxRsJacksonMarshallingActive = active;
    }-*/;
    

    或通过简单地调用:

    RestClient.setJacksonMarshallingActive(true);
    

    最后一点:不要同时做以上两个,否则你会遇到相反的问题!您必须配置任一客户端远离其自然默认值的服务器。

    【讨论】:

    • Errai 编组最适合我的 Errai 前端,因为我有一个单独的 API 供任何安静的客户端使用。
    • 只包括依赖就可以了?
    • 是的,如果您使用 errai-jaxrs-provider 进行部署,RestEasy 应该会找到 Errai Marshalling 提供程序。
    • 检查的另一点是什么。我已经添加了依赖,仍然有同样的错误。
    • 我不确定。您需要的类型是ErraiProvider。它带有@Provider 注释。这是供应商上的RestEasy documentation
    猜你喜欢
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2019-07-28
    相关资源
    最近更新 更多