繁体   English   中英

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

[英]Best practices incoming object message inheritance using JAX-RS

我想知道在处理对象层次结构中的不同消息时,是否有解决我问题的好方法,或者有好的做法。

简而言之:我有一个对象层次结构,可以这样说:

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端点方法,因为大多数处理程序代码对于这些类都是相同的,但是我们在代码中需要一些条件部分。

例如:

@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,然后根据对象的类的需要对其进行处理。

您对此问题有什么建议吗? 或者,您是否知道有关解决此类问题的最佳做法?

您可以将父类用作消费对象,然后根据某些条件,使用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 { ... }
       ...
  }

尽管我找不到以下解决方案“ nice”或“ elegant”,但这似乎可行:

步骤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. 这可能是因为球衣如何找到给定类型的内容提供者(从最通用的到最具体的,并且因为它找到的是比我更通用的内容提供者,因此不会使用它)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM