自定义对象在 Jax-RS 中反序列化很好,但如果它在另一个对象中使用,则它不起作用

Custom object deserializes fine in Jax-RS but if it is used in another object it doesn't work

如果我只是将我的自定义对象传递给

,反序列化工作正常
@POST
public Response saveCustomObject(CustomObject data)
{
    // Prints correct value
    System.out.println(data);
}

但是,如果它是另一个对象上的属性,它只是获取我的自定义对象的默认值

@POST
public Response saveCustomObjectWrapper(CustomObjectWrapper data)
{
    // Prints incorrect value
    System.out.println(data.getCustomObject());
}

我的提供商已注册,如下所示:

public CustomObject readFrom(Class<CustomObject> type, Type type1, Annotation[] antns, MediaType mt, MultivaluedMap<String, String> mm, InputStream in) throws IOException, WebApplicationException
{
    try {
        return new CustomObject(IOUtils.toString(in));
    } catch (Exception ex) {
        throw new ProcessingException("Error deserializing a CustomObject.", ex);
    }
}

问题是所有其他对象的 reader 在解组时不执行 lookup/delegation。我的意思是,可以在 中看到,其中一个 reader 根据类型查找另一个 reader。假设格式为 JSON,无论您使用的是 MOXy(Glassfish 的默认格式)还是 Jackson,结果都是一样的。 reader 足够聪明,可以自己处理 JSON,因此不需要查找任何其他 reader。

一个解决方案是为包装器 class 创建另一个 reader,然后执行 lookup/delegation,如上文 link 所示。如果你有很多这样的情况,你可以扩展默认 reader,并覆盖它的解组方法,但我完全不建议这样做,除非你真的知道你在做什么。

根据您使用的序列化器,另一种解决方案是编写 JsonDeserializer(对于 Jackson)或 XmlAdapter(对于 MOXy 或 Jackson)。对于杰克逊来说,一个例子是这样的(你可以看到一个更好的例子here

public class CustomObjectDeserializer extends JsonDeserializer<CustomObject> { 

    @Override
    public CustomObject deserialize(JsonParser jp, DeserializationContext dc) 
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        return new CustomObject("Hello World");
    }
}

@JsonDeserialize(using = CustomObjectDeserializer.class)
public class CustomObject {
    public String message;
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
    public CustomObject(String message) { this.message = message; }
    public CustomObject(){}
}

在这种情况下,根本不需要自定义 reader。这将处理 CustomObject 和具有 CustomObject 作为成员的对象。一个问题是我不确定如何或是否可以得到 InputStream。您只需要使用 Jackson API 来解析 JSON.

如果您想使用 Jackson 而不是 glassfish 的默认 MOXy,您只需添加 Jackson 依赖项

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.13</version>
</dependency>

然后注册 JacksonFeature,或者简单地禁用 MOXy,如前所述 . If you want to continue using MOXy, I don't know if there is such thing as a class level adapter, so you will still need the reader as well as create a XmlAdapter for class members. It's a bit of a hassle, but that's why I recommend Jackson, for many other reasons, besides this particular use case. You can see an example of an adapter

现在很多答案都是基于您使用 JSON 格式的假设,因为您没有指定您正在使用的媒体类型。如果是其他格式,那么我认为您唯一的解决方案可能是为包装器创建另一个客户 reader。