【问题标题】:Jersey cannot deserialize java.util.UUID out of String in request objectJersey 无法从请求对象中的 String 中反序列化 java.util.UUID
【发布时间】:2016-09-06 19:36:48
【问题描述】:

我有一个端点,它接受 DriverJson 类实例作为 http 请求负载。 DriverJson 类有一个属性userId,它的类型是java.util.UUID。 问题是 Jersey 无法将 UUID 字符串反序列化为 UUID 对象。当我调试和检查driverJson 时,userId1 属性是null(幸运的是它不会抛出异常)。我已经阅读了这篇文章 (article),它解释了具有 fromString(String string) 方法(java.util.UUID 拥有它)或具有带有一个 (String) 参数的构造函数的类会被 Jersey 自动反序列化(无需编写任何额外的反序列化器类)。如果我将UUID 类型更改为String 并将其转换为我自己(UUID.fromString(userId)),它工作得很好。

此外,我在一些端点中使用了@PathParam UUID 参数,它们运行良好(如预期的那样)。

下面是我的代码:

我的资源端点:

@POST
public Response add(DriverJson driverJson) {
    DriverJson driver = service.add(driverJson);
    return Response.status(Response.Status.CREATED).entity(driver).build();
}

我的驱动类:

@XmlRootElement
public class DriverJson {

    private UUID id;
    private String name;
    private UUID userId;

    public DriverJson() {}

    public DriverJson(UUID id, String name, UUID userId){
        this.id = id;
        this.name = name;
        this.userId = userId;
    }


    /// getters & setters /////////

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public UUID getUserId() {
        return userId;
    }

    public void setUserId(UUID userId) {
        this.userId = userId;
    }
}

我的 JSON 请求对象:

{
  "name" : "John", 
  "userId" : "ff06c5a4-135c-40b7-83f3-3648ec035efc"
}

我正在使用具有以下依赖项的标准 Jersey 原型(版本 2.23.2):

<dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
            <!-- artifactId>jersey-container-servlet</artifactId -->
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.50</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>16.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.7</version>
        </dependency>
    </dependencies>

【问题讨论】:

    标签: java rest serialization jersey


    【解决方案1】:

    AFAIK 您可以使用自定义 XmlAdapter 修复它:

    public class UUIDAdapter extends XmlAdapter<String, UUID> {
    
        @Override
        public UUID unmarshal(String v) throws Exception {
            return UUID.fromString(v);
        }
    
        @Override
        public String marshal(UUID v) throws Exception {
            return v.toString();
        }
    }
    

    然后用@XmlJavaTypeAdapter注解标记你的字段

    @XmlRootElement
    public class DriverJson {
    
        @XmlJavaTypeAdapter(UUIDAdapter.class)
        private UUID id;
        @XmlJavaTypeAdapter(UUIDAdapter.class)
        private UUID userId;
    
        /* ... */
    }
    

    【讨论】:

    • 我尝试了您的解决方案并且它有效,但我不明白为什么我必须编写自定义适配器,而 Jersey 应该知道如何开箱即用地反序列化它?我也不明白 Jersey 如何将 String @PathParam 反序列化为 UUID,但是当涉及到请求对象时,它不能?
    • @anchor 我的解决方案适用于jaxb,默认情况下无法将UUID 从/到String 转换。 @PathParam 有效,因为它不是由jaxb 处理,而是由jersey 本身处理。但这只是 one possible way 编组 JSON 数据。我不确定,但猜测jerseyjaxb 之间存在一些错误配置。您可以尝试切换到 afaik 能够处理 UUID 开箱即用的jackson 序列化(jersey-media-json-jackson 包)。
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2016-12-30
    • 1970-01-01
    相关资源
    最近更新 更多