尝试在 Errai 4 中进行 JAXRS 调用时出现 ClassCastException

ClassCastException When Trying to Make JAXRS Call in Errai 4

我正在使用 Errai 4.0.0.Beta1,我正在尝试进行简单的 JAX RS 调用。

这是我使用的代码:

final RemoteCallback<List<Company>> remoteCallback = new RemoteCallback<List<Company>>() {
   @Override
   public void callback(List<Company> companies) {
  Window.alert("rpcServiceCaller - Callback");
  Window.alert("Number of companies returned: " + companies.size());
  }
};
final RestErrorCallback errorCallback = new RestErrorCallback() {
   @Override
   public boolean error(Request message, Throwable throwable) {
  Window.alert(throwable.getMessage());
   logger.error(throwable.getMessage(), throwable);
   return false;
  }
};
RestClient.create(ErraiJAXRSService.class,
  remoteCallback,
  errorCallback,
   200).getCompaniesJSON();

我在超级开发模式中看到以下异常:

Error caused by: ClassCastException: undefined
    at f9b_g$ [as collect_0_g$] (StackTraceCreator.java:198)
    at H8b_g$ (StackTraceCreator.java:343)
    at Iz_g$ [as fillInStackTrace_0_g$] (Throwable.java:114)
    at Bz_g$ (Throwable.java:53)
    at Xz_g$ (Exception.java:25)
    at cA_g$ (RuntimeException.java:25)
    at Ymb_g$ (ClassCastException.java:23)
    at Mzg_g$ (InternalPreconditions.java:45)
    at Xzg_g$ (InternalPreconditions.java:33)
    at n1d_g$ (Cast.java:75)
    at rrh_g$ (RestClient.java:192)
    at srh_g$ (RestClient.java:158)
    at wrh_g$ (RestClient.java:113)
    at ynf_g$ [as erraiJSON_0_g$] (JAXRSPage.java:94)
    at gKh_g$ [as onClick_0_g$] (Type_factory__c_i_e_c_j_JAXRSPage__quals__j_e_i_Any_j_e_i_Default.java:76)
    at Exd_g$ [as dispatch_4_g$] (ClickEvent.java:56)
    at Fxd_g$ [as dispatch_1_g$] (ClickEvent.java:55)
    at Awd_g$ [as dispatch_0_g$] (GwtEvent.java:76)
    at ZGd_g$ (EventBus.java:40)
    at iHd_g$ [as doFire_0_g$] (SimpleEventBus.java:193)
    at oHd_g$ [as fireEvent_2_g$] (SimpleEventBus.java:88)
    at RGd_g$ [as fireEvent_1_g$] (HandlerManager.java:127)
    at Lve_g$ [as fireEvent_1_g$] (Widget.java:129)
    at Lwd_g$ (DomEvent.java:125)
    at Tve_g$ [as onBrowserEvent_0_g$] (Widget.java:177)
    at gne_g$ (DOM.java:1480)
    at fne_g$ (DOM.java:1419)
    at HTMLButtonElement.xte_g$ (DOMImplStandard.java:317)
    at k6b_g$ (Impl.java:233)
    at n6b_g$ (Impl.java:285)
    at HTMLButtonElement.<anonymous> (Impl.java:71)

代理已返回,但任何试图将其转换为 AbstractJaxrsProxy 的行都失败并出现上述异常。

已创建 JaxrsProxyLoaderImpl.java,我的 JAX RS 服务就在那里:

package org.jboss.errai.enterprise.client.jaxrs;

import com.google.gwt.http.client.RequestBuilder;
import com.insclix.erraiPOC.shared.domain.Company;
import com.insclix.erraiPOC.shared.service.jaxrs.ErraiJAXRSService;
import java.util.List;
import org.jboss.errai.common.client.api.ErrorCallback;
import org.jboss.errai.common.client.api.RemoteCallback;
import org.jboss.errai.common.client.framework.ProxyProvider;
import org.jboss.errai.common.client.framework.RemoteServiceProxyFactory;
import org.jboss.errai.security.client.local.interceptors.SecurityExceptionMapper;

public class JaxrsProxyLoaderImpl implements JaxrsProxyLoader { public void loadProxies() {
   class com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl extends AbstractJaxrsProxy implements ErraiJAXRSService {
   private RemoteCallback remoteCallback;
   private ErrorCallback errorCallback;
   public com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl() {
  setExceptionMapper(new SecurityExceptionMapper());
  }

   public RemoteCallback getRemoteCallback() {
   return remoteCallback;
  }

   public void setRemoteCallback(RemoteCallback callback) {
  remoteCallback = callback;
  }

   public ErrorCallback getErrorCallback() {
   return errorCallback;
  }

   public void setErrorCallback(ErrorCallback callback) {
  errorCallback = callback;
  }

   public List getCompaniesJSON() {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
  requestBuilder.setHeader("Accept", "application/json");
  sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, List.class, Company.class);
  }
  });
   return null;
  }

   public List getCompaniesXML() {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
  requestBuilder.setHeader("Accept", "application/xml");
  sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, List.class, Company.class);
  }
  });
   return null;
  }

   public Long createCompanyJSON(final Company a0) {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
  requestBuilder.setHeader("Content-Type", "application/json");
  sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, Long.class, null);
  }
  });
   return 0L;
  }

   public Long createCompanyXML(final Company a0) {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
  requestBuilder.setHeader("Content-Type", "application/xml");
  sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, Long.class, null);
  }
  });
   return 0L;
  }
  }
  RemoteServiceProxyFactory.addRemoteProxy(ErraiJAXRSService.class, new ProxyProvider() {
   public Object getProxy() {
   return new com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl();
  }
  });
  }
}

事实证明这是 JAX-RS/Errai class 和接口配置方式的问题。根据 JAX-RS 规范,@Path 注释需要在实现上,但 Errai 需要在接口上。

因此,解决方案是在接口(对于 Errai)和实现它的 class(对于 JAX-RS)上都使用 @Path 注释。

注意,如果注解在接口上,Wildfly 允许这样做,Jersey 忽略接口,Resteasy 失败(如果 运行 通过 ResteasyServletInitializer。