[英]how to access a @Stateless @LocalBean remotely
I'm following an EJB cookbook , from packt, with the following code: 我正在跟踪来自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;
}
}
How do i access this bean from a class which doesn't extend HttpServlet
? 如何从不扩展
HttpServlet
的类访问此bean? The servlet itself works fine: 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);
}
}
and is viewable from the designated URL: 并可以从指定的URL查看:
thufir@dur:~$
thufir@dur:~$ lynx http://localhost:8080/SalutationApplication-war/SalutationServlet -dump
Dear Sherlock Holmes
thufir@dur:~$
The current structure: 当前结构:
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$
Right now it's fine that it's only a local bean, but ultimately I would like the Salutation.java bean to be accessible remotely. 现在,它只是一个本地bean很好,但是最终我希望Salutation.java bean可以远程访问。 I have a passing familiarity with EJB from Head First EJB , but that's quite old.
我对Head First EJB的EJB已有一定的了解,但这已经很老了。
You can create an interface and add @Remote annotation: 您可以创建一个界面并添加@Remote批注:
@Remote
public interface MyRemoteInterface {
void myRemoteMethod();
}
After this, you can implement this interface in your EJB: 之后,您可以在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
}
}
Obviously you need to inject it in the client like 显然,您需要像这样将其注入客户端
@EJB
MyRemoteInterface remote;
TIP: Don't give access to remote clients of what they don't need. 提示:不要让远程客户端访问不需要的内容。
EDIT: Depends on where is the client: 编辑:取决于在哪里客户端:
(This answer relates the my comment above.) (此答案与我的上述评论相关。)
In objects that are not managed automatically by the container, you can initialize a manual injection by obtaining a reference to the BeanManager
and let the CDI container do all the work for you. 在容器不自动管理的对象中,您可以通过获取对
BeanManager
的引用来初始化手动注入,并让CDI容器为您完成所有工作。 This works with everything that you can also inject into managed beans, but you don't have to do the complicated JNDI lookup. 这适用于您还可以注入到托管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);
}
}
Suppose this was your client: 假设这是您的客户:
public class MyClient {
@EJB private MyEJB myEJB;
public void run() {
if (myEJB == null)
CDIUtils.makeManagedStatic(this);
myEJB.someMethod();
}
}
You can also simply make them managed at creation, this spares the test for null
: 您也可以简单地在创建时对其进行管理,这将测试省去了
null
:
MyClient client = new MyClient();
CDIUtils.makeManagedStatic(client);
client.run(); // etc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.