我有一个称为Activity的实体类,该类正在反序列化并且可以正常工作,直到我决定向该实体添加int类型的id字段。该字段的getter和setter是公共的,似乎还不错,但是当我运行从客户端创建对象的测试时,会出现如下所示的反序列化错误。我正在使用jersey进行REST教程。
我已经检查了setter和getter的可见性,它们既不是包私有的也不是私有的。
这是我得到的错误:
javax.ws.rs.ProcessingException: Error deserializing object from entity stream.
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:77)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:233)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:212)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1067)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:850)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:784)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:297)
at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:91)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:365)
at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:240)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:88)
at tzpl.client.ActivityClient.create(ActivityClient.java:54)
at tzpl.client.ActivityClientTest.testCreate(ActivityClientTest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: javax.json.bind.JsonbException: Can't deserialize JSON array into: class tzpl.model.Activity
at org.eclipse.yasson.internal.serializer.DeserializerBuilder.build(DeserializerBuilder.java:141)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:60)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:51)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:45)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:85)
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:75)
... 38 more
Process finished with exit code 255
这是活动实体:
package tzpl.model;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Activity {
private int id;
private String description;
private int duration;
private boolean worthIt;
private User user;
public Activity(){
}
public Activity (int id, String description, int duration, boolean worthIt){
this.description = description;
this.duration = duration;
this.worthIt = worthIt;
this.id = id;
}
@XmlElement(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement(name="user")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@XmlElement(name="verdict")
public boolean isWorthIt() {
return worthIt;
}
public void setWorthIt(boolean worthIt) {
this.worthIt = worthIt;
}
@XmlElement(name="desc")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@XmlElement(name="time-taken")
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
}
这是我试图用来获取活动对象的客户端;
package tzpl.client;
import tzpl.model.Activity;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
public class ActivityClient {
private Client client;
public ActivityClient() {
client = ClientBuilder.newClient();
}
public Activity get(String id) {
WebTarget target = client.target("http://localhost:8080/myapp" +
"/activities");
Response response =
target.path("activity/" + id).request(MediaType.APPLICATION_JSON).get(Response.class);
if (response.getStatus() != 200) {
throw new RuntimeException(response.getStatus() + ": An error was" +
" encountered on the server.");
}
return response.readEntity(Activity.class);
}
public List<Activity> get() {
WebTarget target = client.target("http://localhost:8080/myapp");
List<Activity> response =
target.path("activities/").request(MediaType.APPLICATION_JSON).get(List.class);
return response;
}
public Activity create(Activity activity) {
WebTarget target = client.target("http://localhost:8080/myapp" +
"/activities/");
Response response =
target.path("activity").request(MediaType.APPLICATION_JSON).post(Entity.entity(activity, MediaType.APPLICATION_JSON));
if (response.getStatus() != 200) {
throw new RuntimeException(response.getStatus() + ": there was an" +
" error on the server.");
}
return response.readEntity(Activity.class);
}
public Activity update(Activity activity) {
WebTarget target = client.target("http://localhost:8080/myapp" +
"/activities/");
Response response =
target.path("activity/"+activity.getId()).request(MediaType.APPLICATION_JSON).put(Entity.entity(activity, MediaType.APPLICATION_JSON));
if (response.getStatus() != 200) {
throw new RuntimeException(response.getStatus() + ": there was " +
"an" +
" error on the server.");
}
return response.readEntity(Activity.class);
}
}
我正在客户端测试中运行testCreate方法的测试,如下所示:
package tzpl.client;
import org.junit.Test;
import tzpl.model.Activity;
import tzpl.repository.ActivityRepository;
import tzpl.repository.ActivityResourceStub;
import java.util.List;
import static org.junit.Assert.assertNotNull;
public class ActivityClientTest {
@Test
public void testPut(){
ActivityRepository activityRepository = new ActivityResourceStub();
Activity activity = new Activity(6,"Mountain climbing", 45, true);
Activity activity2 = activityRepository.listAllActivities().get(2);
ActivityClient client = new ActivityClient();
activity2 = client.update(activity2);
assertNotNull(activity2);
}
@Test
public void testGet(){
ActivityClient client = new ActivityClient();
Activity activity = client.get("1");
System.out.println(activity.getDescription());
assertNotNull(activity);
}
@Test
public void testGetList(){
ActivityClient client = new ActivityClient();
List<Activity> activities = client.get();
System.out.println(activities);
assertNotNull(activities);
}
@Test (expected=RuntimeException.class)
public void testGetWithBadRequest(){
ActivityClient client = new ActivityClient();
client.get("");
}
@Test(expected=RuntimeException.class)
public void testGetWithNotFound(){
ActivityClient client = new ActivityClient();
client.get("777");
}
@Test
public void testCreate(){
ActivityClient client = new ActivityClient();
Activity activity = new Activity(7,"Skiing", 20, false);
activity = client.create(activity);
assertNotNull(activity);
}
}
在我什至断言活动无效或缺少活动之前,我从活动客户端收到一个错误,抱怨它无法反序列化传入的Jason流。我在pom.xml中具有以下依赖项。正如下面提到的pom所示,我显然对使用jason有依赖性,就像我提到的,只有在引入id字段之后测试才失败。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tzpl</groupId>
<artifactId>com.tzpl</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>com.tzpl</name>
<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>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<!-- uncomment this to get JSON support:-->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>tzpl.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jersey.version>2.28</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
我需要有关如何克服此反序列化错误的帮助。
答案 0 :(得分:0)
根本原因很清楚:
无法将JSON数组反序列化为:类tzpl.model.Activity
反序列化器看到的下一个东西是一个数组,但是您说它应该是一个Activity对象,因此它无法工作。
答案 1 :(得分:0)
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-moxy</artifactId>
</dependency>
改变对这个的依赖。它会正常工作。