[英]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;
提示:不要讓遠程客戶端訪問不需要的內容。
編輯:取決於在哪里客戶端:
(此答案與我的上述評論相關。)
在容器不自動管理的對象中,您可以通過獲取對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.