2013-08-30 9 views
5

Non riesco a configurare un client Jersey per testare una richiesta POST a una risorsa.Come configurare un client Jersey con il provider Jackson (2.x) per elaborare una richiesta POST

la mia maglia e Jackson dipendenze sembrano questi:

<dependencies> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-grizzly2-http</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-json-jackson</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.jaxrs</groupId> 
     <artifactId>jackson-jaxrs-json-provider</artifactId> 
     <version>${jackson.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-client</artifactId> 
    </dependency> 
</dependencies> 

<dependencyManagement> 
    <dependencies> 
     <dependency> 
      <groupId>org.glassfish.jersey</groupId> 
      <artifactId>jersey-bom</artifactId> 
      <version>${jersey.version}</version> 
      <type>pom</type> 
      <scope>import</scope> 
     </dependency> 
    </dependencies> 
</dependencyManagement> 

sto utilizzando Jersey 2.4 e Jackson 2.2.3.

I ha installato il client di amd WebTarget come questo:

client = JerseyClientBuilder.newBuilder().build(); 

target = client.target(Main.BASE_URI); 

ho configurato il server in questo modo:

ResourceConfig rc = new ResourceConfig().packages("com.my.package.is.here"); 
HttpServer httpServer = GrizzlyHttpServerFactory 
          .createHttpServer(URI.create(BASE_URI), rc); 

provo a testare la richiesta POST alla risorsa:

ClientResponse response = target.path(resourceIdentifier) 
          .request(MediaType.APPLICATION_JSON_TYPE) 
          .post(Entity.json(testObjectJSON.toString()), 
             ClientResponse.class); 

Attualmente, viene visualizzato il seguente errore:

javax.ws.rs.ProcessingException: Error reading entity from input stream. 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:849) 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:768) 
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:96) 
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:761) 
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90) 
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:228) 
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:422) 
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667) 
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:423) 
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:326) 
at com.my.package.is.here.test.MyResourceTest.testPOSTJSON(MyResourceTest.java:117) 
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$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.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
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.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: com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]] 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:272) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247) 
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146) 
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:305) 
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:634) 
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:438) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:298) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247) 
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146) 
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:322) 
at com.fasterxml.jackson.databind.ObjectReader._findRootDeserializer(ObjectReader.java:1326) 
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1174) 
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:635) 
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:660) 
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:188) 
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134) 
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988) 
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833) 
... 38 more 
Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]] 
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createMapDeserializer(BasicDeserializerFactory.java:945) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:382) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:354) 
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:267) 
... 55 more 

Tuttavia, quando sto testando la richiesta POST alla risorsa con curl tutto funziona correttamente. Quindi penso che possa avere qualcosa a che fare con l'installazione del client Jersey.

+0

Sembra che abbia qualcosa a che fare con l'implementazione della classe ClientResponse, cioè restituendo direttamente il risultato, non ha causato l'eccezione. Quindi le seguenti righe di codice funzionano per rendere il test riuscito: String responseString = target.path (resourceIdentifier +) .request (MediaType.APPLICATION_JSON_TYPE) .post (Entity.json (testObjectJSON.toString()), String.class); – zazi

risposta

2

Sembra che abbia qualcosa a che fare con l'implementazione della classe ClientResponse, cioè restituire direttamente il risultato, non ha causato l'eccezione. Così le seguenti righe di codice sono al lavoro per rendere il test di successo:

String responseString = target.path(resourceIdentifier).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(testObjectJSON.toStr‌​ing()), String.class); 
+0

L'azione 'post' non può restituire direttamente' ClientResponse.class'? – DerekY

0

Prova questo:

package myco.mypkg; 

import static org.junit.Assert.assertEquals; 

import javax.ws.rs.client.Entity; 
import javax.ws.rs.client.WebTarget; 
import javax.ws.rs.core.Form; 

import org.glassfish.jersey.server.ResourceConfig; 
import org.glassfish.jersey.servlet.ServletContainer; 
import org.glassfish.jersey.test.DeploymentContext; 
import org.glassfish.jersey.test.JerseyTest; 
import org.glassfish.jersey.test.ServletDeploymentContext; 
import org.glassfish.jersey.test.TestProperties; 
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; 
import org.glassfish.jersey.test.spi.TestContainerFactory; 
import org.junit.Test; 
import org.springframework.http.MediaType; 

/** 
* Simple tests, with a simple endpoint/resource, no injections, to debug and document how JerseyTest works. 
* 
*/ 
public class SimpleTest extends JerseyTest { 

    public SimpleTest() { 

     // Enable logging. This is really critical! 
     enable(TestProperties.LOG_TRAFFIC); 
     enable(TestProperties.DUMP_ENTITY);  
    } 

    /** Start a Grizzly server */ 
    @Override 
    protected TestContainerFactory getTestContainerFactory() { 
     return new GrizzlyWebTestContainerFactory(); 
    } 

    /** Tell the server to deploy the TestResource endpoint class */ 
    @Override 
    protected DeploymentContext configureDeployment() { 
     return ServletDeploymentContext.forServlet(new ServletContainer(new ResourceConfig(TestResource.class))).build(); 
    } 

    /** 
    * Make a test call. 
    */ 
    @Test 
    public void testGet() { 
     WebTarget target = target("root"); 

     String s = target.request().get(String.class); 
     assertEquals("GET", s); 
    } 

    @Test 
    public void testGetSub() { 
     WebTarget target = target("root/sub"); 

     String s = target.request().get(String.class); 
     assertEquals("sub", s); 
    } 

    @Test 
    public void testPost() { 
     WebTarget target = target("root/mypost"); 

     Form form = new Form(); 
     form.param("id", "1234"); 
     form.param("description", "test"); 
     String s = target.request(MediaType.APPLICATION_FORM_URLENCODED_VALUE).post(Entity.form(form), String.class); 
     assertEquals("posted", s); 
    } 

    @Test 
    public void testPostWithParam() { 
     WebTarget target = target("root/postparams"); 

     Form form = new Form(); 
     form.param("id", "1234"); 
     String s = target.request(MediaType.APPLICATION_FORM_URLENCODED_VALUE).post(Entity.form(form), String.class); 
     assertEquals("posted1234", s); 
    } 
} 

Questi chiamando il seguente:

package myco.mypkg; 

import javax.ws.rs.FormParam; 
import javax.ws.rs.GET; 
import javax.ws.rs.POST; 
import javax.ws.rs.Path; 

/** 
*  A test endpoint, for use with SimpleTest 
*/ 
@Path("root") 
public class TestResource { 

    @GET 
    public String get() { 
     return "GET"; 
    } 

    @Path("sub") 
    @GET 
    public String getSub() { 
     return "sub"; 
    } 

    @Path("mypost") 
    @POST 
    public String post() { 
     return "posted"; 
    } 

    /** If you omit the @FormParam, id contains "id=1234" */ 
    @Path("postparams") 
    @POST 
    public String post(@FormParam("id") String id) { 
     return "posted" + id; 
    } 
} 

ho preso la roba POST digitando Entità. e aspettando l'aiuto del popup per mostrarmi quali fossero i metodi.

Sto utilizzando Jersey 2.13.