迷你MVC教程——命令行方式创建第一个servelt小程序

迷你MVC教程

本文节选自《Head First Servlets and JSP》第3章 MVC实战,根据个人配置和实操情况有所删改。本人注解部分用斜体表示。图片截取自原书,部分为个人操作截图。本人电脑配置win10x64, tomcat7, jdk10。本教程的特色处在于全程采用手工编写和命令行结合,不借助IDE开发环境,适合初次接触Servlet者当作练习的小项目。任何问题请在下方留言。

  • 迷你MVC教程
    • 构建小型Web应用步骤
      • 用户视图
      • 体系结构
      • 开发环境
      • 部署环境
      • 迭代式的开发和测试
        • 第一个表单页面的HTML
        • 部署和测试开始页面
        • 逻辑名映射到servlet类文件
        • 控制器servlet的第1版
        • 编译、部署和测试控制器servlet
        • 构建和测试模型类
        • 改进servlet,调用模型得到真正的建议
        • 第2版Servlet代码
        • 第2版servlet的关键步骤
        • 创建提供建议的JSP”视图”
        • 改进这个servlet,让它”调用“JSP(第3版)
        • 第3版servlet的代码
        • 编译、部署和测试最后的应用

构建小型Web应用步骤

  1. 分析用户的视图以及高层体系结构
  2. 创建用于开发这个项目的开发环境
  3. 创建用于部署这个项目的部署环境
  4. 对Web应用的各个组件完成迭代式的开发和测试

(基于Beer Advisor的案例。根据用户选择的酒色提供酒的品牌建议的servlet小程序

用户视图

  • 用户最初请求的HTML表单,生成HTTP POST请求
  • 处理请求返回的result.jsp

体系结构

  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为容器生成一个页面
  11. 容器将jsp页面返回给用户

迷你MVC教程——命令行方式创建第一个servelt小程序_第1张图片

开发环境

IDE项目的目录结构

迷你MVC教程——命令行方式创建第一个servelt小程序_第2张图片

部署环境

将Web项目部署到容器中

迷你MVC教程——命令行方式创建第一个servelt小程序_第3张图片

迭代式的开发和测试

  1. 构建和测试用户最初请求的HTML表单
  2. 构建控制器servlet的第一个版本,并用HTML表单测试这个控制器。这个版本通过HTML表单来调用,并打印出它接收到的参数
  3. 为模型类构建一个测试类,然后构建并测试模型类本身
  4. 把servlet升级到第2版。这个版本增加了一个功能,可以调用模型类来得到啤酒建议。
  5. 构建JSP, 把servlet升级到第3版本(增加一个功能,可以把表示流分派到JSP完成),然后再测试整个应用。

第一个表单页面的HTML

form.html包含标题文本,一个下拉列表,还有一个提交按钮(原书代码)

<html>
    <body>
        <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 value="light">lightoption>
                <option value="amber">amberoption>
                <option value="brown">brownoption>
                <option value="dark">darkoption>
            select>
            <br><br>
            <center>
            <input type="SUBMIT">
            center>
        form>
    body>
html>

部署和测试开始页面

  1. 在开发环境中创建HTML

创建这个HTML文件,取名为form.html,然后保存在开发环境的/beerV1/web/目录下

  1. 把这个文件复制到部署环境

把form.html文件的一个副本放在tomcat/webapps/Beer-vl/中

  1. 在开发环境中创建DD

创建XML文档,取名为web.xml, 把它保存在开发环境的/beer/etc/目录下(原书代码)


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <servlet>
      
    <servlet-name>Ch3 Beerservlet-name>
      
    <servlet-class>com.example.web.BeerSelectservlet-class>
  servlet>

  <servlet-mapping>
    <servlet-name>Ch3 Beerservlet-name>
      
    <url-pattern>/SelectBeer.dourl-pattern>
  servlet-mapping>

web-app> 

由于原书代码是tomcat5, 版本有所变化,可以到tomcat/webapps/ROOT/WEB-INF自带目录下拷贝了一份web-xml文件,并添加相应的映射语句。

  1. 把这个文件复制到部署环境

把web.xml文件的一个副本放在tomcat/webapps/Beer-v1/WEB-INF/

  1. 启动Tomcat

Tomcat既作为Web服务器,又作为Web容器。要启动Tomcat, 先用cd命令切换到tomcat主目录,再运行bin/startup.sh

迷你MVC教程——命令行方式创建第一个servelt小程序_第4张图片

命令行中用cd切换到tomcat/bin目录下(tomcat根据版本名称不同),win系统运行startup.bat

  1. 测试页面

在浏览器中打开这个HTML页面,为此键入:

http://localhost:8080/Beer-v1/form.html

逻辑名映射到servlet类文件

以下部分为xml文件中配置的详解

  1. 用户填写表单,然后点击submit。浏览器生成了以下请求URL:

/1Beer-v1[^2]/SelectBeer.do[^3]

在用户发送的http post请求中,“/Beer-v1”不是路径的一部分。在form.html中,它只说:

但浏览器为请求追加了“/Beer-v1/”,因为用户请求就来自这里。换句话说,form.html中的“SelectBeer.do”相对于其所在页面的URL。在这里,就是相对于Web应用的根:“/Beer-v1”

  1. 容器搜索DD, 找到与/SelectBeer.do匹配的一个, 这里的斜线{/}表示Web应用的上下文根,SelectBeer.do就是资源的逻辑名
  2. 容器看到对应这个是“Ch3 Beer”。但是这并不是实际servlet类文件的名字。“Ch3 Beer”是servlet名,而不是servlet类的名字。

对容器来说,servlet只是在DD中标记下的一个东西。servlet名只在DD中使用,以便DD的其他部分建立与该servlet的映射

  1. 容器查找为“Ch3 Beer”的标记
  2. 根据标记中的,容器可以知道有哪个servlet类负责处理这个请求。如果这个servlet还没有初始化,就会加载类,并初始化servlet
  3. 容器开始一个新线程来处理这个请求,并把请求传递给这个线程(传递给servelt的service()方法)
  4. 容器把响应(通过Web服务器)发回给用户

控制器servlet的第1版

确保HTML页面能适当地调用servlet, 而且servlet能正确地接收HTML参数。

(原书代码)

//确保与前面创建的开发结构和部署结构匹配
package com.example.web;

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

//HttpServlet扩展了GenericServlet,GenericServlet则实现了Servlet接口
public class BeerSelect extends HttpServlet{
     

    //我们使用doPOST来处理HTTP请求,因为HTML表单指出,method=POST
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{

        //这个方法来自ServletResponse接口
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Beer Selection Advice
"
); //这个方法来自ServletRequest接口。注意这个参数与HTML