Java 使用JAX-RS实现传入对象消息继承的最佳实践

Java 使用JAX-RS实现传入对象消息继承的最佳实践,java,inheritance,jax-rs,jersey-2.0,Java,Inheritance,Jax Rs,Jersey 2.0,我想知道在处理来自对象层次结构的不同消息方面是否有一个很好的解决方案,或者是否有很好的实践 简而言之,我有一个对象层次结构,比如说: interface IMessage abstract Message implements IMessage class SimpleMessage extends Message class ReportMessage extends SimpleMessage class CostReportMessage extends ReportMessage cl

我想知道在处理来自对象层次结构的不同消息方面是否有一个很好的解决方案,或者是否有很好的实践

简而言之,我有一个对象层次结构,比如说:

interface IMessage 
abstract Message implements IMessage
class SimpleMessage extends Message
class ReportMessage extends SimpleMessage
class CostReportMessage extends ReportMessage
class IncomeReportMessage extends ReportMessage
... (like 3 other types, similar to the CostReportMessage)
因此,我希望有一个传入的JAX-RS端点方法,因为大多数处理程序代码对于类是相同的,但我们需要代码中的一些条件部分

例如:

所以我们有一些类似于上面的方法,但是我想把它变成一个,比如接收一个传入的IMessage,然后在对象的类需要时处理它


你对这个问题有什么建议吗?或者您知道如何解决此类问题的最佳做法吗?

您可以使用父类作为已使用的对象,然后根据特定条件使用BeanUtils.copyProperties将所有属性复制到新的专用消息对象,例如:在SimpleMessage中有messageTypeID变量来告诉它应该是什么类型的消息

  @POST
  @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
  @Produces({ MediaType.APPLICATION_XML + "; charset=UTF-8", MediaType.APPLICATION_JSON + "; charset=UTF-8"})
  public Response createReport(  SimpleMessage message, @Context HttpHeaders headers ) {
       SimpleMessage convertedMessage;
       if(//condition//) {
           convertedMessage = new ReportMessage();
           BeanUtils.copyProperties(convertedMessage, message);
       } else { ... }
       ...
  }

虽然我觉得以下解决方案不好,也不优雅,但这似乎是可行的:

第一步。创建一个函数

private IMessage parseRequest(String request) throws IOException, JAXBException{
    StringReader reader = new StringReader(request);
    // unmarshaller here is a simple JAXB Unmarshaller for the message package
    IMessage message = (SimpleMessage) unmarshaller.unmarshal(reader); 
    return message;
}
第二步。修改jaxb入口点

@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML + "; charset=UTF-8", MediaType.APPLICATION_JSON + "; charset=UTF-8"})
public Response createReport(  final String request, @Context HttpHeaders headers ) {
    IMessage message = parseRequest(request);
    ...
    ...
    return response;
}
所以我认为,这是因为以下原因,这只是我的理论,但我不知道从哪里寻找真相:

JAX-RS只是检查类型,并创建一个对应于方法签名中给定类型的解组器。 JAX-RS将无法在方法param中提供IMessage,因为接口没有构造函数 由于JAX-RS创建的解组器只会创建一个上下文,该上下文知道SimpleMessage,因此它将无法解组任何子类,例如CostReportMessage 好的解决方案是提供一个定制的MessageBodyReader@Provider注释,但我无法让它工作 这可能是因为jersey为给定类型找到内容提供者的方式从最通用到最具体,并且因为它找到了比我更通用的内容提供者,所以它不会使用它
隐马尔可夫模型。。很好的捕获,我将研究它。它不起作用,因为JAX-RS运行时只知道SimpleMessage类,会使用该类,不会知道,传入消息的另一部分,例如,它不会解组CostReportMessage类的细节。如果每个特定消息类都有自己的属性对象变量,那么您可以尝试在方法参数中使用对象类型,然后根据特定的条件将其转换为特定的消息类型类对象,正如我建议使用对传递对象属性1的反射
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML + "; charset=UTF-8", MediaType.APPLICATION_JSON + "; charset=UTF-8"})
public Response createReport(  final String request, @Context HttpHeaders headers ) {
    IMessage message = parseRequest(request);
    ...
    ...
    return response;
}