java – 使用JAXB将子类实例作为超类传递

前端之家收集整理的这篇文章主要介绍了java – 使用JAXB将子类实例作为超类传递前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一组代表消息类型的 Java类(接近25).他们都是继承自我想抽象的Message类.每个消息类型为Message超类提供的集合添加了一些附加字段.

我正在使用RESTeasy实现一些RESTful Web服务,并希望有这样的方法

  1. public Response persist(Message msg) {
  2. EntityTransaction tx = em.getTransaction();
  3. tx.begin();
  4. try {
  5. em.persist(msg);
  6. } catch (Exception e) {
  7. e.printStackTrace();
  8. }
  9. tx.commit();
  10. em.close();
  11. return Response.created(URI.create("/message/" + msg.getId())).build();
  12. }

而不是使用25个单独的持久化方法

目前,我已经注释了我的Message类,如下所示:

  1. @MappedSuperclass
  2. @XmlRootElement(name = "message")
  3. public abstract class Message implements Serializable {
  4.  
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.AUTO)
  7. Integer id;
  8. @Embedded
  9. Header header;
  10. @Embedded
  11. SubHeader subHeader;

我的子类看起来像这样:

  1. @Entity
  2. @XmlRootElement(name="regmessage")
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. public class REGMessage extends Message {
  5.  
  6. @XmlElement(required = true)
  7. int statusUpdateRate;
  8. @XmlElement(required = true)
  9. int networkRegistrationFlag;

这将创建一个看起来像应该工作的模式,但是在持久化操作期间在服务器端看到的所有模式都是一个Message对象(子类型完全丢失,或者至少没有被编组回到其正确的子类型).在客户端,调用方法我这样做:

  1. REGMessage msg = new REGMessage();
  2. // populate its fields
  3. Response r = client.createMessage(msg);

是我试图可能的吗我需要使用什么JAXB魔术来使翻译发生在他们应该的方式 – 即,将Java中的所有内容视为消息,以保持方法数量仍然保留所有子类型特定信息?

感谢Blaise的博客指南,现在看起来正在全面的工作.这是我已经得到的,它的工作:

  1. //JAXB annotations
  2. @XmlRootElement(name="message")
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. @XmlSeeAlso(REGMessage.class)
  5. //JPA annotations
  6. @MappedSuperclass
  7. public class Message {
  8.  
  9. @Id
  10. @GeneratedValue(strategy = GenerationType.AUTO)
  11. @XmlAttribute
  12. private Integer id;
  13.  
  14. private JICDHeader header;
  15. private int subheader;
  16.  
  17. @XmlAnyElement
  18. @Transient
  19. private Object body;

我今天早上遇到的一个问题是Hibernate关于列数不匹配的一个隐含的错误.一旦我意识到“身体”正在映射到表中,我标记为短暂的,瞧!

  1. @XmlRootElement(name="regmessage")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. @Entity
  4. public class REGMessage extends Message {
  5.  
  6. private int field1;
  7. private int field2;

现在,该代码生成的唯一表是regmessage表.在RESTeasy方面:

  1. @Path("/messages")
  2. public class MessageResource implements IMessageResource {
  3.  
  4. private EntityManagerFactory emf;
  5. private EntityManager em;
  6.  
  7. Logger logger = LoggerFactory.getLogger(MessageResource.class);
  8.  
  9. public MessageResource() {
  10. try {
  11. emf = Persistence.createEntityManagerFactory("shepherd");
  12. em = emf.createEntityManager();
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. }
  17.  
  18. @Override
  19. @POST
  20. @Consumes("application/xml")
  21. public Response saveMessage(Message msg) {
  22.  
  23. System.out.println(msg.toString());
  24.  
  25. logger.info("starting saveMessage");
  26. EntityTransaction tx = em.getTransaction();
  27. tx.begin();
  28.  
  29. try {
  30. em.persist(msg);
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34.  
  35. tx.commit();
  36. em.close();
  37. logger.info("ending saveMessage");
  38.  
  39. return Response.created(URI.create("/message/" + msg.getId())).build();
  40. }
  41. }

这实现了一个接口:

  1. @Path("/messages")
  2. public interface IMessageResource {
  3.  
  4. @GET
  5. @Produces("application/xml")
  6. @Path("{id}")
  7. public Message getMessage(@PathParam("id") int id);
  8.  
  9. @POST
  10. @Consumes("application/xml")
  11. public Response saveMessage(Message msg) throws URISyntaxException;
  12.  
  13. }

编组&解组工作按预期,持久性是子类的表(根本没有超类表).

我确实看到了Blaise关于JTA的笔记,我可以尝试在完成“Message& REGMessage类完全退出.

解决方法

您是否尝试将以下内容添加到消息类中? @XmlSeeAlso注释将让JAXBContext知道子类.
  1. import javax.xml.bind.annotation.XmlRootElement;
  2. import javax.xml.bind.annotation.XmlSeeAlso;
  3.  
  4. @XmlRootElement
  5. @XmlSeeAlso(RegMessage.class)
  6. public abstract class Message {
  7.  
  8. Integer id;
  9.  
  10. }

替代策略:

这是我帮助人们使用的策略的链接

> http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html

本质上你有一个消息对象和多个单独的消息有效载荷.消息和有效负载之间的关系通过@XmlAnyElement注释来处理.

交易处理说明

我注意到你正在处理你自己的交易.您是否考虑将JAX-RS服务实现为会话bean,并利用JTA进行事务处理?例如:

> http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-45.html

猜你在找的Java相关文章