Head First Servlets & JSP 学习笔记 第三章 —— MVC迷你教程

时间:2021-01-01 21:03:23

渊羡鱼,不如退而结网!是时候动手搞事情了!

们的四大步骤:

分析用户的视图(也就是浏览器要显示的东西),以及高层体系结构;

(这个就是所谓的前端吧?用JSP?JSP可以当成Html来用吧?高层体系结构,这个没听过)

创建用于开发这个项目的开发环境;

(这个说简单也简单,说难也难啊!不少好汉被这个难住了)

创建用于部署这个项目的部署环境;

(同②)

对Web应用的各个组件完成迭代式的开发和测试。

(好高深。。。好学术。。。迭代式?)

我们的Web应用是一个啤酒顾问(Beer Advisor)。尽管这是一个非常小的应用,但我们要使用一个简单的MVC体系结构来构建(原来高层体系结构说的就是MVC体系结构)。

应用内部的具体流程:

1.客户请求得到form.html页面。

2.容器获得form.html页面。

3.容器把这个页面返回给浏览器,用户再在浏览器上回答表单上的问题。

4.用户问题回答完毕点击提交,浏览器把请求数据发送到容器。

5.容器根据URL找到正确的Servlet,并把请求传递给这个Servlet。

6.Servlet调用模型BeerExpert,寻求模型的帮助。

7.模型BeerExpert返回一个回答,Servlet把这个回答增加到请求对象。

8.Servlet把请求转发给JSP。(不理解,不懂是怎么转发的?)

9.JSP从请求对象得到回答。(不理解)

10.JSP为容器生成一个页面。(不理解,JSP怎么生成一个页面的?)

11.容器把这个页面返回给客户。

中使用的是Tomcat5,由于第一章中的小例子在部署Web应用中就遇到了问题,这次还是先暂时跟着书来,如果还是不行就按照自己的方式进行修改。

前面的四大步骤先不管①②③,直接看④。第④步又分为5个小步骤:

④a:构建和测试用户最初请求的Html表单;④b:构建控制器Servlet的第一个版本;④c:为模型类构建一个测试类,然后构建模型类本身;④d:把Servlet升级到版本2,这个版本增加一个功能,可以调用模型类来得到啤酒建议; ④e:构建JSP,把Servlet升级到版本3,再增加一个功能,可以把表示分配到JSP完成,然后再测试整个应用。

④a:第一个表单页面的html

(保存为from.html,保存到F:/Beer/web目录下,这个是开发环境,然后再把这个文件复制到tomcat/webapps/Beer中,这个是部署环境)(部署环境的tomcat目录就是你安装的Tomcat的根目录,下面有webapps目录)

 1 <!doctype html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>Beer Selection</title>
 6     </head>
 7     <body>
 8         <h1 style="text-align:center">Beer Selection Page</h1>
 9         <form style="text-align:center" method="post" action="SelectBeer.do"> //anction表示表单数据提交到SelectBeer.do这个Servlet,这个名字只是一个逻辑名字,不是Servlet的真正名字,也不是Servlet类的类名
10             <p>Select beer characteristics</p>
11             <span>Color:</span>
12             <select name="color" size="1">
13                 <option value="light">light</option>
14                 <option value="amber">amber</option>
15                 <option value="brown">brown</option>
16                 <option value="dark">dark</option>
17             </select>
18             <br /><br />
19             <input  style="text-align:center" type="submit" value="提交" />
20         </form>
21     </body>
22 </html>

在开发环境中创建DD(部署描述文件——web.xml)

将其保存到F:/Beer/etc目录下,然后再复制到tomcat/webapps/Beer/WEB-INF目录下,这个是部署环境

<?xml version="1.0" encoding="utf-8"?>
<web-app>
    <servlet>
        <servlet-name>Ch3 Beer</servlet-name>
        <servlet-class>com.example.web.BeerServlet</servlet-class> //Servlet真正的名字,com.example.web是包名
    </servlet>
    <servlet-mapping>
        <servlet-name>Ch3 Beer</servlet-name> //Servlet的内部名字
        <url-pattern>/SelectBeer.do</url-pattern> //Servlet的逻辑名字,对用户名字
    </servlet-mapping>
</web-app>

测试form.html页面:

