Java EE 6:如何在应用程序客户端上添加Web模块 [英] Java EE 6: How to add web module on top of application client

查看:337
本文介绍了Java EE 6:如何在应用程序客户端上添加Web模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

技术(Java EE 6 with Glassfish 3.1,Netbeans 7.0)

我有一个应用程序客户端访问一个数据库通过JPA。不涉及 EJB 。现在我需要为此应用程序客户端添加一个Web界面。所以我会选择使用 JSF 2.x 。我对这里的设计有一些关注,希望社区能够帮助我。 所以感谢BalusC,我可以在独立的客户端应用程序中使用JPA ,在持久性中指定 transaction-type = RESOURCE_LOCAL .XML。以下是演示:

I have an application client that access a db via JPA. No EJB is involved. Now I need to add an web interface for this application client. So I will choose to use JSF 2.x. I have some concern about design here, and I hope the community would help me out. So thanks to BalusC, I am able to use JPA in a stand alone client application by specify transaction-type=RESOURCE_LOCAL in the persistence.xml. Below are demonstration:

编辑以下代码已根据BalusC建议编辑

这是我的应用客户端 main

public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("CoreInPU");
    EntityManager em = emf.createEntityManager();
    EntityDAO entityDAOClient = new EntityDAOClient(em);
    Main pgm = new Main();
    try {
        process(entityDAOClient);
    } catch (Exception e) {
        logger.fatal("", e);
    }finally{
        em.close();
        emf.close();
    }
}

public void process(EntityDAO entityDAO){
    validatePDF(List<pdfFiles>);
    processPDF(List<pdfFiles>, entityDAO);
    createPrintJob(List<pdfFiles>, entityDAO);
}

public void processPDF(List<pdfFiles>, EntityDAO entityDAO){
    for(File file : pdfFiles){
        entityDAO.create(file);
    }
}

这是我的 DAO 我的应用客户端中的接口类

public interface EntityDAO {
    public <T> T create(T t);
    public <T> T find(Class<T> type, Object id);
    public List findWithNamedQuery(String queryName);
    public List findWithNamedQuery(String queryName, int resultLimit);

}

这里是 App Client DAO

public class EntityDAOClient implements EntityDAO {

    private EntityManager em;

    private static Logger logger = Logger.getLogger(EntityDAOClient.class);

    public EntityDAOClient(EntityManager em) {
        this.em = em;
    }

    @Override
    public <T> T create(T t){
        em.getTransaction().begin();
        em.persist(t);
        em.getTransaction().commit();
        return t;
    }

    @Override
    public <T> T find(Class<T> type, Object id){
        em.getTransaction().begin();
        T t = em.find(type, id);
        em.getTransaction().commit();
        return t;
    }
    ...
}

这里是 persistence.xml

<persistence-unit name="CoreInPU" transaction-type="RESOURCE_LOCAL">
   <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
   <class>com.wf.docsys.core.entity.Acknowledgement</class>
   <class>com.wf.docsys.core.entity.PackageLog</class>
   <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/core"/>
      <property name="javax.persistence.jdbc.password" value="root"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="xxxx"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
   </properties>
</persistence-unit>

现在我需要添加一个Web模块。我知道我需要 JTA 事务类型,所以我创建一个EAR项目调用 foo foo_ejb foo_war 。所以我的EJB看起来像这样。

Now I need to add a web module on top of this. I know I need JTA transaction type, so I create an EAR project call foo with foo_ejb and foo_war in it. So my EJB look like this.

@Stateless
@LocalBean
public class CoreEJB implements EntityDAO{

    @PersistenceContext(unitName = "CoreInWeb-ejbPU")
    private EntityManager em;

    //@Override
    public <T> T create(T t) {
        em.persist(t);
        return t;
    }

    //@Override
    public <T> T find(Class<T> type, Object id) {
        return em.find(type, id);
    } 

    ...
}

请注意, CoreInWeb-ejbPU 是具有 JTA 事务类型的新的persistence.xml单元名称。我还将我的应用程序客户端jar文件添加到 foo_ejb 包中。 当我部署我得到这个消息无效的ejb jar [foo-ejb.jar]:它包含零ejb。这是因为这个 @Stateless public class CoreEJB实现EntityDAO 。如果我把实现EntityDAO ,那么它是部署的,但是我需要EJB来实现 EntityDAO 我的托管bean我可以这样做

Note that CoreInWeb-ejbPU is the new persistence.xml unit name with JTA transaction type. I also add my app client jar file to the foo_ejb package. When I deploy I got this message Invalid ejb jar [foo-ejb.jar]: it contains zero ejb. It is because of this @Stateless public class CoreEJB implements EntityDAO. If I take the implements EntityDAO out then it is deploy, but I need the EJB to be implements EntityDAO so that in my managed bean I can do this

@ManagedBean
@RequestScoped
public class Bean {

