1、采用MVC,不仅要求业务逻辑和表示分离。实际上,业务逻辑甚至根本不知道表示的存在。MVC的关键是,业务逻辑要与表示分离,而要求在中间放上别的东西,这样业务逻辑本身就可以作为一个可以重用的Java类存在,它根本不用对视图有所了解。
2、MVC迷你教程,创建和部署MVC Web应用。
第一步:分析用户视图,以及高层体系结构(方便以后“从容地”扩展这个应用)
使用标准的包结构,这样才能得到包的所有好处:项目管理,命名空间管理,可移植和可重用。
Ⅱ、构建控制器servlet的第一个版本,并用前面的HTML表单测试这个控制器
Ⅲ、为专家/模型类构建一个测试类,然后构建并测试专家/模型类本身
Ⅳ、把servlet升级到第二个版本,该版本增加一个功能,可以调用模型类来得到啤酒建议
Ⅴ、构建JSP,把servlet升级到第三个版本(把表示分派到JSP),然后再测试整个应用
创建form.html
<!DOCTYPE html> <html> <head> <meta charset="{CHARSET}"> <title>form.html</title> </head> <body> <!--在html看来,SelectBeer.do就是要调用的servlet--> <h1 align="center">Beer Selection Page</h1> <form method="post" action="SelectBeer.do"> <p>select beer characteristics</p> Color: <select name="color" size="1"> <option>light</option> <option>amber</option> <option>brown</option> <option>dark</option> </select> <br /> <center> <input type="submit" /> </center> </form> </body> </html>
部署并测试
在开发环境的etc文件下创建部署描述文件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/web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name>Ch3 Beer</servlet-name> <servlet-class>com.example.web.BeerSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Ch3 Beer</servlet-name> <url-pattern>/SelectBeer.do</url-pattern> </servlet-mapping> </web-app>
部署并测试
流程详解:把逻辑名映射到servlet文件
Ⅱ、构建控制器servlet的第一个版本,并用前面的HTML表单测试这个控制器
idea快速重写父类方法的快捷是ctrl+0.
package com.example.web; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class BeerSelect extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 之所以是doPost,是因为在html中的表单指出method=post resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("Beer Selection Advice<br>"); String c = req.getParameter("color"); out.println("<br>Got beer color" + c); } }
把.class文件部署到相应的tomcat目录下,重启tomcat(必要的!),完成测试。如果在这个时候如果对.class文件有修改,只有重启tomcat才能生效,对于html的修改则不是必须的。
Ⅲ、为专家/模型类构建一个测试类,然后构建并测试专家/模型类本身
package com.example.model; import java.util.*; public class BeerExpert { public List getBrands(String color) { List brands = new ArrayList(); if (color.equals("amber")) { brands.add("Jack Amber"); brands.add("Red Moose"); } else { brands.add("Jail Pale Ale"); brands.add("Gout Stout"); } return brands; } }
Ⅳ、把servlet升级到第二个版本,该版本增加一个功能,可以调用模型类来得到啤酒建议
package com.example.web; import com.example.model.BeerExpert; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public class BeerSelect extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 之所以是doPost,是因为在html中的表单指出method=post resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("Beer Selection Advice<br>"); String c = req.getParameter("color"); // out.println("<br>Got beer color " + c); BeerExpert be = new BeerExpert(); List result = be.getBrands(c); Iterator it = result.iterator(); while (it.hasNext()) { out.print("<br>try: " + it.next()); } } }
Ⅴ、构建JSP,把servlet升级到第三个版本(把表示分派到JSP),然后再测试整个应用
result.jsp
<%@ page import="java.util.*" %> <html> <body> <h1 align="center">Beer Recommendations JSP</h1> <p> <% List styles = (List)request.getAttribute("styles"); Iterator it = styles.iterator(); while (it.hasNext()) { out.print("<br>try: " + it.next()); } %> </body> </html>
package com.example.web; import com.example.model.BeerExpert; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public class BeerSelect extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 之所以是doPost,是因为在html中的表单指出method=post // resp.setContentType("text/html"); // PrintWriter out = resp.getWriter(); // out.println("Beer Selection Advice<br>"); String c = req.getParameter("color"); // out.println("<br>Got beer color " + c); BeerExpert be = new BeerExpert(); List result = be.getBrands(c); // Iterator it = result.iterator(); // while (it.hasNext()) { // out.print("<br>try: " + it.next()); // } req.setAttribute("styles", result); // 为请求增加一个属性,供JSP使用。 RequestDispatcher view = req.getRequestDispatcher("result.jsp"); // 为JSP实例化一个请求分派器 view.forward(req, resp); // 使用请求分派器要求容器准备好JSP,并向JSP发送请求和响应 } }