【Head First Servlets and JSP】笔记2:MVC迷你教程

1、采用MVC,不仅要求业务逻辑和表示分离。实际上,业务逻辑甚至根本不知道表示的存在。MVC的关键是,业务逻辑要与表示分离,而要求在中间放上别的东西,这样业务逻辑本身就可以作为一个可以重用的Java类存在,它根本不用对视图有所了解。

2、MVC迷你教程,创建和部署MVC Web应用。

第一步:分析用户视图,以及高层体系结构

第二步:创建用于开发这个项目的开发环境

第三步:创建用于部署这个项目的部署环境

第四步:对Web应用的各个组件完成迭代的开发和测试

第一步:分析用户视图,以及高层体系结构(方便以后“从容地”扩展这个应用)

第二步:创建用于开发这个项目的开发环境

使用标准的包结构,这样才能得到包的所有好处:项目管理,命名空间管理,可移植和可重用。

【Head First Servlets and JSP】笔记2:MVC迷你教程

【Head First Servlets and JSP】笔记2:MVC迷你教程

【Head First Servlets and JSP】笔记2:MVC迷你教程

第三步:创建用于部署这个项目的部署环境

【Head First Servlets and JSP】笔记2:MVC迷你教程

第四步:对Web应用的各个组件完成迭代的开发和测试

Ⅰ、构建和测试用户最初请求的HTML表单

Ⅱ、构建控制器servlet的第一个版本,并用前面的HTML表单测试这个控制器

Ⅲ、为专家/模型类构建一个测试类,然后构建并测试专家/模型类本身

Ⅳ、把servlet升级到第二个版本,该版本增加一个功能,可以调用模型类来得到啤酒建议

Ⅴ、构建JSP,把servlet升级到第三个版本(把表示分派到JSP),然后再测试整个应用

Ⅰ、构建和测试用户最初请求的HTML表单

创建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>

部署并测试

【Head First Servlets and JSP】笔记2:MVC迷你教程

 在开发环境的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>

部署并测试

【Head First Servlets and JSP】笔记2:MVC迷你教程

 流程详解:把逻辑名映射到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的修改则不是必须的。

Ⅲ、为专家/模型类构建一个测试类,然后构建并测试专家/模型类本身

如何用junit编写测试类?单元测试

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());
        }
    }
}

 【Head First Servlets and JSP】笔记2:MVC迷你教程

Ⅴ、构建JSP,把servlet升级到第三个版本(把表示分派到JSP),然后再测试整个应用

【Head First Servlets and JSP】笔记2:MVC迷你教程

 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>

 【Head First Servlets and JSP】笔记2:MVC迷你教程

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发送请求和响应
    }
}