Мой проект является проектом Java Enterprise и состоит из трех модулей:
Моя модель домена находится в EJB. Это включает в себя класс Manufacturer
и класс Model
. Между двумя существует связь один ко многим. Я раскрываю экземпляры этих производителей и моделей через интерфейс 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
и аннотирую поле в классе Manufacturer
с помощью @XmlJavaTypeAdapter(ModelAdapter.class)
. Этот адаптер также находится в моем модуле EJB. Однако возникает проблема, когда Model
необходимо разобрать:
private ModelFacade modelFacade;
@Override
public Model unmarshal(Long id) throws Exception {
return modelFacade.find(id);
}
ModelFacade
, сессионный компонент без состояния, не может быть введен в XmlAdapter
, и поэтому процесс демаршаллинга всегда будет завершаться неудачей.
Мне посоветовали написать MessageBodyReader
, чтобы иметь возможность "вручную" создать экземпляр адаптера и передать фасад в качестве аргумента, но это специальное средство чтения тела сообщения должно быть реализовано в веб-модуле. Мне бы очень хотелось, чтобы такое поведение содержалось в модуле 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);
}
и это будет прекрасно работать, но я не уверен, что это правильный путь. Является ли поиск JNDI из модуля EJB идеальным решением или есть более выгодное?