上面做好后,启动Tomcat,在浏览器地址栏输入:http://127.0.0.1:8080/Beer/form.html,应该能正常显示form.html页面。

 Servlet版本一:

(保存到开发环境:F:/Beer/src/com/example/web/BeerServlet.java)

package com.example.web; //包名

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class BeerServlet extends HttpServlet{ //继承了HttpServlet
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ //将异常抛出
        response.setContentType("text/html; charset=utf-8"); //设置响应对象的编码
        
        PrintWriter out = response.getWriter();
        out.println("Beer Selection Advice<br />"); //简单地输出一段信息
        
        String c = request.getParameter("color"); //获取请求中的color属性
        out.println("<br />Got beer color " + c);  //把选中的颜色输出
    }
}

编译Servlet:

(先在F:/Beer文件夹中新建一个classes目录,用来存放.class文件)

win + r + cmd进入windows命令行,依次输入如下命令:

1 F: //先进入F盘 2 cd Beer //再进入Beer目录 3 javac -classpath F:/tomcat/common/lib/servlet-api.jar;classes -d classes -encoding utf8 src/com/example/web/BeerServlet.java //编译BeerServlet.java,其中tomcat/com/lib前面的盘根据自己的情况来写,我自己是F盘

编译成功后,会发现F:/Beer/classes目录下有com/example//web/BeerServlet.class文件,它编译的时候把包目录也自动生成了。(但是如果没有一开始的classes目录就会编译错误)

部署Servlet:

(复制F:Beer里面的classes目录,将其复制到部署目录F:/tomcat/webapps/Beer/WEB-INF目录下,所以部署目录会是:F:/tomcat/webapps/Beer/WEB-INF/classes/com/example/web/BeerServlet.class。部署完成之后,就测试Servlet。重启Tomcat,在浏览器地址栏中输入:http://127.0.0.1:8080/Beer/form.html  然后选择一个颜色,点击提交按钮,会看到一个新的页面,其中显示了你选择的颜色!

构建和测试模型

(模型,大多数情况下只是普通的Java代码,根本不知道自己会被Servlet调用。编写完后保存到开发环境:F:/Beer/src/com/example/model/BeerExpert.java)

 1 package com.example.model; //包名  2 
 3 import java.util.*;
 4 
 5 public class BeerExpert{
 6     public List getBrands(String color){ //返回一个List列表  7         List<String> brands = new ArrayList<>();
 8         if(color.equals("amber")){ 
 9             brands.add("Jack Amber");
10             brands.add("Red Moose");
11         }else{
12             brands.add("Jail Pale Ale");
13             brands.add("Gout Stout");
14         }
15         return brands;
16     }
17 }

编译BeerExpert.java:

win + r + cmd 进入windows命令行,依次输入如下命令:

1 F:
2 cd Beer
3 javac -d classes -encoding utf8 src/com/example/model/BeerExpert.java

改进Servlet,版本2:

(调用模型来得到建议。在开发环境,F:/Beer/src/com/example/web/BeerServlet.java,修改版本1中的Servle)

 1 package com.example.web;
 2 
 3 import javax.servlet.*;
 4 import javax.servlet.http.*;
 5 import java.io.*;
 6 import java.util.*; //新增  7 import com.example.model.BeerExpert; //新增  8 
 9 public class BeerServlet extends HttpServlet{
10     public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
11         response.setContentType("text/html; charset=utf-8");
12         
13         PrintWriter out = response.getWriter();
14         out.println("Beer Selection Advice<br />");
15         
16         String c = request.getParameter("color");
17         List result = new BeerExpert().getBrands(c); //新增 18         
19         Iterator it = result.iterator(); //新增 20         while(it.hasNext()){
21             out.print("<br />try: " + it.next());
22         }
23     }
24 }

到这里还是没有理解前面具体流程中8、9、10。因为JSP还没有发挥作用。

重新编译BeerServlet.java

win + r + cmd ,进入命令行,和第一次编译BeerServlet的命令一样:

1 F:
2 cd Beer
3 javac -classpath F:/tomcat/common/lib/servlet-api.jar;classes -d classes -encoding utf8 src/com/example/web/BeerServlet.java //-classpath用来指定类路径,当指定多个类路径时,用“;”分号进行分隔,例如这句命令就指定了两个

