是否有可能使用Jersey实现POST资源上json有效负载的多态反序列化

时间:2017-09-22 16:21:34

标签: jackson jersey-2.0

我希望端点能够接受单个动词和路径一个json有效负载,该负载稍微变化并且可以映射到不同的对象。变体通常与字段值类似,如OAuth世界中的grant_type

我废弃了stackoverflow并谷歌,我在其他

中找到了这个

但是这些问题似乎与我无关,杰克森反序列化对于这个有效负载来说效果很好,但是泽西总是拒绝使用错误启动servlet,让我觉得它没有办法解决它。

@Path("parent")
interface Resource {
    @POST
    @Path("test")
    String test(Payload1 payload1);

    @POST
    @Path("test")
    String test(Payload2 payload1);

    @Data
    @JsonTypeName("payload1")
    class Payload1 extends BasePayload {
        String a;
    }

    @Data
    @JsonTypeName("payload2")
    class Payload2 extends BasePayload {
        String b;
    }

//    @JsonTypeInfo(use= Id.MINIMAL_CLASS, include=As.PROPERTY, property="@class")
    @JsonTypeInfo(use= Id.NAME, include=As.PROPERTY, property="@payload")
    @JsonSubTypes({
                      @JsonSubTypes.Type(value = Payload1.class),
                      @JsonSubTypes.Type(value = Payload2.class)
    })
    class BasePayload {
    }

但是我在servlet初始化时遇到异常。 (为清晰起见,已编辑的信息)

</pre><p><b>root cause</b></p><pre>
org.glassfish.jersey.server.model.ModelValidationException: 
  Validation of the application resource model has failed during application initialization.

[[FATAL] A resource model has 
ambiguous (sub-)resource method for HTTP method POST and input mime-types as defined by
 "@Consumes" and "@Produces" annotations 
at Java methods 
 public java.lang.String xxx.Service.test(xxx.Resource$Payload1) 
and 
 public java.lang.String xxx.Service.test(xxx.Resource$Payload2) 
at matching regular expression /test. 

These two methods produces and consumes exactly the same mime-types and 
therefore their invocation as a resource methods will always fail.;
source='org.glassfish.jersey.server.model.RuntimeResource@59b668bf']

但请注意,让端点与有效负载的父类一起工作,但您必须自己处理调度。

@POST
@Path("test")
String test(BasePayload payload);

我正在使用Spring-Boot 1.4 / Jersey 2.23.2 / Jackson 2.8.5

1 个答案:

答案 0 :(得分:1)

JAX-RS运行时使用以下方法将请求与资源方法匹配:

  • URI:@Path注释中定义。

  • 请求方法:由资源方法指示符定义,例如@GET@POST等。

  • 媒体类型:在AcceptContent-Type标头中定义,与@Produces和{{3}中定义的值相匹配分别是注释。

没有考虑有效载荷的内容,因此它使您的第一个方法定义不明确。

正如您已经想到的那样,以下方法是可行的方法:

@POST
@Path("test")
String test(BasePayload payload);