I'd like a endpoint to accept on a single verb and path a json payload that varies by a tiny bit and that can be mapped to different objects. The variation is usually on the field value like the grant_type
in the OAuth world.
I scrapped stackoverflow and google on this, I found this among other
- JAX-RS polymorphic POST request: how should I write my JSON?
- Polymorphism in JSON, Jersey and Jackson
But those question don't seem to be relevant to me, jackson deserialisation alone works fine for this payloads, but Jersey always refuses to init the servlet with an error that let me thinks there's no way around it.
@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 {
}
However I get this message in an exception upon servlet initialisation. (edited message for clarity)
</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']
Note however that having a endpoint with the parent class of the payload works, but you have to handle the dispatch yourself.
@POST
@Path("test")
String test(BasePayload payload);
I'm using Spring-Boot 1.4 / Jersey 2.23.2 / Jackson 2.8.5