Джерси не может десериализовать java.util.UUID из строки в объекте запроса

2

У меня есть конечная точка, которая принимает DriverJson класса DriverJson качестве полезной нагрузки HTTP-запроса. Класс DriverJson имеет свойство userId которое имеет тип java.util.UUID. Проблема заключается в том, что Джерси не может десериализацию UUID строки в UUID объект. Когда я отлаживаю и проверяю driverJson, свойство userId1 равно null (к счастью, оно не userId1 исключение). Я прочитал эту статью (статью), которая объясняет, что классы, которые имеют fromString(String string) (у него есть java.util.UUID) или конструктор с одним аргументом (String) десериализуются Джерси автоматически (без написания каких-либо дополнительных классов десериализатора). Если я изменю тип 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"
}

Я использую стандартный архетип Джерси (версия 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>
Теги:
rest
serialization
jersey

1 ответ

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;

    /* ... */
}
  • 0
    Я попробовал ваше решение, и оно работает, но я не понимаю, почему я должен писать собственные адаптеры, когда Джерси должен знать, как десериализовать его из коробки? Я также не понимаю, как Джерси может десериализовать String @PathParam в UUID, но когда приходит запрос объектов, он не может?
  • 0
    @anchor мое решение относится к jaxb который по умолчанию не может конвертировать UUID из / в String . @PathParam работает, потому что он обрабатывается не jaxb а самой jersey . Но это только один из возможных способов JSON данные JSON . Я не уверен, но думаю, что есть некоторая неправильная конфигурация между jersey и jaxb . Вы можете попытаться переключиться на jackson serilalization ( jersey-media-json-jackson пакет) , который AFAIK способен обрабатывать UUID из коробки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню