REST Java 客户端API: 在分配另一个之前释放连接

REST Java client API: Release connection before allocating another

我正在使用此测试代码调用 REST 服务:

public class TestRESTServices {
    private static final String BASE_URL = "http://localhost/ma.ge.persistence-1.0/rest/reference";
    private static URI uri = UriBuilder.fromUri(BASE_URL).port(8080).build();
    private static Client client = ClientBuilder.newClient();

    @Test
    public void createAndDeleteAReference() {

        Reference r = ReferenceFactory.createReference("Maz",
                "dummy", 1.7);
        Response response = client.target(uri).request().post(Entity.entity(r, MediaType.APPLICATION_JSON));
        assertEquals(Response.Status.CREATED, response.getStatusInfo());

        URI referenceURI = response.getLocation();

        // Get the posted reference
        response = client.target(referenceURI).request().get();

        Reference retreivedRef = response.readEntity(Reference.class);
        assertEquals(Response.Status.OK, response.getStatusInfo());
        assertEquals(retreivedRef.getName(), r.getName());

    }

但我收到以下错误:

javax.ws.rs.ProcessingException: Unable to invoke request at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:407) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.get(ClientInvocationBuilder.java:159) at ma.gesto.persistence.TestRESTServices.createAndDeleteAReference(TestRESTServices.java:34) 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:606) at org.junit.runners.model.FrameworkMethod.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.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.run(ParentRunner.java:238) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:53) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) 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:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one. at org.apache.http.impl.conn.BasicClientConnectionManager.getConnection(BasicClientConnectionManager.java:162) at org.apache.http.impl.conn.BasicClientConnectionManager.getConnection(BasicClientConnectionManager.java:139) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) ... 26 more

Client接口表示外部资源。因此,创建一个静态变量并将其存储在静态变量中是一个严重的错误。这是错误的:

private static Client client = ClientBuilder.newClient();

这可以用于单元测试:

private Client client;

@Before
public void setUp() {
    this.client = ClientBuilder.newClient();
}

@After
public void tearDown() {
    this.client.close();
}

在正常代码中,您可能希望将 Client 用法包装在 try-with-resourcestry..finally:

Client client = ClientBuilder.newClient();
try {
    // use the client to make requests
} finally {
    client.close();
}

理想情况下,会有一种方法来管理 Client 个实例池以供重用。

您还需要关闭 Response 以释放连接。 请参阅此处的解释: