Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Reference for MVC: http://www.javaworld.com/article/2076557/java-web-development/understanding-javaserverpages-model-2-architecture.html Understanding JavaServer Pages Model 2 architecture MORE LIKE THIS Server-side Java: Internationalize JSP-based Websites Server-side Java: Advanced form processing using JSP Banking on Java-based billing Exploring the MVC design pattern Despite its relatively recent introduction, JavaServer Pages (JSP) technology is well on its way to becoming the preeminent Java technology for building applications that serve dynamic Web content. Java developers love JSP for myriad reasons. Some like the fact that it brings the "write once, run anywhere" paradigm to interactive Web pages; others appreciate the fact that it is fairly simple to learn and lets them wield Java as a server-side scripting language. But most concur on one thing -- the biggest advantage of using JSP is that it helps effectively separate presentation from content. In this article, I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-ViewController (MVC) design pattern. Please note that you should be familiar with the basics of JSP and servlet programming before continuing on, as I do not address any syntax issues in this article. So, what's wrong with servlets? While JSP may be great for serving up dynamic Web content and separating content from presentation, some may still wonder why servlets should be cast aside for JSP. The utility of servlets is not in question. They are excellent for server-side processing, and, with their significant installed base, are here to stay. In fact, architecturally speaking, you can view JSP as a high-level abstraction of servlets that is implemented as an extension of the Servlet 2.1 API. Still, you shouldn't use servlets indiscriminately; they may not be appropriate for everyone. For instance, while page designers can easily write a JSP page using conventional HTML or XML tools, servlets are more suited for back-end developers because they are often written using an IDE -- a process that generally requires a higher level of programming expertise. When deploying servlets, even developers have to be careful and ensure that there is no tight coupling between presentation and content. You can usually do this by adding a third-party HTML wrapper package like to the mix. But even this approach, though providing some flexibility with simple screen changes, still does not shield you from a change in the presentation format itself. For example, if your presentation changed from HTML to DHTML, you would still need to ensure that wrapper packages were compliant with the new format. In a worst-case scenario, if a wrapper package is not available, you may end up hardcoding the presentation within the dynamic content. So, what is the solution? As you shall soon see, one approach would be to use both JSP and servlet technologies for building application systems. Differing philosophies The early JSP specifications advocated two philosophical approaches for building applications using JSP technology. These approaches, termed the JSP Model 1 and Model 2 architectures, differ essentially in the location at which the bulk of the request processing was performed. In the Model 1 architecture, shown in Figure 1, the JSP page alone is responsible for processing the incoming request and replying back to the client. There is still separation of presentation from content, because all data access is performed using beans. Although the Model 1 architecture should be perfectly suitable for simple applications, it may not be desirable for complex implementations. Indiscriminate usage of this architecture usually leads to a significant amount of scriptlets or Java code embedded within the JSP page, especially if there is a significant amount of request processing to be performed. While this may not seem to be much of a problem for Java developers, it is certainly an issue if your JSP pages are created and maintained by designers -- which is usually the norm on large projects. Ultimately, it may even lead to an unclear definition of roles and allocation of responsibilities, causing easily avoidable project-management headaches. Figure 1: JSP Model 1 architect The Model 2 architecture, shown in Figure 2, is a hybrid approach for serving dynamic content, since it combines the use of both servlets and JSP. It takes advantage of the predominant strengths of both technologies, using JSP to generate the presentation layer and servlets to perform process-intensive tasks. Here, the servlet acts as the controller and is in charge of the request processing and the creation of any beans or objects used by the JSP, as well as deciding, depending on the user's actions, which JSP page to forward the request to. Note particularly that there is no processing logic within the JSP page itself; it is simply responsible for retrieving any objects or beans that may have been previously created by the servlet, and extracting the dynamic content from that servlet for insertion within static templates. In my opinion, this approach typically results in the cleanest separation of presentation from content, leading to clear delineation of the roles and responsibilities of the developers and page designers on your programming team. In fact, the more complex your application, the greater the benefits of using the Model 2 architecture should be. Figure 2: JSP Model 2 architecture In order to clarify the concepts behind the Model 2 architecture, let's walk through a detailed implementation of it: a sample online music store called Music Without Borders. Understanding Music Without Borders The main or presentation, for our Music Without Borders online store is facilitated by the JSP page EShop.jsp view, (shown in Listing 1). You will notice that the page deals almost exclusively with presenting the main user interface of the application to the client, and performs no processing whatsoever -- an optimal JSP scenario. Also, notice that another JSP page, Cart.jsp (shown in Listing 2), is included within EShop.jsp via the directive <jsp:include page="Cart.jsp" flush="true" /> via the directive <jsp:include page="Cart.jsp" flush="true" /> . Listing 1: EShop.jsp <%@ page session="true" %> <html> <head> <title>Music Without Borders</title> </head> <body bgcolor="#33CCFF"> <font face="Times New Roman,Times" size="+3"> Music Without Borders </font> <hr><p> <center> <form name="shoppingForm" action="/examples/servlet/ShoppingServlet" method="POST"> <b>CD:</b> <select name=CD> <option>Yuan | The Guo Brothers | China | 4.95</option> <option>Drums of Passion | Babatunde Olatunji | Nigeria | 6.95</option> <option>Kaira | Tounami Diabate| Mali | 6.95</option> <option>The Lion is Loose | Eliades Ochoa | Cuba | 3.95</option> <option>Dance the Devil Away | Outback | Australia | 4.95</option> <option>Record of Changes | Samulnori | Korea | 2.95</option> <option>Djelika | Tounami Diabate | Mali | 4.95</option> <option>Rapture | Nusrat Fateh Ali Khan | Pakistan | 2.95</option> <option>Cesaria Evora | Cesaria Evora | Cape Verde | 6.95</option> <option>Ibuki | Kodo | Japan | 3.95</option> </select> <b>Quantity: </b><input type="text" name="qty" SIZE="3" value=1> <input type="hidden" name="action" value="ADD"> <input type="submit" name="Submit" value="Add to Cart"> </form> </center> <p> <jsp:include page="Cart.jsp" flush="true" /> </body> </html> Listing 2: Cart.jsp <%@ page session="true" import="java.util.*, shopping.CD" %> <% Vector buylist = (Vector) session.getValue("shopping.shoppingcart"); if (buylist != null && (buylist.size() > 0)) { %> <center> <table border="0" cellpadding="0" width="100%" bgcolor="#FFFFFF"> <tr> <td><b>ALBUM</b></td> <td><b>ARTIST</b></td> <td><b>COUNTRY</b></td> <td><b>PRICE</b></td> <td><b>QUANTITY</b></td> <td></td> </tr> <% for (int index=0; index < buylist.size();index++) { CD anOrder = (CD) buylist.elementAt(index); %> <tr> <td><b><%= anOrder.getAlbum() %></b></td> <td><b><%= anOrder.getArtist() %></b></td> <td><b><%= anOrder.getCountry() %></b></td> <td><b><%= anOrder.getPrice() %></b></td> <td><b><%= anOrder.getQuantity() %></b></td> <td> <form name="deleteForm" action="/examples/servlet/ShoppingServlet" method="POST"> <input type="submit" value="Delete"> <input type="hidden" name= "delindex" value='<%= index %>'> <input type="hidden" name="action" value="DELETE"> </form> </td> </tr> <% } %> </table> <p> <form name="checkoutForm" action="/examples/servlet/ShoppingServlet" method="POST"> <input type="hidden" name="action" value="CHECKOUT"> <input type="submit" name="Checkout" value="Checkout"> </form> </center> <% } %> Here, Cart.jsp handles the presentation of the session-based shopping cart, which constitutes the model in our MVC architecture. Observe the scriptlet at the beginning ofCart.jsp: <% Vector buylist = (Vector) session.getValue("shopping.shoppingcart"); if (buylist != null && (buylist.size() > 0)) { %> Basically, the scriptlet extracts the shopping cart from the session. If the cart is empty or not yet created, it displays nothing; thus, the first time a user accesses the application, she is presented with the view shown in Figure 3. Figure 3: Music Without Borders, main view If the shopping cart is not empty, then the selected items are extracted from the cart one at a time, as demonstrated by the following scriptlet: <% for (int index=0; index < buylist.size(); index++) { CD anOrder = (CD) buylist.elementAt(index); %> Once the variables describing an item have been created, they are then simply inserted into the static HTML template using JSP expressions. Figure 4 shows the application view after the user has placed some items in the shopping cart. Figure 4: Music Without Borders, shopping cart view The important thing to observe here is that the processing for all actions carried out within eitherEshop.jsp or Cart.jsp is handled by the controllerservlet, ShoppingServlet.java, which is shown in . Page 2 of 2 Listing 3: ShoppingServlet.java import java.util.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import shopping.CD; public class ShoppingServlet extends HttpServlet { public void init(ServletConfig conf) throws ServletException { super.init(conf); } public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session = req.getSession(false); if (session == null) { res.sendRedirect("http://localhost:8080/error.html"); } Vector buylist= (Vector)session.getValue("shopping.shoppingcart"); String action = req.getParameter("action"); if (!action.equals("CHECKOUT")) { if (action.equals("DELETE")) { String del = req.getParameter("delindex"); int d = (new Integer(del)).intValue(); buylist.removeElementAt(d); } else if (action.equals("ADD")) { //any previous buys of same cd? boolean match=false; CD aCD = getCD(req); if (buylist==null) { //add first cd to the cart buylist = new Vector(); //first order buylist.addElement(aCD); } else { // not first buy for (int i=0; i< buylist.size(); i++) { CD cd = (CD) buylist.elementAt(i); if (cd.getAlbum().equals(aCD.getAlbum())) { cd.setQuantity(cd.getQuantity()+aCD.getQuantity()); buylist.setElementAt(cd,i); match = true; } //end of if name matches } // end of for if (!match) buylist.addElement(aCD); } } session.putValue("shopping.shoppingcart", buylist); String url="/jsp/shopping/EShop.jsp"; ServletContext sc = getServletContext(); RequestDispatcher rd = sc.getRequestDispatcher(url); rd.forward(req, res); } else if (action.equals("CHECKOUT")) { float total =0; for (int i=0; i< buylist.size();i++) { CD anOrder = (CD) buylist.elementAt(i); float price= anOrder.getPrice(); int qty = anOrder.getQuantity(); total += (price * qty); } total += 0.005; String amount = new Float(total).toString(); int n = amount.indexOf('.'); amount = amount.substring(0,n+3); req.setAttribute("amount",amount); String url="/jsp/shopping/Checkout.jsp"; ServletContext sc = getServletContext(); RequestDispatcher rd = sc.getRequestDispatcher(url); rd.forward(req,res); } } private CD getCD(HttpServletRequest req) { //imagine if all this was in a scriptlet...ugly, eh? String myCd = req.getParameter("CD"); String qty = req.getParameter("qty"); StringTokenizer t = new StringTokenizer(myCd,"|"); String album= t.nextToken(); String artist = t.nextToken(); String country = t.nextToken(); String price = t.nextToken(); price = price.replace('$',' ').trim(); CD cd = new CD(); cd.setAlbum(album); cd.setArtist(artist); cd.setCountry(country); cd.setPrice((new Float(price)).floatValue()); cd.setQuantity((new Integer(qty)).intValue()); return cd; } } very time the user adds an item within EShop.jsp, the request is posted to the controller servlet. The servlet in turn determines the appropriate action, and then processes the request parameters for the item to be added. It then instantiates a new CD bean (shown in Listing 4) representing the selection, and goes about updating the shopping cart object before placing it back within the session. Listing 4: CD.java package shopping; public class CD { String album; String artist; String country; float price; int quantity; public CD() { album=""; artist=""; country=""; price=0; quantity=0; } public void setAlbum(String title) { album=title; } public String getAlbum() { return album; } public void setArtist(String group) { artist=group; } public String getArtist() { return artist; } public void setCountry(String cty) { country=cty; } public String getCountry() { return country; } public void setPrice(float p) { price=p; } public float getPrice() { return price; } public void setQuantity(int q) { quantity=q; } public int getQuantity() { return quantity; } } Notice that we have also included additional intelligence within the servlet, so that it understands that, if a previously added CD is reselected, it should simply increase the count for that CD bean within the shopping cart. The controller servlet also processes actions triggered from within Cart.jsp, such as the user deleting items from the shopping cart, or proceeding to the checkout counter. Observe that the controller always has complete control over which resources should be invoked in response to specific actions. For example, changes made to the state of the shopping cart, such as additions or deletions, cause the controller servlet to forward the request after processing to the Eshop.jsp page. This in turn causes the page to redisplay the main view, along with the updated contents of the shopping cart. If the user decides to check out, the request is forwarded after processing to theCheckout.jsp page (shown in Listing 5) by means of the following request dispatcher, as shown below: String url="/jsp/shopping/Checkout.jsp"; ServletContext sc = getServletContext(); RequestDispatcher rd = sc.getRequestDispatcher(url); rd.forward(req,res); Listing 5: Checkout.jsp <%@ page session="true" import="java.util.*, shopping.CD" %> <html> <head> <title>Music Without Borders Checkout</title> </head> <body bgcolor="#33CCFF"> <font face="Times New Roman,Times" size=+3> Music Without Borders Checkout </font> <hr><p> <center> <table border="0" cellpadding="0" width="100%" bgcolor="#FFFFFF"> <tr> <td><b>ALBUM</b></td> <td><b>ARTIST</b></td> <td><b>COUNTRY</b></td> <td><b>PRICE</b></td> <td><b>QUANTITY</b></td> <td></td> </tr> <% Vector buylist = (Vector) session.getValue("shopping.shoppingcart"); String amount = (String) request.getAttribute("amount"); for (int i=0; i < buylist.size();i++) { CD anOrder = (CD) buylist.elementAt(i); %> <tr> <td><b><%= anOrder.getAlbum() %></b></td> <td><b><%= anOrder.getArtist() %></b></td> <td><b><%= anOrder.getCountry() %></b></td> <td><b><%= anOrder.getPrice() %></b></td> <td><b><%= anOrder.getQuantity() %></b></td> </tr> <% } session.invalidate(); %> <tr> <td> </td> <td> </td> <td><b>TOTAL</b></td> <td><b>$<%= amount %></b></td> <td> </td> </tr> </table> <p> <a href="/examples/jsp/shopping/EShop.jsp">Shop some more!</a> </center> </body> </html> Checkout.jsp simply extracts the shopping cart from the session and the total amount for the request, and then displays the selected items and their total cost. Figure 5 shows the client view upon checkout. Once the user goes to the checkout counter, it is equally important to get rid of the session object. That is taken care of by having asession.invalidate() invocation at the end of the page. This process is necessary for two reasons. First, if the session is not invalidated, the user's shopping cart is not reinitialized; if the user then attempts to commence another round of shopping upon checkout, her shopping cart will continue to hold items that she has already purchased. The second reason is that if the user simply left the site upon checkout, the session object will not be garbage collected and will continue to take up valuable system resources until its lease period expires. Since the default session-lease period is about 30 minutes, this can quickly lead to the system running out of memory in a highvolume system. Of course, we all know what happens to an application that runs out of system resources! Figure 5: Music Without Borders, checkout view Notice that all the resources for this application are session aware, since the model here is stored within the session. Consequently, you must ensure that the user does not somehow access the controller directly, even by mistake. You can take care of this by implementing the automatic client redirection to the error page (shown in Listing 6) when the controller detects the absence of a valid session. Listing 6: error.html <html> <body> <h1> Sorry, there was an unrecoverable error! <br> Please try <a href="/examples/jsp/shopping/EShop.jsp">again</a>. </h1> </body> </html> SIMILAR ARTICLES 17 JavaScript tools breathing new life into old code HTTP/2: A jump-start for Java developers 7 reasons why frameworks are the new programming languages Deploying Music Without Borders I will assume that you are using the latest version of JavaServer Web Development Kit (JSWDK) from Sun for running the example. If not, see the Resources section to find out where to get it. Assuming that the server is installed in \jswdk-1.0.1 , its default location in Microsoft Windows, deploy the Music Without Borders application files as follows: Leveraging JSP and servlets Create shopping directory under \jswdk-1.0.1\examples\jsp Copy EShop.jsp to \jswdk-1.0.1\examples\jsp\shopping Copy Cart.jsp to \jswdk-1.0.1\examples\jsp\shopping Copy Checkout.jsp to \jswdk-1.0.1\examples\jsp\shopping Compile the .java files by typing javac *.java Copy ShoppingServlet.class to \jswdk-1.0.1\webpages\WebInf\servlets Create shopping directory under \jswdk-1.0.1\examples\WebInf\jsp\beans Copy CD.class to \jswdk-1.0.1\examples\WebInf\jsp\beans\shopping Copy error.html to \jswdk-1.0.1\webpages Once your server has been started, you should be able to access the application using http://localhost:8080/examples/jsp/shopping/EShop.jsp a s the URL In this example, we have examined in detail the level of control and flexibility provided by the Model 2 architecture. In particular, we've seen how the best features of servlets and JSP pages can be exploited to maximize the separation of presentation from content. Properly applied, the Model 2 architecture should result in the concentration of all of the processing logic in the hands of the controller servlet, with the JSP pages responsible only for the view or presentation. However, the downside of using the Model 2 approach is its complexity. Consequently, it may be desirable to use the Model 1 approach for simpler applications. Get the source code for the example http://www.javaworld.com/jw-12-1999/ssj/ShoppingCart.jar http://www.javatpoint.com/MVC-in-jsp MVC in JSP 1. MVC in JSP 2. Example of following MVC in JSP MVC stands for Model View and Controller. It is a design pattern that separates the business logic, presentation logic and data. Controller acts as an interface between View and Model. Controller intercepts all the incoming requests. Model represents the state of the application i.e. data. It can also have business logic. View represents the presentaion i.e. UI(User Interface). Advantage of MVC (Model 2) Architecture 1. Navigation Control is centralized 2. Easy to maintain the large application If you new to MVC, please visit Model1 vs Model2 first. Example of following MVC in JSP In this example, we are using servlet as a controller, jsp as a view component, Java Bean class as a model. In this example, we have created 5 pages: index.jsp a page that gets input from the user. ControllerServlet.java a servlet that acts as a controller. login-success.jsp and login-error.jsp files acts as view components. web.xml file for mapping the servlet. 1. 2. 3. 4. 5. File: index.jsp <form action="ControllerServlet" method="post"> Name:<input type="text" name="name"><br> Password:<input type="password" name="password"><br> <input type="submit" value="login"> </form> File: ControllerServlet 1. 2. 3. 4. 5. 6. 7. 8. package com.javatpoint; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 9. public class ControllerServlet extends HttpServlet { 10. protected void doPost(HttpServletRequest request, HttpServletResponse response) 11. throws ServletException, IOException { 12. response.setContentType("text/html"); 13. PrintWriter out=response.getWriter(); 14. 15. String name=request.getParameter("name"); 16. String password=request.getParameter("password"); 17. 18. LoginBean bean=new LoginBean(); 19. bean.setName(name); 20. bean.setPassword(password); 21. request.setAttribute("bean",bean); 22. 23. boolean status=bean.validate(); 24. 25. if(status){ 26. RequestDispatcher rd=request.getRequestDispatcher("login-success.jsp"); 27. rd.forward(request, response); 28. } 29. else{ 30. RequestDispatcher rd=request.getRequestDispatcher("login-error.jsp"); 31. rd.forward(request, response); 32. } 33. 34. } 35. 36. @Override 37. protected void doGet(HttpServletRequest req, HttpServletResponse resp) 38. throws ServletException, IOException { 39. doPost(req, resp); 40. } 41. } File: LoginBean.java 1. package com.javatpoint; 2. public class LoginBean { 3. private String name,password; 4. 5. public String getName() { 6. return name; 7. } 8. public void setName(String name) { 9. this.name = name; 10. } 11. public String getPassword() { 12. return password; 13. } 14. public void setPassword(String password) { 15. this.password = password; 16. } 17. public boolean validate(){ 18. if(password.equals("admin")){ 19. return true; 20. } 21. else{ 22. return false; 23. } 24. } 25. } File: login-success.jsp 1. 2. 3. 4. 5. 6. 7. <%@page import="com.javatpoint.LoginBean"%> <p>You are successfully logged in!</p> <% LoginBean bean=(LoginBean)request.getAttribute("bean"); out.print("Welcome, "+bean.getName()); %> File: login-error.jsp 1. <p>Sorry! username or password error</p> 2. <%@ include file="index.jsp" %> File: web.xml 1. <?xml version="1.0" encoding="UTF-8"?> 2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3. xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/w eb-app_2_5.xsd" 4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/we b-app_3_0.xsd" 5. id="WebApp_ID" version="3.0"> 6. 7. <servlet> 8. <servlet-name>s1</servlet-name> 9. <servlet-class>com.javatpoint.ControllerServlet</servlet-class> 10. </servlet> 11. <servlet-mapping> 12. <servlet-name>s1</servlet-name> 13. <url-pattern>/ControllerServlet</url-pattern> 14. </servlet-mapping> 15. </web-app> download this example (developed using eclipse IDE) http://jansipke.nl/model-view-controller-mvc-with-jsp-and-jstl/ Model View Controller (MVC) with JSP and JSTL POSTED ON JULY 20, 2010 In this article we will create a small web application that uses the Model View Controller (MVC) pattern with Java Server Pages (JSP) and JSP Standard Template Library (JSTL). A container like Tomcat is needed to run this combination. Thanks go out to the author of the JSP – MVC Tutorial, who thought of the sample application that we will use here, the coffee advisor. The user is first presented with a choice in coffee taste she prefers. Pressing a button moves on to a page with advise about the type of coffee to drink based on that taste. An MVC application has three parts: Model. The model is the domain-specific representation of the data upon which the application operates. In our case this is implemented in the CoffeeExpert class. View. The view renders the model into a form suitable for interaction, typically a user interface element. In our case this is implemented in a JSP file called coffee.jsp. Controller. The controller receives input and initiates a response by making calls on model objects. In our case this is implemented in the CoffeeSelect class. In addition to these three file we need a web.xml file that tells the container how to map a URL (e.g. /CoffeeSelect.do) into a class to run (e.g. com.example.web.CoffeeSelect). We also need a start page for the user input, which we will call coffee.html. In total this means we should create a .war file with the following structure: coffee.html <html> <body> <h2>Coffee Advisor Input</h2> <form method="POST" action="CoffeeSelect.do"> <select name="taste" size=1"> <option value="milky">Milky</option> <option value="froffy">Froffy</option> <option value="icey">Icey</option> <option value="strong">Spaced Out</option> </select> <br/><br/> <input type="Submit"/> </form> </body> </html> CoffeeExpert.java package com.example.model; import java.util.*; public class CoffeeExpert { public List<String> getTypes(String taste) { List<String> result = new ArrayList<String>(); if (taste.equals("milky")) { result.add("Latte"); result.add("Cappuccino"); } else if (taste.equals("froffy")) { result.add("Latte"); result.add("Cappuccino"); result.add("Frappuccino"); } else if (taste.equals("icey")) { result.add("Frappuccino"); } else if (taste.equals("strong")) { result.add("Espresso"); result.add("Double espresso"); } else { result.add("Vending machine"); } return (result); } } CoffeeSelect.java package com.example.web; import java.io.IOException; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.example.model.CoffeeExpert; public class CoffeeSelect extends HttpServlet { private static final long serialVersionUID = 1L; public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { List<String> types = new CoffeeExpert().getTypes(request.getParameter("taste")); request.setAttribute("types", types); RequestDispatcher view = request.getRequestDispatcher("coffee.jsp"); view.forward(request, response); } } coffee.jsp <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <body> <h2>Coffee Advisor Output</h2> <c:forEach var="type" items="${types}"> <c:out value="${type}"/> <br /> </c:forEach> </body> </html> web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/webapp_2_4.xsd" version="2.4"> <servlet> <servlet-name>Coffee</servlet-name> <servlet-class>com.example.web.CoffeeSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Coffee</servlet-name> <url-pattern>/CoffeeSelect.do</url-pattern> </servlet-mapping> </web-app> THIS ENTRY WAS POSTED IN PROGRAMMING AND TAGGED JAVA, JSP, JSTL, MVC. BOOKMARK THEPERMALINK. http://www.thejavageek.com/2013/08/11/mvc-architecture-with-servlets-and-jsp/ MVC architecture with servlets and jsp by Prasad Kharkar • August 11, 2013 In this tutorial we are going to learn how to create a simple MVC application using servlets and jsp. MVC i.e. Model-View-Controller is a pattern helpful separation of concerns. Model represents a POJO object that carries data. View is the layer in which the data is presented in visual format. Controller is the component which is responsible for communication between model and view. A user always sees the view and communicates with the controller. We will understand this using a sample login application which will display a welcome username message and if the login fails, it will redirect to an error page. Here is what we are going to create. login.jsp :- this will input username and password success.jsp :- If login is successful, then this page is displayed error.jsp :- If login is not successful then this page is displayed. LoginController.java :- This is controller part of the application which communicates with model Authenticator.java :- Has business logic for authentication User.java :- Stores username and password for the user. Requirements: Eclipse IDE Apache tomcat server JSTL jar Create a new Dynamic web project in eclipse by clicking File -> New -> Dynamic Web Project. Fill the details i.e. project name, the server. Enter your project name as “MVCDemo”. You will get the following directory structure for the project. Initial Project Structure Create success.jsp, error.jsp and login.jsp and LoginController servlet, Authenticator class, User class in the packages as shown in the images. Put the jstl.jar in WEB-INF/lib folder. File Structure Package Structure Now that we have file structure, put this code in corresponding files. Now that we have file structure, put this code in corresponding files. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mvcdemo.controllers; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mvcdemo.model.Authenticator; import mvcdemo.model.User; import sun.text.normalizer.ICUBinary.Authenticate; public class LoginController extends HttpServlet { 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 } private static final long serialVersionUID = 1L; public LoginController() { super(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); RequestDispatcher rd = null; Authenticator authenticator = new Authenticator(); String result = authenticator.authenticate(username, password); if (result.equals("success")) { rd = request.getRequestDispatcher("/success.jsp"); User user = new User(username, password); request.setAttribute("user", user); } else { rd = request.getRequestDispatcher("/error.jsp"); } rd.forward(request, response); } Authenticator.java 1 package mvcdemo.model; 2 3 public class Authenticator { 4 5 public String authenticate(String username, String password) { 6 if (("prasad".equalsIgnoreCase(username)) 7 && ("password".equals(password))) { 8 return "success"; 9 } else { 10 return "failure"; 11 } 12 } 13 } User.java 1 package mvcdemo.model; 2 3 public class User { 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 } private String username; private String password; public User(String username, String password){ this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } error.jsp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> Login failed, please try again. </body> </html> login.jsp 1 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" 2 pageEncoding="ISO-8859-1"%> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <form action="LoginController" method="post"> Enter username : <input type="text" name="username"> <BR> Enter password : <input type="password" name="password"> <BR> <input type="submit" /> </form> </body> </html> success.jsp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <title>Insert title here</title> </head> <body> Welcome ${requestScope['user'].username}. </body> </html> and the web.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>MVCDemo</display-name> <servlet> <description></description> <display-name>LoginController</display-name> <servlet-name>LoginController</servlet-name> <servlet-class>mvcdemo.controllers.LoginController</servlet-class> </servlet> <servlet-mapping> 14 <servlet-name>LoginController</servlet-name> <url-pattern>/LoginController</url-pattern> </servlet-mapping> </web-app> We are done with the code. Let us try and run it. Start your tomcat server and hit url http://localhost:8080/MVCDemo/login.jsp. You should be able to view this page. Enter username as “prasad” and password as “password”. You will see the message “Welcome prasad”. Let us understand what happens under the hood with the help of diagram. 1. First, user visits login.jsp page and fills out data and submits form. 2. This causes LoginController to be invoked because of formaction="LoginController" . 3. In LoginController , following code causes the model to be invoked and set the User properties. 1 Authenticator authenticator = new Authenticator(); 2 String result = authenticator.authenticate(username, password); and User user = new User(username, password); . 4. rd.forward(request, response); causes the servlet to forward to jsp page. success.jsp page displays the username with expression language Welcome${requestScope['user'].username}. Notable advantages of mvc pattern are: This separate presentation layer from business layer. The controller performs action of invoking the model and sending data to view. Model is not even aware that it is used by some web application or desktop application. Authenticator class can be used by desktop applications also. Thus separation helps in re-usability. Hope this helps in understanding how to create MVC application using servlets and jsp. http://www.datadisk.co.uk/html_docs/jsp/jsp_mvc_tutorial.htm MVC Tutorial This is a simple Model View Controller (MVC) tutorial, although this is a very small application it uses the MVC model approach which proves that even small applications can use MVC. The following is what we will be doing in this tutorial, Writing an HTML form page Creating a Servlet controller - Controller Creating the Model (a plain old Java class) - Model Creating an XML deployment descriptor Creating an JSP View - View You will need the following requirements already setup, you can use either Unix/Linux or Windows the choice is yours Java SDK 1.5 or greater (I have a tutorial on Java) Tomcat 6 (I have a tutorial on Tomcat) Apache Web server (I have some information on Apache in my Tomcat web pages) The web application is a Coffee advisor, the user will input the type of Coffee and get back some advise, below is the users input screen The User will receive the below advise page Even though this is a small application we'll build it using a simple MVC architecture 1. 2. 3. The client makes a request for the form.html page The Container retrieves the form.html page The Container returns the page to the browser, where the user answers the questions on the form 4. The browser sends the request data to the Container 5. The Container finds the correct servlet based on the URL, and passes the request to the servlet 6. The servlet calls the CoffeeExpert for help 7. The expert class returns an answer, which the servlet adds to the request object 8. The servlet forwards the request to the JSP 9. The JSP gets the answer from the request object 10. The JSP generates a page for the Container 11. The Container returns the page to the user Below is an example for creating your development environment but this is entirely up to you Below is the deployment environment, here I am using Tomcat deploying a web application involves both Container-specific rules and requirements of the servlet and JSP specification, everything below the coffeeV1 directory is the same regardless of your Container The HTML form page This is a simple HTML form page, basically containing a heading and a drop down list, I have already touched on HTML HTML Form Page <html> <title>Coffee Advisor></title> <body> <h1 align="center">Coffee Advisor </h1> <form method="POST" action="SelectCoffee.do"> Select coffee Type: <select name="type" size=1"> <option value="milky">Milky</option> <option value="froffy">Froffy</option> <option value="icey">Icey</option> <option value="strong">Spaced Out</option> </select> <br><br> <center> <input type="Submit"> </center> </form> </body> <html> Note: the SelectCoffee.do is a logical name as we will not have access to the cl The Deployment Descriptor Now we nee to create the deployment descriptor which is called web.xml, see above diagram on where to place this file <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" Version="2.4"> Deployment Descriptor <servlet> <servlet-name>Coffee</servlet-name> <servlet-class>com.example.web.CoffeeSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Coffee</servlet-name> <url-pattern>/SelectCoffee.do</url-pattern> </servlet-mapping> </web-app> Note: I have more information on URL servlet mapping in my Tomcat tutorial The Controller Servlet and Model Class What we will be doing here is to create the Model class that will be used by the controller servlet, we have separated out the model class because the model class could be updated to point to a database or another coffee expert source, thus the servlet will not have to be changed, the idea in any OO programming is to think about development at a later date, you don't what a whole load of changes to your application because you want to change one aspect of it, providing your interfaces to classes don't change then development is much easier. package com.example.model; import java.util.*; public class CoffeeExpert { public List getTypes(String type) { List types = new ArrayList(); Model Class if (type.equals("milky")) { types.add("latte"); types.add("cappuccino"); } else if (type.equals("froffy")) { types.add("latte"); types.add("cappuccino"); types.add("frappuccino"); } else if (type.equals("icey")) { types.add("frappuccino"); } else if (type.equals("strong")) { types.add("espresso"); types.add("double espresso"); } else { types.add("Vending Machine"); } return(types); } } # To compile the above class file javac -d classes src/com/example/model/CoffeeExpert.java Note: At a later date this Model could become complex by using a database, which package com.example.web; import import import import import com.example.model.*; javax.servlet.*; javax.servlet.http.*; java.io.*; java.util.*; public class CoffeeSelect extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String c = request.getParameter("type"); // Now use our Coffee Model above CoffeeExpert ce = new CoffeeExpert(); List result = ce.getTypes(c); // Use the below code to debug the program if you get problems //response.setContentType("text/html"): //PrintWriter out = response.getWriter(); //out.println("Coffee Selection Advise<br>"); Servlet Controller //Iterator it = result.iterator(); //while(it.hasNext()) { // out.print("<br>try: " + it.next()); //} // The results will be passed back (as an attribute) to the JSP view // The attribute will be a name/value pair, the value in this case will be a request.setAttribute("styles", result); RequestDispatcher view = request.getRequestDispatcher("result.jsp"); view.forward(request, response); } } ## To compile the servlet ## UNIX javac -classpath <tomcat directory>/lib/servlet-api.jar:classes:. -d classes src # Windows (notice the semi-colons instead of colons) javac -classpath c:/tomcat6/lib/servlet-api.jar;classes;. -d classes src/com/exa The JSP View The last thing to do is to create the JSP view that will display the results of the coffee advisor # Create the result.jsp file below <%@ page import="java.util.*" %> <html> <body> <h1 align="center">Coffee Recommandation JSP View</h1> <p> JSP View <% List styles = (List) request.getAttribute("styles"); Iterator it = styles.iterator(); while(it.hasNext()) { out.print("<br>try: " + it.next()); } %> </body> </html>