我正在使用以下代码关注来自packt的EJB cookbook:
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);
}
}
可从指定的网址查看:
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,但这已经很老了。
答案 0 :(得分:2)
您可以创建一个界面并添加@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;
提示:不要向远程客户端提供他们不需要的内容。
编辑: 取决于客户在哪里:
答案 1 :(得分:2)
(这个答案与我上面的评论有关。)
在容器不自动管理的对象中,您可以通过获取对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