Designproblem DD2390 Internetprogrammering 6 hp En Servlet är lämplig för att hantera logik men olämplig för att hantera presentation p g a att all HTML läggs inuti Java-kod. En JSP-sida är lämplig för att hantera presentation men olämplig för att hantera logik p g a att all Java-kod hamnar i en HTML-kod. Innehåll Designmönster Lektion 9 Designmönster Model-1 Model-View-Controller (MVC) Enterprise JavaBeans (EJB 3.0) • 1. Hantera inkommande HTTP-request 2. Instansiera objekt och / eller anropa metoder i dessa / redan befintliga objekt 3. Generera HTTP-response • Model - 1 •Den metod vi främst använt hittils •I JSP-sidan blandas presentation (View) och validering av input (Control) •En eller flera JavaBönor innehåller datastrukturen (Model) •Ibland används inte ens JavaBönor och då blir koden mycket rörig. Omedvetet eller ej har ni hittils oberoende av designmönster haft ungefär följande Servlets är bra på (1), JavaBeans på (2) och JSP-sidor är lämpliga för (3) Model – 2 (MVC) Designmål: Separera •Datastruktur (Model) •Presentation (View) •Validering av input (Control) Exempel: MVC ForumController.java if(request.getParameter("email")!=null){ bean.User u = (bean.User)session.getAttribute("user"); u.setNickname(request.getParameter("nickname")); u.setEmail(request.getParameter("email")); RequestDispatcher rd = sc.getRequestDispatcher("/forum_view.jsp"); try{ rd.forward(request, response); } catch(ServletException e){ out.println(e.getMessage()); } } Model (JavaBönor) Forum.java (application scope) User.java (session scope) Post.java (request scope / page scope) View (JSP-sidor) forum_index.html forum_view.jsp Controller (Servlet) ForumController.java ForumController.java ForumController.java import java.io.*; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher;// ny import javax.servlet.ServletException; // ny import javax.servlet.http.*; import java.util.ArrayList; if(request.getParameter("text")!=null){ bean.User u = (bean.User)session.getAttribute("user"); bean.Forum f = (bean.Forum)sc.getAttribute("forum"); bean.Post p = new bean.Post(); p.setText(request.getParameter("text")); p.setNickname(u.getNickname()); f.addPost(p); RequestDispatcher rd = sc.getRequestDispatcher("/forum_view.jsp"); try{ rd.forward(request, response); } catch(ServletException e){ out.println(e.getMessage()); } } out.close(); } public class ForumController extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{ PrintWriter out = response.getWriter(); ServletContext sc = getServletContext(); if(sc.getAttribute("forum")==null){ sc.setAttribute("forum", new bean.Forum()); } } ForumController.java HttpSession session = request.getSession(); if(session.isNew()){ session.setAttribute("user", new bean.User()); RequestDispatcher rd = sc.getRequestDispatcher("/forum_index.html"); try{ rd.forward(request, response); } catch(ServletException e){ out.println(e.getMessage()); } } Forum_index.html <html> <head><title>Forum - inloggning</title></head> <body> <form action="/ForumController"> Nickname<input type="text" name="nickname"><br> Email<input type="text" name="email"><br> <input type="submit"></form> </body> </html> Forum_view.jsp <%@ page import="java.util.ArrayList" %> <html><head><title>Forum - visa</title></head><body> <% bean.Forum f = (bean.Forum)pageContext.getServletContext().getAttribute("forum"); bean.User u = (bean.User)pageContext.getSession().getAttribute("user"); bean.Post p; %> <h4><%= u.getNickname() %>(<%= u.getEmail() %>)</h4> <% ArrayList posts = f.getPosts(); for(int i = 0; i < posts.size(); i++){ p = (bean.Post)posts.get(i); %> <b> <%=p.getText() %> </b><br> <i> <%=p.getNickname()%> </i><br> <%}%> <form action="/ForumController"> Text<input type="text" name="text"><br> <input type="submit"></form> </body></html> Olika sorters böner • Entitetsbönor – CMP (Container Managed Persistence) – Autogenererad SQL. – Primärnyckel • Sessionsbönor • Stateful • Stateless web.xml <servlet> <servlet-name>ForumController</servlet-name> <servlet-class>ForumController</servlet-class> </servlet> <servlet-mapping> <servlet-name>ForumController</servlet-name> <url-pattern>/ForumController</url-pattern> </servlet-mapping> En EJB består av • EJB klassen självt • En stateless böna. • Ett Java interface – För distribuerade EJB:er • Remote – För lokala EJB:er • Local • Konfiguration (persistence.xml) EJB Installation • En EJB är en server-side komponent som erbjuder databeständighet (persistens) genom att objekt speglas i en databas. • En EJB överlever därför systemkrascher • Den är distribuerbar. • OpenEJB stödjer EJB 3.0 • JNDI används för att få en referens till en EJB. • EJB != JavaBean • Kopiera openejb.war till tomcat/webapps • http://localhost:8080/openejb/installer • Skapa katalog tomcat/webapps/ROOT/WEBINF/classes/META-INF • Log finns i tomcat/logs/openejb.log • Ändra i tomcat/bin/compile.sh • Om ni inte arbetar på samma dator som kör tomcat måste ni ändra rättigheter i tomcat/conf/Catalina/localhost/openejb.xml compile.sh #!/bin/csh set rootpath=/afs/nada.kth.se/home/teach/stene/ set tomcatpath=$rootpath/tomcat/lib set webapppath=$rootpath/tomcat/webapps/ROOT/WEBINF/classes set openejbpath=$rootpath/tomcat/webapps/openejb/lib javac -cp $tomcatpath/servlet-api.jar:$openejbpath/javaeeapi-5.0-3.jar $webapppath/*.java $webapppath/bean/*.java $webapppath/ejb/*.java persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="CarPU"> <properties> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> </properties> </persistence-unit> </persistence> Hello.java • package ejb; • import javax.ejb.Local; • @Local public interface Hello{ • public String sayHello(); • } HelloEJB.java package ejb; import javax.ejb.*; @Local(Hello.class) @Stateless public class HelloEJB implements Hello { public String sayHello(){ return "Hello World!!!!!"; } } Car.java CarEntity.java 1/2 package ejb; package ejb; import javax.ejb.Local; import java.io.Serializable; @Local public interface Car{ public void addCar(String name); import javax.persistence.*; import javax.annotation.*; @Entity @Table(name = "Car") public void update(CarEntity c); public class CarEntity implements Serializable { @Id public CarEntity findByPrimaryKey(int id); @GeneratedValue(strategy=GenerationType.AUTO) long id; public java.util.List findAll(); String name; } CarEJB.java 1/2 CarEntity.java 2/2 package ejb; public void setId(long id){ import javax.ejb.*; this.id = id; import javax.persistence.*; } @Local(Car.class) public long getId(){ @Stateless return id; public class CarEJB implements Car { } @PersistenceContext(unitName="CarPU", name="em") private EntityManager em; public void setName(String name){ this.name = name; public void addCar(String name){ } CarEntity ce = new CarEntity(); ce.setName(name); em.persist(ce); public String getName(){ return name; em.close(); } } } CarEJB.java 2/2 public void update(CarEntity c){ ejblocaltest.jsp 1/2 <%@page import="ejb.*,javax.naming.*,java.util.Properties"%> em.flush(); <% em.close(); try{ } Properties p = new Properties(); // För att få tillgång till de JNDI-bindningar i openejb där våra EJB:er finns. public CarEntity findByPrimaryKey(int id){ CarEntity ce = (CarEntity)em.find(CarEntity.class, id); p.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory"); em.close(); Context ctx = new InitialContext(p); return ce; Hello h = (Hello)ctx.lookup("HelloEJBLocal"); out.println("<p>EJB information: " + h); } out.println("<p>Result of call: " + h.sayHello()); public java.util.List findAll(){ } } Query query = em.createQuery("SELECT c from CarEntity as c"); // Interfacet c används för att skapa upp och söka reda på EJB:er em.close(); // Betrakta det som att c representerar hela tabellen. return query.getResultList(); Car c = (Car)ctx.lookup("CarEJBLocal"); out.println("<p>EJB information: " + c); c.addCar("Volvo"); ejblocaltest.jsp 2/2 // ce är en instans av CarEJBLocal CarEntity ce = (CarEntity)c.findByPrimaryKey(1); out.println("<p>Brand: " + ce.getName()); ce.setName("Saab"); c.update(ce); out.println("<p>Brand: " + ce.getName()); java.util.List li = c.findAll(); out.println("<p>Iteration"); for(int i = 0; i < li.size(); i++){ ce = (CarEntity)li.get(i); out.println("<p>Brand: " + ce.getName()); } } catch(NamingException e){ out.println(e.getMessage()); } %>