2016-09-06 2 views
1

У меня есть конечная точка, которая принимает экземпляр класса DriverJson в качестве полезной нагрузки запроса http. Класс DriverJson имеет свойство userId, которое имеет тип java.util.UUID. Проблема в том, что Джерси не может десериализовать UUID строку в UUID объект. Когда я отлаживаю и проверяю driverJson, userId1 свойство null (к счастью, это не исключение). Я прочитал эту статью (article), которая объясняет, что классы, которые имеют метод fromString(String string) (java.util.UUID), имеют конструктор с одним аргументом (String), который десериализуется Джерси автоматически (без написания каких-либо дополнительных классов десериализатора). Если я меняю UUID на String, и я конвертирую его сам (UUID.fromString(userId)), он отлично работает.Джерси не может десериализовать java.util.UUID из строки в объекте запроса

Кроме того, я использую аргументы @PathParam UUID в некоторых моих конечных точках, и они работают отлично (как и ожидалось).

Ниже мой код:

Мой ресурс конечных точек:

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

Мой класс Driver:

@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" 
} 

Я использую стандартная арка Джерси ETYPE (версия 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> 

ответ

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, но когда приходит запрос объектов, он не может? – anchor

+0

@anchor мое решение относится к 'jaxb', который по умолчанию не может преобразовать' UUID' из/в 'String'. '@ PathParam' работает, потому что он не обрабатывается' jaxb', а сам 'jersey'. Но это только [один возможный путь] (https://jersey.java.net/documentation/latest/media.html#d0e8052) для маршалирования данных JSON. Я не уверен, но думаю, что есть некоторая неправильная конфигурация между 'jersey' и' jaxb'. Вы можете попробовать переключиться на сериализацию «jackson» (пакет 'jersey-media-json-jackson'), который * afaik * способен обрабатывать' UUID' из коробки. – vsminkov

Смежные вопросы