Jakarta ee 在WAR打包应用程序的@FacesConverter/Validator中获取Entitymanager/EJB

Jakarta ee 在WAR打包应用程序的@FacesConverter/Validator中获取Entitymanager/EJB,jakarta-ee,java-ee-6,ejb-3.1,jsf-2,Jakarta Ee,Java Ee 6,Ejb 3.1,Jsf 2,我有一个JavaEE6应用程序运行在GlassFishV3.0.1和EJB3.1上(应用程序打包为WAR),我所有的EJB都是@LocalBeans。 目前,我正在编写一个用于JSF2的FacesConverter,其中需要EntityManager从id中获取实体 现在我想知道,既然我们在JEE6上,哪种方法是将Entitymanager放在FacesConverter中的最好和最干净的方法?或者我甚至可以通过表达式语言访问EJB?而Weld/CDI在FacesConverter内部不起作用,

我有一个JavaEE6应用程序运行在GlassFishV3.0.1和EJB3.1上(应用程序打包为WAR),我所有的EJB都是@LocalBeans。 目前,我正在编写一个用于JSF2的FacesConverter,其中需要EntityManager从id中获取实体

现在我想知道,既然我们在JEE6上,哪种方法是将Entitymanager放在FacesConverter中的最好和最干净的方法?或者我甚至可以通过表达式语言访问EJB?而Weld/CDI在FacesConverter内部不起作用,或者是吗

@FacesConverter(value="subscriptionListConverter")
class SubscriptionListConverter extends Converter {
  public Object getAsObject(FacesContext ctx, UIComponent comp, String value) {
    var id:Long = Long.parseLong(value);
    // How to get the entitymanager?
    return em.find(User.getClass, id);
  }

  public String getAsString(ctx:FacesContext, comp:UIComponent, value:Object) {...}
}

抱歉,我希望这不是重复的,但大多数情况下,我看到的地方略有不同,对我没有多大帮助。

好的,经过一些尝试后,我通过手动查找成功获得了一个EJB:

Context ctx = new InitialContext();
UserEJB userEJB = (UserEJB) ctx.lookup("java:global/teachernews/" + UserEJB.class.getName())

看起来没问题,但无论如何,如果有其他有趣的方法,请随意发布。

好的,在尝试了一番之后,我成功地通过手动查找获得了一个EJB:

Context ctx = new InitialContext();
UserEJB userEJB = (UserEJB) ctx.lookup("java:global/teachernews/" + UserEJB.class.getName())

看起来不错,但无论如何,如果有其他有趣的方法,请随意发布。

我也在使用手动查找,但我创建了一个实现转换器接口的抽象类,以扩展到不同的转换器,并有一个获取EJB的方法。要在不同的应用程序中重用它,我已执行以下操作以获取Appname和web模块名称:

abstract public class Converter implements javax.faces.convert.Converter
{
    public Object getManager(String jndiName) throws NamingException
    {
        ServletContext servletContext = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
        Context env = new InitialContext();
        String aname = (String)env.lookup("java:app/AppName");
        if (aname == null || aname.length() == 0 || servletContext.getContextPath().equals(aname)) //FIXME If deploying war inside an ear, appname equals module name, won't work.
            return env.lookup("java:global/" + aname + "/" + jndiName);
        else
            return env.lookup("java:global/" + aname + servletContext.getContextPath() + "/" + jndiName);
    }
}

我也在使用手动查找,但我创建了一个实现转换器接口的抽象类,以扩展到不同的转换器,并有一个获取EJB的方法。要在不同的应用程序中重用它,我已执行以下操作以获取Appname和web模块名称:

abstract public class Converter implements javax.faces.convert.Converter
{
    public Object getManager(String jndiName) throws NamingException
    {
        ServletContext servletContext = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
        Context env = new InitialContext();
        String aname = (String)env.lookup("java:app/AppName");
        if (aname == null || aname.length() == 0 || servletContext.getContextPath().equals(aname)) //FIXME If deploying war inside an ear, appname equals module name, won't work.
            return env.lookup("java:global/" + aname + "/" + jndiName);
        else
            return env.lookup("java:global/" + aname + servletContext.getContextPath() + "/" + jndiName);
    }
}

我刚刚使用@EJB将它们注入到我的转换器中。

我刚刚使用@EJB将它们注入到我的转换器中。

好吧,这应该只适用于接缝面,但没有它,转换器/验证器不支持注入。至少在我的问题中提到的配置中没有。AFAIK这应该只适用于接缝面,但是没有它转换器/验证器不支持注入。至少在我的问题中提到的配置中没有。