【发布时间】:2011-10-12 07:39:39
【问题描述】:
我的项目是一个 Java Enterprise 项目,由三个模块组成:
- 组件 (EAR)
- EJB (JAR)
- 网络 (WAR)
我的域模型驻留在 EJB 中。这包括Manufacturer 类和Model 类。两者之间存在一对多的关系。我通过驻留在我的 Web 项目中的 REST 接口公开这些制造商和模型的实例。
每当我访问这些制造商之一时,都会生成以下 XML 代码:
<manufacturer id=1>
<name>Ford</name>
<models>
<model id=1>
<name>Fiesta</name>
</model>
<model id=2>
<name>Focus</name>
</model>
</models>
</manufacturer>
但是,我希望它是这样的:
<manufacturer id=1>
<name>Ford</name>
<models>
<model>1</model>
<model>2</model>
</models>
</manufacturer>
我通过写一个专门的XmlAdapter,ModelAdapter,并用@XmlJavaTypeAdapter(ModelAdapter.class)注释Manufacturer类中的字段,达到了预期的效果。这个适配器也驻留在我的 EJB 模块中。但是,当需要对 Model 进行解组时,就会出现问题:
private ModelFacade modelFacade;
@Override
public Model unmarshal(Long id) throws Exception {
return modelFacade.find(id);
}
ModelFacade 是一个无状态会话 bean,不能注入到 XmlAdapter 中,因此解组过程总是会失败。
有人建议我写一个MessageBodyReader,以便能够“手动”实例化适配器并将外观作为参数传递,但是这个专门的消息正文阅读器需要在 web 模块中实现。我非常希望在 EJB 模块中包含这种行为,原因很简单,例如,如果我决定创建一个依赖于 EJB 的桌面应用程序,我不需要再次处理相同的问题。
为了实现这种行为,我可以在适配器的构造函数中执行 JNDI 查找:
public AbstractAdapter(String name) throws NamingException {
facade = (AbstractFacade<B>) lookup("java:app/MyEJB/" + name);
}
private Object lookup(String name) throws NamingException {
Context c = new InitialContext();
return c.lookup(name);
}
这将完全正常,但我不确定这是正确的方法。从 EJB 模块进行 JNDI 查找是一个完美的解决方案还是有更好的解决方案?
【问题讨论】:
-
您的解决方案简洁明了,不涉及任何黑客攻击。您为什么要寻找其他解决方案?
-
@Kingo 感谢您的回复!我很沉默,因为它涉及将我的 EJB 的名称嵌入到静态字符串中。如果模块曾经使用不同的名称部署怎么办?用户需要进入源代码才能更改它。还有什么让我退缩的是,虽然您说它不涉及黑客攻击,但在 CDI 环境中执行 JNDI 查找确实感觉如此。它有多常见?
标签: java jakarta-ee jaxb jersey