簡體   English   中英

如何遠程訪問@Stateless @LocalBean

[英]how to access a @Stateless @LocalBean remotely

我正在跟蹤來自packt的EJB食譜 ,其中包含以下代碼:

package packt;

import javax.ejb.Stateless;
import javax.ejb.LocalBean;

//@Stateless
@LocalBean
@Stateless(mappedName="salutationBean")
public class Salutation {
    public String getFormalSalutation(String name) {
        return "Dear " + name;
    }
    public String getInformalSalutation(String name) {
        return "Hi " + name;
    }
}

如何從不擴展HttpServlet的類訪問此bean? servlet本身運行良好:

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import packt.Salutation;

@WebServlet(urlPatterns = {"/SalutationServlet"})
public class SalutationServlet extends HttpServlet {

    @EJB
    private Salutation salutation;

    protected void processRequest(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet SalutationServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>"
                    + salutation.getFormalSalutation("Sherlock Holmes")
                    + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } finally {
            out.flush();
            out.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

並可以從指定的URL查看:

thufir@dur:~$ 
thufir@dur:~$ lynx http://localhost:8080/SalutationApplication-war/SalutationServlet -dump
                              Dear Sherlock Holmes


thufir@dur:~$ 

當前結構:

thufir@dur:~/NetBeansProjects$ 
thufir@dur:~/NetBeansProjects$ tree SalutationApplication/
SalutationApplication/
├── build.xml
├── nbproject
│   ├── ant-deploy.xml
│   ├── build-impl.xml
│   ├── genfiles.properties
│   ├── private
│   │   └── private.properties
│   ├── project.properties
│   └── project.xml
├── SalutationApplication-ejb
│   ├── build.xml
│   ├── nbproject
│   │   ├── ant-deploy.xml
│   │   ├── build-impl.xml
│   │   ├── genfiles.properties
│   │   ├── private
│   │   │   └── private.properties
│   │   ├── project.properties
│   │   └── project.xml
│   └── src
│       ├── conf
│       │   └── MANIFEST.MF
│       └── java
│           └── packt
│               └── Salutation.java
├── SalutationApplication-war
│   ├── build.xml
│   ├── nbproject
│   │   ├── ant-deploy.xml
│   │   ├── build-impl.xml
│   │   ├── genfiles.properties
│   │   ├── private
│   │   │   └── private.properties
│   │   ├── project.properties
│   │   └── project.xml
│   ├── src
│   │   ├── conf
│   │   │   └── MANIFEST.MF
│   │   └── java
│   │       └── servlet
│   │           └── SalutationServlet.java
│   └── web
│       ├── index.html
│       └── WEB-INF
└── src
    └── conf
        └── MANIFEST.MF

20 directories, 27 files
thufir@dur:~/NetBeansProjects$ 

現在,它只是一個本地bean很好,但是最終我希望Salutation.java bean可以遠程訪問。 我對Head First EJB的EJB已有一定的了解,但這已經很老了。

您可以創建一個界面並添加@Remote批注:

@Remote
public interface MyRemoteInterface {
    void myRemoteMethod();    
}

之后,您可以在EJB中實現此接口:

@LocalBean
@Stateless(mappedName="salutationBean")
public class Salutation implements MyRemoteInterface {
    public String getFormalSalutation(String name) {
        return "Dear " + name;
    }

    public String getInformalSalutation(String name) {
        return "Hi " + name;
    }

    @Override
    public void myRemoteMethod(){
        // only this method will be visible in a remote interaction
    }
}

顯然,您需要像這樣將其注入客戶端

@EJB
MyRemoteInterface remote;

提示:不要讓遠程客戶端訪問不需要的內容。


編輯:取決於在哪里客戶端:

  • 如果您的客戶端使用的是Java組件(cdi對象,其他EJB,servlet,jaxrs / jaxws工件),則使用@EJB(可能需要添加mapdName)
  • 如果您的客戶在ejb容器之外調用(即,獨立的Java應用程序),則可以使用JNDI查找
  • 如果跨網絡,則可以像網絡服務(@ WebService / @ Path)一樣公開ejb並使用它……如果願意的話。

(此答案與我的上述評論相關。)

在容器不自動管理的對象中,您可以通過獲取對BeanManager的引用來初始化手動注入,並讓CDI容器為您完成所有工作。 這適用於您還可以注入到托管bean中的所有內容,但是您不必執行復雜的JNDI查找。

public class CDIUtils {

    public static BeanManager beanManager() {
        try {
            return (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
        } catch (NamingException e) {
            throw new IllegalStateException("Unable to obtain CDI BeanManager", e);
        }
    }

    public static void makeManagedStatic(Object obj) {
        BeanManager bm = beanManager();
        makeManaged(obj, bm);
    }

    public static void makeManaged(Object obj, BeanManager beanManager) {
        Class objClass = (Class) obj.getClass();
        AnnotatedType annotatedType = beanManager.createAnnotatedType(objClass);
        InjectionTarget injectionTarget = beanManager.createInjectionTarget(annotatedType);
        CreationalContext context = beanManager.createCreationalContext(null);
        injectionTarget.inject(obj, context);
    }

}

假設這是您的客戶:

public class MyClient {
    @EJB private MyEJB myEJB;
    public void run() {
        if (myEJB == null)
            CDIUtils.makeManagedStatic(this);
        myEJB.someMethod();
    }
}

您也可以簡單地在創建時對其進行管理,這將測試省去了null

MyClient client = new MyClient();
CDIUtils.makeManagedStatic(client);
client.run(); // etc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM