Model - 1 Föreläsning 6 Model – 2 (MVC) •Den metod vi använt hittils •I jsp-sidan blandas presentation (View) och validering av input (Control) •En eller flera JavaBean:s innehåller datastrukturen (Model), ibland används inte ens JavaBean:s och då blir koden mycket rörig. Model – 2 (MVC) Designmål: Separera •Datastruktur (Model) •Presentation (View) •Validering av input (Control) Servlet:s •Servlet:s placeras under orion\applications\kurs\web\WEB-INF\classes\ •I browsern nås dem som default under http://datornamn/servlet/ServletNamn Servletnamnet är .class-filens namn utan suffix. Detta går att konfigurera om i web.xml •En .jsp-sida översätts till en servlet första gången den laddas, sedan kompileras servlet:en och körs. <servlet> <servlet-name>Slask</servlet-name> •En servlet är en J2EE-komponent <servlet-class>LoginServlet</servlet-class> </servlet> med sin egen container som <servlet-mapping> hanterar den. <servlet-name>Slask</servlet-name> <url-pattern>/Servlet/LoginServlet</url-pattern> •Alla klienter delar på samma servlet. </servlet-mapping> Exempel 1:2 Exempel 2:2 import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class LoginServlet extends HttpServlet{ public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{ PrintWriter out; response.setContentType("text/html"); out = response.getWriter(); out.println ("<html><body>"); String username = request.getParameter(”username"); out.println ("Hello " + username); out.println("</body></html>"); out.close(); } } 1 Exempel 1:2 1:a klick för klient nr 1 Exempel 2:2 1:a klick för klient nr 2 import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class RaceServlet extends HttpServlet{ private boolean ffg=true; Alla satser i en servlet som påverkar en instansvariabel måste vara inom ett synchronized block, annars kan oförsedda saker inträffa när trådarna switchar, detta kallas ett ”race condition”. I exemplet ovan ska första bilden endast visas för den första klienten som ansluter men det är det inte säkert att den gör om man inte använder synchronized. public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{ PrintWriter out; response.setContentType("text/html"); out = response.getWriter(); out.println ("<html><body>"); synchronized(this){ if(ffg){ out.println("<p>Nu börjar provet!"); ffg = false; } } out.println("</body></html>"); out.close(); } } MVC-exempel SavingsBean.java (Model) package bean; public class SavingsBean{ private double deposit; private double time; private double interest = 3; public void setDeposit(double deposit){ this.deposit = deposit; } public void setTime(double time){ this.time = time; } public int getWithdrawal(){ return (int)Math.round(deposit*Math.pow((100+interest)/100,time)); } public double getInterest(){ return interest; } } mvc.html (View) <html> <head><title>Exempel - MVC</title></head> <body> <center> <h2>Sparandeberäkning</h2> <form method="post" action="servlet/Savings"> <p>Insättning första året: <input type=text name="deposit"> <p>Antal år att förräntas: <input type=text name="time"> <p><input type=submit value="Beräkna"> </form> </center> </body> </html> mvc.jsp (View) <%@ page import="bean.SavingsBean" %> <html> <head><title>Exempel - MVC</title></head> <body> <center> <% SavingsBean sb = (SavingsBean)session.getAttribute("sb"); %> <h2>Resultat</h2> <p>Du får ut <%= sb.getWithdrawal() %> kr. <p>Beräkningen är baserad på <%= sb.getInterest() %>% ränta. </center> </body> </html> 2 Savings.java (Controller) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import bean.SavingsBean; getServletContext() är en metod i interface:t ServletConfig som implementeras av GenericServlet. HttpServlet är subklass till denna. public class Savings extends HttpServlet { public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session = req.getSession(true); SavingsBean sb = new SavingsBean(); session.setAttribute("sb",sb); double deposit = Double.parseDouble(req.getParameter("deposit")); double time = Double.parseDouble(req.getParameter("time")); sb.setDeposit(deposit); sb.setTime(time); ServletContext sc = getServletContext(); // Är metod i interface:t ServletConfig som implementeras RequestDispatcher rd = sc.getRequestDispatcher("/mvc.jsp"); rd.forward(req, res); } } Ingenting får ha skrivits till response innan 3