我尝试使用RestEasy客户端代理更新 Book . Book 实体继承自 ProductService 接口(JAX-RS资源)定义方法:

public interface Service<E, I> {

    /**
     * Updates an existing entity in data base
     * 
     * @param entity
     *            E
     * @return {@link Response}
     */
    @PUT
    @Consumes(MediaType.APPLICATION_XML)
    public Response update(E entity);

具体实现是:

@Override
public Response update(Product entity) {
    System.out.println("Update book: "+entity);
    throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);
}

我现在尝试使用客户端代理调用更新方法:

private static ServiceProduct serviceProductClient_musterm;
...

@BeforeClass
public static void setUpClass() throws Exception {
    serviceProductClient_musterm = ProxyFactory.create(
            ServiceProduct.class, HOST, sslExecutor_musterm);
}

@Test
public void updateProductTest_Forbidden_OK() {
    Book prod = new Book(100, "name", "description", 1000, "EUR",
            "isbn", new Date(), "author");

    response = (ClientResponse<?>) serviceProductClient_musterm.update(prod);
    assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
}

测试用例因RuntimeException失败:

java.lang.RuntimeException: java.lang.RuntimeException: could not find writer for content-type application/xml type: java.lang.Object
    at org.jboss.resteasy.client.core.ClientInvoker.invoke(ClientInvoker.java:114)
    at org.jboss.resteasy.client.core.ClientProxy.invoke(ClientProxy.java:88)
    at $Proxy28.update(Unknown Source)
    at at.fhj.ase.business.ServiceProductImplTestWithClientProxy.j100_updateProductTest_Forbidden_OK(ServiceProductImplTestWithClientProxy.java:521)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.RuntimeException: could not find writer for content-type application/xml type: java.lang.Object
    at org.jboss.resteasy.client.ClientRequest.writeRequestBody(ClientRequest.java:469)
    at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.loadHttpMethod(ApacheHttpClient4Executor.java:221)
    at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.execute(ApacheHttpClient4Executor.java:107)
    at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:39)
    at org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPInterceptor.execute(AcceptEncodingGZIPInterceptor.java:40)
    at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:45)
    at org.jboss.resteasy.client.ClientRequest.execute(ClientRequest.java:443)
    at org.jboss.resteasy.client.ClientRequest.httpMethod(ClientRequest.java:674)
    at org.jboss.resteasy.client.core.ClientInvoker.invoke(ClientInvoker.java:110)
    ... 31 more

java.lang.NullPointerException
    at at.fhj.ase.business.ServiceProductImplTestWithClientProxy.tearDown(ServiceProductImplTestWithClientProxy.java:78)
    at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

我知道java泛型的类型擦除删除了具体的类型信息 . 这就是为什么Jaxb声称找不到 Object 类型的作家的原因 . 对于服务器响应,存在 GenericEntiy

GenericEntity<List<Category>> entity = new GenericEntity<List<Category>>(
            categories) {
    };

但是客户端请求的解决方案是什么?

[EDIT]

通过使用RestEasy客户端框架,更新方法可以正常工作:

@Test
public void a100_insertRecensionTest() throws Exception {
    Book prod = new Book(100, "name", "description", 1000, "EUR",
            "isbn", new Date(), "author");

    ClientRequest request = new ClientRequest(BASE_URL, sslExecutor_musterm);
    request.body(MediaType.APPLICATION_XML, prod);
    ClientResponse<?> response = request.put();

    assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());

    response.releaseConnection();
    request.clear();
}

update方法的输出与预期的一样:

18:51:19,636 INFO  [stdout] (http--0.0.0.0-443-2) Update book: Id: 100 Name: name Description: description Price: 1000 Currency: EUR ISBN: isbn PublicationDate: Tue Jul 02 18:51:18 CEST 2013 Author: author

如何使用RestEasy客户端代理实现此目的?