把重新编译生成的BeerServlet.class复制到部署环境:F:/tomcat/webapps/Beer/WEB-INF/classes/com/example/web目录下,替换之前的版本1的BeerServlet.class。

部署模型的类文件:

把上面编译好的BeerExpert.class复制到的部署环境:F:/tomcat/webapps/Beer/WEB-INF/classes/com/example/model目录下,没有就自己新建一个model文件夹。

关闭Tomcat并重启,验证模型:

在浏览器地址栏输入http://127.0.0.1:8080/Beer/form.html,可以发现选择“amber”这个颜色时,会推荐Jack Amber 、Red Moose这两种酒,选择其他颜色时,会推荐Jail Pale、 AleGout Stout,说明模型成功运行了。

创建JSP,再部署JSP:

一个非常简单的JSP,命令为result.jsp,先保存在开发环境F:/Beer/web 文件夹中。然后复制这个result.jsp到部署环境:F:/tomcat/webapps/Beer 文件夹中,和上面的form.html同级。

 1 <%@ page import="java.util.*" %>
 2 <!doctype html>
 3 <html>
 4     <head>
 5         <meta charset="utf-8" />
 6         <title>result_jsp</title>
 7     </head>
 8     <body>
 9         <h1 style="text-align:center">Beer Recommendations JSP</h1>
10         
11         <% 
12             List<String> styles = (List)request.getAttribute("styles");
13             Iterator it = styles.iterator();
14             while(it.hasNext()){
15                 out.print("<br />try: " + it.next());
16             }
17         %>
18     </body>
19 </html>

继续改进Servlet,得到版本3:

这一步,要把Servlet修改为“调用”JSP来生成输出(视图)。容器提供了一种称为“请求分派”的机制,允许容器管理的一个组件调用另一个组件。我们就会使用这种机制,Servlet从模型中得到消息,把它保存在请求对象中,然后把请求对象分派给JSP。

 1 package com.example.web;
 2 
 3 import javax.servlet.*;
 4 import javax.servlet.http.*;
 5 import java.io.*;
 6 import java.util.*;
 7 import com.example.model.BeerExpert;
 8 
 9 public class BeerServlet extends HttpServlet{
10     public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
11         //response.setContentType("text/html; charset=utf-8");
12         //既然要由JSP来生成输出,Servlet的测试输出就没用了
13         //PrintWriter out = response.getWriter();
14         //out.println("Beer Selection Advice<br />");
15         
16         String c = request.getParameter("color");
17         List result = new BeerExpert().getBrands(c);
18         
19         request.setAttribute("styles", result); //为请求对象设置一个属性,供JSP使用
20         
21         request.getRequestDispatcher("result.jsp").forward(request, response); 
22         // 为JSP实例化一个请求分派器(这不就是服务器端的跳转嘛?)
23         //forward(request, response),这个是使用请求分派器要求容器准备好JSP,并向JSP发送请求和响应
24     }
25 }

编译、部署和最后的测试:

1 F:
2 cd Beer
3 javac -classpath F:/tomcat/common/lib/servlet-api.jar;classes -d classes -encoding utf8 src/com/example/web/BeerServlet.java

把新的BeerServlet.class文件复制到部署环境中,替换掉之前的。

然后关闭Tomcat并重启,在浏览器中输入http://127.0.0.1:8080/Beer/form.html 

选择颜色“amber”点击“提交”后,出现Beer Recommendations JSP页面,建议Jack Amber 和 Red Moose;

选择颜色“light”,建议 Jail Pale Ale 和 Gout Stou。说明JSP生成视图成功。

总结:

这一章学习了简单的MVC设计模式,写了一个BeerExpert类作为模型,这个模型的作用是根据控制器传给它的颜色,来做出酒的推荐;写了一个result.jsp来作为视图,这个视图的使用方式是:Servlet把用户提交的颜色参数传给模型,模型给出建议,建议保存在List列表中,Servlet根据生成的建议,对请求对象增加一个属性styles,这个属性styles中肯定要么指向建议,要么就保存着建议,然后Servlet在进行服务器端的跳转,跳转到result.jsp页面(书上说是实例化一个请求分派器,并向JSP发送请求和响应);然后JSP页面上有一段Java代码,这段代码获取请求上的属性styles,并把styles中的内容打印出来。