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

时间:2015-11-10 10:30:46

标签: 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
class IncomeReportMessage extends ReportMessage
... (like 3 other types, similar to the CostReportMessage)

所以我想要的是有一个传入的JAX-RS端点方法,因为大多数处理程序代码对于类是相同的,但我们需要代码中的一些条件部分。

E.g:

@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 ReportMessage, @Context HttpHeaders headers ) {
...
...
}

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

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

2 个答案:

答案 0 :(得分:0)

您可以使用父类作为使用对象,然后使用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 { ... }
       ...
  }

答案 1 :(得分:0)

虽然我没有找到以下解决方案“很好”或“优雅”,但这似乎有效:

步骤1.创建一个功能

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;
}

步骤2.修改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;
}

所以我想,这是因为以下(这只是我的理论,但我不知道在哪里寻找真相):

  1. JAX-RS只是检查类型,并创建一个与方法签名中给出的类型相对应的Unmarshaller。
  2. JAX-RS将在方法参数中给出IMessage失败(因为接口没有构造函数)
  3. 由于JAX-RS创建的Unmarshaller只会创建一个知道SimpleMessage的上下文,因此它无法解组任何子类,例如: CostReportMessage
  4. 好的解决方案是提供自定义MessageBodyReader(@Provider注释),但我无法让它工作
  5. 这可能是因为球衣如何找到给定类型的内容提供者(从最通用到最具体,并且因为它找到比我更通用的内容提供者,它将不会使用它)
相关问题