我正在努力设置Jersey客户端来测试对资源的POST请求。
我的泽西岛和杰克逊的依赖关系看起来像这样:
<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>
我正在使用Jersey 2.4和Jackson 2.2.3。
我像这样设置了客户端和WebTarget:
client = JerseyClientBuilder.newBuilder().build();
target = client.target(Main.BASE_URI);
我像这样设置服务器:
ResourceConfig rc = new ResourceConfig().packages("com.my.package.is.here");
HttpServer httpServer = GrizzlyHttpServerFactory
.createHttpServer(URI.create(BASE_URI), rc);
我尝试在资源上测试POST请求:
ClientResponse response = target.path(resourceIdentifier)
.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.json(testObjectJSON.toString()),
ClientResponse.class);
目前,我收到以下错误:
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
但是,当我用curl测试资源上的POST请求时,一切正常。所以我认为它可能与Jersey客户端设置有关。
答案 0 :(得分:2)
看起来这与ClientResponse类的实现有关,即直接返回结果,不会导致异常。因此,以下代码行正在努力使测试成功:
String responseString = target.path(resourceIdentifier).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(testObjectJSON.toString()), String.class);
答案 1 :(得分:0)
试试这个:
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);
}
}
这些调用以下内容:
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;
}
}
我通过输入Entity获得了POST的东西。并等待弹出窗口帮助向我展示方法是什么。
我正在使用Jersey 2.13。