   @EJB
   private CoreEJB coreEJB;


   public Bean() {

   }

   public void runAppClientMainProcess() { 
       //The web interface can also kick off the same process as the app client
       process(coreEJB);
   }

   // ...
}

如何正确执行?请帮助

我知道我可能会问太多,但如果您可以根据上面的结构,告诉我如何添加一个Web模块, 我将不胜感激。一些代码将会很棒。 我还在学习,所以如果我的设计有缺陷,可以随意撕掉它,如果我说服有更好的方法来完成这个任务,我将重新设计一切。底线是,有一组业务逻辑,我想通过应用程序客户端 web界面。喜欢glassfishv3有web界面和管理控制台

I know I might be asking too much here, but if you can base on my structure above, show me how to add a web module in, I would greatly appreciate it. Some codes would be awesome. I am still learning, so if my design is flaw, feel free to rip it, I will redesign everything if I am convince there are better way to accomplish this. Bottom line is, there are a set of business logic, and I want to access those via both application client and web interface. Like how glassfishv3 have web interface and admin console

推荐答案

我想对我迟到的回复表示歉意。我在另一个项目的时间表之后,所以我没有时间为 BalusC kiran 答案写下正确的回复。

I want to apologize for my late reply. I was behind the schedule for another project so I do not have time to write a proper response to BalusC and kiran answers.

kiran 请问我:案例2 - Web模块 - 您已经使用使用)jsf进行演示,CoreEJB用于持久化 - 我不清楚你打算将业务逻辑放在哪里,因为现在不好的是另一个ejb类。

答案:kiran,底线是,我想要同样的一套逻辑在应用程序客户端和Web模块端都可以访问。像glassfish应用服务器。您具有访问相同资源的命令行版本和Web模块版本。

Answer: Hi kiran, the bottom line is that, I want the same set of logic to be access at both app client side and web module side. Like glassfish app server. You have a command line version and web module version accessing the same resources.

BalusC 建议使用 RESOURCE_LOCAL 只需使用应用客户端。然而,一旦我添加了Web模块,我不能让它工作了,即使BalusC也试图与我一起工作。你们可以阅读BalusC的回应和我上面实现的想法(原来帖子的代码是我实施BalusC的想法)。如果我将App Client添加到Java EE项目(EAR)类路径中,当我尝试从App Client访问逻辑时,它不会收到编译错误,但是当我运行Web模块时,它会生成异常,表示它没有看到我尝试从App Client访问的类/方法。所以我决定将所有的逻辑移植到EJB上,使我的App Client非常薄。这些逻辑将通过 javax.ejb.Remote 接口暴露给App Client,并通过 javax.ejb.Local 界面。以下是我这个想法的总体布局。

BalusC suggestion to use RESOURCE_LOCAL work great if I just use application client. However, once I adding the web module on top of it, I cant not get it to work anymore even though BalusC did try to work with me. You guys can read BalusC response and my implementation of his idea above (The code from the original post is my implementation of BalusC idea). If I add the App Client to the Java EE project (EAR) classpath, it receive no compile error when I try to access the logic from App Client, but when i run the web module, it generate Exception saying that it does not see the class/method that I try to access from App Client. So I decide to port all my logic onto EJB and make my App Client very thin. The logics will be exposed to App Client via javax.ejb.Remote interface, and exposed to the Web module via javax.ejb.Local interface. So below is my general layout of this idea.

这是我的 thin App Client(Main)

This is my thin App Client (Main)

public class Main {

    @EJB
    private static CoreMainEJBRemote coreEJBRemote;

    private static Logger logger = Logger.getLogger(Main.class);

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
         coreEJBRemote.process(args[0]);
    }
}

所以在我的EJB端,Java EE项目中的哪个包(EAR)包含EJB和Web模块,我有

So on my EJB side which package inside Java EE project (EAR) that contain EJB and web module, I have

@Stateless
public class CoreMainEJB implements CoreMainEJBRemote, CoreMainEJBLocal {

    @EJB
    private PackageProcessor packageProcessor;

    @Override
    public void process(String configFileName) {
         ...
         //Process config File
         packageProcessor.validatePDF();
         packageProcessor.processPDF();
         ...
    }
}

请注意,由于所有现在在EJB内部的逻辑,我可以使用容器管理的 JTA 事务类型。我喜欢这种方式比自己管理更好。

Note that since all the logics now inside EJB, I can use JTA transaction type, which is container managed. I like it this way better than manage it myself.

有人建议通过RESTful公开业务逻辑。由于我对RESTful不太了解,所以现在我将继续执行这个实现。感谢您的帮助 BalusC kiran

Some people suggestion to exposed the business logics via RESTful. Since I do not know very well about RESTful, I will stay with this implementation for now. Thank you for all your help BalusC and kiran.

这篇关于Java EE 6:如何在应用程序客户端上添加Web模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