杰克逊提供商没有将POST数据反序列化为Pojo(Jersey 2.0)

时间:2013-07-09 01:23:46

标签: post jersey jackson deserialization pojo

我正在使用Jackson json提供商和Jersey 2.0。我有这样的Web资源:

@Path("/accesstokens")
public class AccessTokensService {

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response generate(UserCredentials creds) {

    System.out.println("In generate method..");
    System.out.println(creds);
    try {
        // Authenticate .. generate token ..
        return Response.ok(token, MediaType.APPLICATION_JSON).build();
    }
    catch (Exception e) {
        e.printStackTrace();
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }
}
}

UserCredentials Pojo类如下:

public class UserCredentials {

private String username;
private String password;
private String ipAddress;

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getIpAddress() {
    return ipAddress;
}

public void setIpAddress(String ipAddress) {
    this.ipAddress = ipAddress;
}
}

以下是web.xml的相关摘录:

<servlet>
    <servlet-name>jersey-rest-service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.xxxxx.apps.ws.services;com.fasterxml.jackson.jaxrs.json;com.xxxxxx.apps.servlet;com.xxxxxx.apps.ws.filters</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
        <param-value>com.xxxxxx.apps.ws.filters.LoggingFilter</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

以下是POST实体数据的样子:

{"username":"xxxxx", "password":"xxxxxx", "ipAddress": "xxx.xxx.xxx.xxx"}

不幸的是,Jackson提供商没有反序列化上面的JSON。将一个null UserCredentials对象注入到上面的Web资源POST方法中。如果我使用自定义的MessageBodyReader,我的Reader的readFrom方法被调用,我可以创建UserCredentials pojo,然后在POST方法中可用。

几个问题:

1)我是否需要在Pojo上对Jackson进行任何特殊注释以识别它?是否需要在web.xml中添加Pojo的包?

2)web.xml中的这个属性是否相关:“com.sun.jersey.api.json.POJOMappingFeature”?

3)我是否需要添加ObjectMapper?我认为只需要为自定义案例做,但请告知。

3)还有其他陷阱吗?有没有办法在Jackson中调试代码?

感谢。

3 个答案:

答案 0 :(得分:2)

1)您不需要任何特殊注释

2)没有POJOMappingFeature似乎不再相关

3)不,您不需要添加ObjectMapper

4)是的任何其他陷阱:

编写一个扩展javax.ws.rs.core.Application的类,并将JacksonFeature添加到已配置的类中(您必须将它放在类路径中,添加到您的maven配置中):

package com.example;
public class YourApplication extends Application {

    @Override
    public final Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<>(1);
        set.add(JacksonFeature.class);
        return set;
    }

}

在web.xml的servlet配置下的web.xml中添加以下参数:

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.example.YourApplication</param-value>
    </init-param>

应该这样做。不幸的是,它确实让球衣2.0变得更加困难。

答案 1 :(得分:0)

如果您使用标准的Jackson 2.x JAX-RS提供商:

https://github.com/FasterXML/jackson-jaxrs-providers

除了在classpath中添加它之外,你不应该做任何其他事情;它有SPI元数据,应该自动注册提供者。

Jackson 1.x提供商没有添加此内容,因为担心它可能会干扰其他选项。 但是对于2.x,似乎没有必要这样做。

答案 2 :(得分:0)

我知道出了什么问题。我附加了一个LoggingFilter来处理请求。它正在从实体流中读取实体。因此杰克逊没有任何东西可以阅读和处理。傻傻的我!