Advanced Java Services | Servlet Bean Kommunikation |
Es ist ab der Version 3.0 ziemlich einfach für ein Servlet eine Verbindung zu einer Bean aufzunehmen. Mit Hilfe
einer einzigen Annotation gelingt die kontaktaufnahme. Das nächste Beispiel beschreibt ein Servlet, das Kontakt zu
unserer ersten stateless Sessionbean aufnimmt.
Da wir auch hier keine Packages verwenden sollten Sie als Übung das Beispiel wieder so abändern, daß Sie Packages
einsetzen. Sie können sehr leicht auch ein Servlet schreiben, daß unsere stateful Sessionbean anspricht.
Wir legen eine Webapplikation mit einer Servletklasse und einer web.xml an.
1 Kontaktaufnahme mit InitialContext
Das erste Servlet verwendet zur Kontaktaufnahme einen IntialContext.
Die Servletklasse
/* Servlet class Remote Interface: @Stateless(name="SayHello", mappedName="ejb/SayHelloJNDI") */ import java.io.PrintWriter; import java.io.IOException; import java.util.Properties; import javax.servlet.*; import javax.servlet.http.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class BeanServlet1 extends HttpServlet { private SayHello hello; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { initAndLookup(); processRequest(request, response); } protected void initAndLookup() { String jndiName = "ejb/SayHelloJNDI"; Properties env = new Properties(); //env.put("org.omg.CORBA.ORBInitialHost","192.168.45.2"); // default ist localhost !! //env.put("org.omg.CORBA.ORBInitialPort","3700"); // ist default env.put("java.naming.factory.initial","com.sun.enterprise.naming.SerialInitContextFactory"); try { Context ctx = new InitialContext(env); // NamingException //System.out.println ("Trying to get the name of this context: " + ctx.getNameInNamespace()); System.out.println("initial context received"); hello = (SayHello)ctx.lookup(jndiName); // NamingException } catch(NamingException ex) { System.out.println("NamingException " + ex); } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>BeanServlet 1</title>"); out.println("</head>"); out.println("<body>"); out.println("<h2>This is BeanServlet 1<h2>"); out.println("<h2>Answer from the Bean: " + hello.sayHello() + "</h2>"); out.println("</body>"); out.println("</html>"); } }
Die Verzeichnisstruktur einer WEB-Applikation
Unser Servlet müssen wir in die Verzeichnisstruktur einer Webapplikation einbetten:
WEB-INF <dir> | |--- classes <dir> | | | |--- BeanServlet.class <file> | | | |--- SayHello.class <file> | |--- web.xml <file>
web.xml
Die Datei web.xml ist die Konfigurartionsdatei für dieses Webapplikation. Hier wird das Url-Pattern festgelegt, mit der ein Client das Servlet aufrufen muß.
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>xxx</servlet-name> <servlet-class>BeanServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xxx</servlet-name> <url-pattern>/BeanContact.html</url-pattern> </servlet-mapping> </web-app>
Mit dem Urlpattern /BeanContact.html gaukeln wir dem Client vor, er würde eine html-Datei anfordern.
Diesem Namen vorangestellt wird der Name der gepackten Webapplikation als Verzeichnisname.
Erstellen des Archivs
Das Archiv erstellen wir wieder mit dem Utility jar.
jar cvf <name-des-webarchivs> .
Deployvorgang
Das fertige Archiv bringen wir nun zum Server und legen es ins Autodeployverzeichnis von Glassfish. Achten Sie aber darauf, daß die Bean bereits "deployed" sein muß.
<SUNHOME>/SDK/domains/domain1/autodeploy
Aufruf des Servlets
Mit unseren Bezeichnungen lautet der Aufruf des Servlets dann:
http://<server-adress>/<name-des-archivs>/BeanContact.html
Die Antwort im Browser
2 Kontaktaufnahme mit der Annotation javax.ejb.EJB
Mit der Verwendung der Annotation javax.ejb.EJB erübrigt sich das Anlegen eines InitialContexts.
Die Servletklasse
Wir wollen diesmal mit der Stateful Sessionbean Kontakt aufnehmen.
/* BeanServlet2 @EJB(mappedName="ejb/SayHelloStateful") diese eine annotation ersetzt String jndiName = "ejb/SayHelloStateful"; Context ctx = new InitialContext(env); // NamingException SayHello hello = (SayHello)ctx.lookup(jndiName); // NamingException daten der bean: @Stateful(name="SayHello2", mappedName="ejb/SayHelloStateful") @Remote(SayHello2.class) die servletklasse muß natürlich den typ SayHello2 kennen, d.h. das remote-interface muß bekannt sein. */ import java.io.*; import javax.ejb.EJB; import javax.servlet.*; import javax.servlet.http.*; public class BeanServlet2 extends HttpServlet { @EJB(mappedName="ejb/SayHelloStateful") private SayHello2 hello2; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>BeanServlet 2</title>"); out.println("</head>"); out.println("<body>"); out.println("<h2>This is BeanServlet 2<h2>"); out.println("<h2>Answer from the Bean: " + hello.sayHello() + "</h2>"); out.println("<h2>Bean Creation Date: " + hello2.getCreationDate() + "</h2>"); out.println("</body>"); out.println("</html>"); } }
Mit der Annotation @EJB(mappedName="ejb/SayHello") kann der dem Beancontainer angeschlossene Servletcontainer
eine Namensauflösung vornehmen und so die Bean ansprechen. Unsere Webapplikation muß allerdings noch den Typ des Remoteinterfaces
kennen. Das erreichen wir dadurch, daß wir das kompilierte Interface "SayHello2.class" in das classes-Verzeichnis legen.
Wir hätten die Kontaktaufnahme auch gleich in die service-Methode schreiben können, aber so ist es etwas strukturierter.
Die Verzeichnisstruktur der WEB-Applikation
ist immer die gleiche.
WEB-INF <dir> | |--- classes <dir> | | | |--- BeanServlet2.class <file> | | | |--- SayHello2.class <file> | |--- web.xml <file>
web.xml
Die Datei web.xml ist die Konfigurationsdatei für dieses Webapplikation. Hier wird das Url-Pattern festgelegt, mit der ein Client das Servlet aufrufen muß. Wir vergeben diesmal den Namen BeanContact2.html.
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>yyy</servlet-name> <servlet-class>BeanServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>yyy</servlet-name> <url-pattern>/BeanContact2.html</url-pattern> </servlet-mapping> </web-app>
Mit dem Urlpattern /BeanContact2.html gaukeln wir dem Client vor, er würde eine html-Datei anfordern.
Erstellen des Archivs
Das Archiv erstellen wir wieder mit dem Utility jar.
jar cvf <name-des-webarchivs> .
Deployvorgang
Das fertige Archiv bringen wir nun zum Server und legen es ins Autodeployverzeichnis von Glassfish. Achten Sie aber darauf, daß die Bean bereits "deployed" sein muß.
<SUNHOME>/SDK/domains/domain1/autodeploy
Aufruf des Servlets
Mit unseren Bezeichnungen lautet der Aufruf des Servlets dann:
http://<server-adress>/<name-des-archivs>/BeanContact2.html
Die Antwort im Browser
|