【问题标题】:Jersey error deserializing ArrayList from JSON stringJersey 错误从 JSON 字符串反序列化 ArrayList
【发布时间】:2016-03-29 20:42:49
【问题描述】:

这里是重要信息。使用泽西岛 1.6。将这种相同类型的列表序列化到前端没有问题,并且不同类型的列表不会在应用程序的其他地方来回导致问题,所以我认为问题出在 bean 本身。我已经尝试过没有额外的路径参数,我遵循所有的 bean 约定,在 ajax 之前数据看起来很好......真的不知道我的问题出在哪里。除了它是一个 NPE 之外,没有真正给出任何信息。

豆子

public class TheBean implements Serializable{

private static final long serialVersionUID = 1L;
private String beanId;
private String name;
private String beanType;
private Boolean group;

public TheBean(){}

public TheBean(String beanId, String name, String beanType, boolean isGroup) {
    super();
    this.beanId = beanId;
    this.name = name;
    this.beanType = beanType;
    this.group = isGroup;
}


public String getBeanId() {
    return beanId;
}
public void setBeanId(String beanId) {
    this.beanId = beanId;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getBeanType() {
    return beanType;
}
public void setBeanType(String beanType) {
    this.beanType = beanType;
}
public boolean isGroup() {
    return group;
}
public void setGroup(boolean group) {
    this.group = group;
}
}

网络服务

@POST
@Path("/update/{parentId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response updateTheBeanList(ArrayList<TheBean> routeList, @PathParam("parentId") String parentId){
    //code
}

客户端代码

var beanListArray = beanListTable.fnGetData();//looks good here
var json = JSON.stringify(beanListArray);//and here

$.ajax({
    dataType: 'text',
    type: "POST",
    data: json,
    url: '${pageContext.request.contextPath}/rest/beanList/update/' + parentId, //looks good here
});

例外

java.lang.NullPointerException
at org.codehaus.jackson.xc.JaxbAnnotationIntrospector.findAdapter(JaxbAnnotationIntrospector.java:1058)
at org.codehaus.jackson.xc.JaxbAnnotationIntrospector.findDeserializer(JaxbAnnotationIntrospector.java:644)
at org.codehaus.jackson.xc.JaxbAnnotationIntrospector.findDeserializer(JaxbAnnotationIntrospector.java:74)
at org.codehaus.jackson.map.AnnotationIntrospector.findDeserializer(AnnotationIntrospector.java:634)
at org.codehaus.jackson.map.AnnotationIntrospector$Pair.findDeserializer(AnnotationIntrospector.java:1286)

有问题的依赖项

<dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-bundle</artifactId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-multipart</artifactId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.8.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.6</version>
    </dependency>

【问题讨论】:

  • 奇怪,我假设有以下问题: 1. @XmlRootElement 不存在于TheBean。 2. List&lt;TheBean&gt; routeList 而不是 ArrayList&lt;TheBean&gt; routeList 但我没有得到,为什么你得到 NullPointerException - 也许是一个错误,你能更新依赖关系吗?
  • 我没有用@XmlRootElement 注释任何bean,我在Web 服务的其他地方使用ArrayList 没有问题。唯一的区别是额外的路径参数,但我试过没有它。这可能是一个错误,我会修改依赖项。
  • 也许可以,但试一试,用 @XmlRootElement 注释 TheBean 并将返回类型更改为 List... 会发生什么?
  • 如果这没有改变任何东西...您可以将 maven 依赖项添加到您的问题中...有时会出现与特定组合相关的奇怪事情...
  • 是的好主意,OP 用 pom sn-p 更新。

标签: jquery json jersey jackson


【解决方案1】:

在您的情况下,Jackson 使用类 org.codehaus.jackson.xc.JaxbAnnotationIntrospector 使用您的 POJO 反序列化/序列化 ArrayList(我假设您在 web.xml 中配置了 com.sun.jersey.api.json.POJOMappingFeature)。

Jackson 正在寻找不存在的注释。请参阅JaxbAnnotationIntrospector.java 中的第 643 行:

Class potentialAdaptee = ((Member)am.getAnnotated()).getDeclaringClass();

其中am.getAnnotated() 是null。

因为您没有“使用@XmlRootElement 注释任何bean”,所以一个简单的解决方案是禁用JaxbAnnotationIntrospector。这可以通过注册自定义ContextResolver 来提供自己的ObjectMapper 实例来完成。

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig.Feature;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
public class PojoObjectMapperProvider implements ContextResolver<ObjectMapper> {

    final ObjectMapper defaultObjectMapper;

    public PojoObjectMapperProvider() {
        defaultObjectMapper = new ObjectMapper();
        defaultObjectMapper.configure(Feature.INDENT_OUTPUT, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {

        return defaultObjectMapper;
    }
}

注册该类:

import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {

        final Set<Class<?>> classes = new HashSet<>();
        classes.add(PojoObjectMapperProvider.class);
        return classes;
    }
}

如果你不使用 web.xml:

ApplicationAdapter rc = new ApplicationAdapter(new MyApplication());
rc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
SelectorThread threadSelector = GrizzlyServerFactory.create(BASE_URI, rc);

【讨论】:

  • 有效。虽然我没有使用确切的代码,但我从另一个项目(我写的:/)中提取了一个类似的 ContextResolver 并且我在做生意。好收获!
猜你喜欢
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 2013-12-13
  • 2021-09-02
相关资源
最近更新 更多