servlet

一 Servlet概述

1.1 什么是Servlet

        Servlet 是Server Applet 的简称,是用Java编写的,可以运行在 Web 服务器(Tomcat)上的程序,是Sun公司制定的一套规范(接口)。

Servlet的主要用途:

  1. 接受、处理来自浏览器端(BS架构中的B端)的请求和用户输入

  2. 响应来自数据库或者服务端(BS架构中的S端)产生的数据到浏览器端,动态构建网页。

 

1.2 手动实现Servlet小程序

1.2.1 实现步骤

  1. 自定义一个类型,实现Servlet接口或者继承HttpServlet类

  2. 使用javac指令,将源文件编译成字节码文件

  3. 将编译完的字节码文件按照一定的组织结构打包,并编写web.xml配置文件

  4. 将整个组织结构放入Tomcat的webapps文件夹中

  5. 启动Tomcat,在浏览器上输入符合规范的地址去访问Servlet。

1.2.2 具体实现

步骤1: 编写一个类HelloWorldServlet,继承HttpServlet类型

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet{
	public void service(HttpServletRequest request,
		HttpServletResponse response) throws ServletException,IOException{
			response.getWriter().println("Hello world");
			
		}
}

步骤2: 编译,生成.class文件

javac HelloWorldServlet.java -classpath   xxxxx\xxxxxx\servlet-api.jar

步骤3:项目的组织结构

appName 项目名称(主要用来区分其他项目的)
    --   WEB-INF文件夹
             -- classes文件夹: 用来存储class文件的整个路径

                        如:com\servlet 
             -- lib(可选文件夹)
             -- web.xml:  当前项目的主配置文件
    -- index.jsp
   -- css
   -- js
   -- html

比如:

myfirstservlet  
    -- WEB-INF
         --classes
         --web.xml

web.xml里的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
		 http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
	
		<!-- 一个servlet组件,对应两个标签,分别是servlet和servlet-mapping
			servlet用于指定具体的servlet组件的类名
			servlet-mapping用于指定浏览器上的请求资源路径
			
			如果想要将servlet和servlet-mapping绑定为一组,
			那么必须使用servlet-name来设定相同的名字
		-->
	<servlet>
		<servlet-name>a</servlet-name>
		<servlet-class>com.servlet.HelloWorldServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>a</servlet-name>
		<url-pattern>/myServlet</url-pattern>
	</servlet-mapping>
</web-app>

步骤4: 将整个文件夹组织结构,拷贝到tomcat的webapps文件夹里。这一步的专业术语叫部署项目.

步骤5:启动tomcat

找到tomcat的bin目录下的startup.bat可执行文件,启动后,不要关闭。

步骤6:在浏览器上输入地址,向tomcat容器发送请求

http://localhost:8080/myfirstweb/hello ,回车后,应该会看到hello world字样

执行过程如图: 

 

 部署完项目后的执行流程:
1. 浏览器向服务器发送请求,访问服务器上的某一个项目下的某一个资源。   
   路径如下:http://服务器IP:服务器端口/项目名/资源路径
2. 服务器收到请求后,会先确认并找到该项目
3. 如果找到了该项目,会加载里面的web.xml配置文件
4. 然后通过资源路径,去匹配servlet-mapping里的url-pattern,来确定servlet-name。
5. 根据servlet-name,定位到对应的servlet里的servlet-class。
6. 根据servlet-class标签里的类全名,去项目的classes目录下查找对应的类文件
7. 执行类文件里的service方法,将数据最终响应给浏览器

1.3 Idea开发Servlet程序

第一步:创建java项目(java module):MyFirstWeb。

第二步:添加web框架支持。 也就是找到add Frameworks Support,选择web application。

idea会帮助我们自动维护web项目的组织结构: web-inf,web.xml

第三步:在WEB-INF下创建lib文件夹,将第三方jar包放入,比如servlet-api.jar文件  

注意:别忘记  add as library 

第四步:编写Servlet组件

第五步:配置web.xml

第六步:关联tomcat:

edit configuration...

add new ...

tomcat server  (注意千万不要用tomEE server)

local:

选择tomcat home

fix   定义项目部署的虚拟名称

apply  ok

第七步:启动tomcat 进行测试  

1.4 常见的HTTP错误代码

404:Not found,表示您要请求的资源服务器无法帮您找到。原因可能如下:  

1. 没有写web.xml配置文件
2. 地址栏上的地址信息写错了,可能没有写部署的项目名称,或者项目名后的资源路径写错误
3. web.xml里的url-pattern对应上了,但是两个name没有对应上
4.上面都改正确了,但是忘记了重新部署。 

405:Method Not Allowed  

servlet组件里没有重写service/doGet/doPost方法,或者是方法写的不标准,比如参数,异常的声明等。

500:Internal Server Error,表示服务器内部发生错误

1. servlet-class标签里的类名书写有误。
2. 编写的类型不是一个servlet组件,也就是没有继承HttpServlet或者实现Servlet接口
3. Servlet 代码中抛出异常导致的,也就是servlet类里你写的代码有问题

二 Servlet工作原理

2.1 Servlet的生命周期

        servlet容器是如何创建Servlet对象,如何为Servlet对象分配资源,如何调用Servlet对象的方法来处理请求,以及如何销毁Servlet对象的整个过程。而这个过程可以分为四个阶段,分别是实例化阶段、初始化阶段、就绪阶段、销毁阶段。

2.1.1 阶段一:实例化

什么是实例化?

  • 容器调用Servlet的构造器,创建一个Servlet对象

    MySecondServlet  s = new MySecondServlet()   <------不是程序员调用的,而是容器帮助我们调用并创建的。

什么时候实例化?

  • 情形一,开始容器里面没有Servlet对象,只有收到请求后才会创建Servlet对象(默认情况)

        当浏览器发送请求:http://localhost:8088/employee_v1/listEmp
        tomcat容器会收到该请求,该请求是请求的是ListEmp.class这个组件,因此tomcat容器会帮助程序员创建ListEmp这个组件的对象
        其他的没有访问过的组件,比如AddEmp,DelEmp等这些组件,在容器中没有。。。

  • 情形二,容器启动之后就立即创建相应的实例,

    需要添加配置<load-on-startup>1</load-on-startup> 1表示创建,-1表示不创建

     <servlet>
            <servlet-name>addEmp</servlet-name>
            <servlet-class>com.shuilidianli.employee.web.AddEmp</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>addEmp</servlet-name>
            <url-pattern>/addEmp</url-pattern>
        </servlet-mapping>

总结:

1. 谁负责实例化servlet类(也可以叫组件)的对象 tomcat(servlet容器)

2. 什么时机实例化:  

                        - 浏览器发送请求这个组件时创建  

                        - 添加配置参数load-on-startup, 在tomcat服务器启动时创建。

2.1.2 阶段二:初始化

什么是初始化?

  • 容器在创建好Servlet对象后,会立即调用该对象的init方法

  • 一般情况下,我们不用写init方法,因为genericServlet已经提供了init方法的实现(将容器传递过来的ServletConfig对象保存下来,并且,提供了getServletConfig方法来获取ServletConfig对象)。

  • init方法只会执行一次

默认情况下,init方法不需要重写。但是有的时候,如果你有这方面的需求时,比如将公司信息作为初始化参数,用于init方法来到程序中,就可以重写init进行获取。

Servlet的初始化参数如何配置,在web.xml中添加如下形式:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>

        <servlet-name>aa</servlet-name>
        <servlet-class>com.servlet.day01.web.MySecondServlet</servlet-class>
        <init-param>
            <param-name>company</param-name>
            <param-value>佑才教育</param-value>
        </init-param>
    <!-- load-on-startup: 容器启动后,就实例化该组件,默认情况下是访问时才实例化-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>

        <servlet-name>aa</servlet-name>
        <url-pattern>/ssy</url-pattern>
    </servlet-mapping>
</web-app>

注意:init-param的位置必须放在load-on-startup前面

如何读取Servlet的初始化参数

 @Override
    public void init() throws ServletException {
        //调用继承过来的getServletConfig方法,获取servlet配置对象
        ServletConfig config = getServletConfig();
        String value = config.getInitParameter("company");
        this.company = value;
    }

总结:

        servlet容器在实例化servlet对象后,会自动调用init方法进行初始化操作。程序员可以重写init方法。 使用ServletConfig对象来读取初始化参数。

2.1.3 阶段三:就绪

容器收到请求后调用Servlet对象的service()方法来处理请求

2.1.4 阶段四:销毁

  • 容器依据自身算法删除Servlet对象删除前会调用destroy()

  • 只会执行一次

  • 可以override destroy方法来实现自己的处理逻辑

  • 应用程序卸载时一定会调用destroy方法

2.2 请求方式

2.2.1 请求方式介绍

不同的请求方式在数据传输时,会有所不同;在表单提交以及服务器处理时都会采用不同的方式。浏览器针对每种请求方式也会使用不同的缓存技术,提高相应的处理速度。

常用的请求方式有:

get:   请求服务器上指定的资源
post: 向服务器上的资源提交数据
head:  和get相似
put:   上传资源
delete: 删除资源 

 get请求:

浏览器发送get请求的场景:
1.  在地址栏单纯的输入一个地址
2.  a标记产生的请求
3.  form表单默认提交方式,也是get请求

注意:
1. get请求,如果带有一些提交数据,比如用户名,密码等。那么这些数据会被添加到地址栏中,不安全
2. get请求提交的数据量比较小,在4KB以内。

post:

浏览器发送post请求的场景: 

form表单的method属性的值为post时。

注意:
    要传输给服务器的处理数据都会在正文(http信息数据的body)中存储相对安全

小贴士:

如果想要提交form表单,两个属性要知道:
1. method属性,用于指定请求方式,默认不写是get请求
2. action属性,是必填项,因为action的值就是地址栏上的url-pattern. 

2.2.2 service/doGet/doPost/

        实际上:当浏览器发送请求后,会默认执行servlet组件继承过来的service方法,然后service方法里的逻辑:String method = req.getMethod(); 会获取请求的方法,如果是get请求,会执行doGet(req, resp); 如果是post请求,会执行doPost(req, resp);

        上述代码说明:程序员在写servlet时,可以选择覆盖service方法,也可以选择覆盖doGet() 或者是doPost方法。前提如果是get请求,可以直接覆盖doGet(), 如果是post请求,可以直接覆盖doPost()

注意:如果重写了service方法,就不会再执行doGet/doPost方法,除非重写的service方法里调用了doGet/doPost

 

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 TestMethodServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----doGet-------");
        PrintWriter pw = resp.getWriter();
        pw.println("get");
        pw.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----doPost-------");
        doGet(req,resp);
    }
}

 web.xml

<servlet>
   <servlet-name>test</servlet-name>
   <servlet-class>com.shuilidianli.web.TestMethodServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>test</servlet-name>
   <url-pattern>/test</url-pattern>
</servlet-mapping>

test.html  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="test">
        <input type="submit" value="提交">
    </form>
</body>
</html>

2.3 请求对象

        web服务器(tomcat容器)在接收到浏览器发送过来的请求后,发送过来的所有通信数据都会被web服务器进行封装和提供。这些信息主要被封装到两个对象上。

一个是HttpServletRequest类型的对象:

1. 浏览器发送的所有数据都会被web服务器封装到HttpServletRequest类型的对象上,此类型提供了相应的方法可以从对象上获取相关的数据。比如请求行的数据、消息头、实体内容(正文、参数值)
2.作用:
    读取和设置http的请求数据
    取得和设置cookies
    实现请求转发
    取得路径信息
    标识HTTP会话

2.3.1 参数值的获取

不管是get请求提交的少量数据,还是post请求提交的大量的数据。那么服务器端就要接受到这些数据,并处理。

浏览器发送的数据有以下两种情况:

1:1的情况:

localhost:8088/day42_servlet/web?username=zhangsan&password=123456

上述的地址,?后面是要传入到服务端的数据username对应一个值,password对应一个值。

1:N的情况

localhost:8088/day42_servlet/web?username=zhangsan&password=123456&hobby=book&hobby=movie&gender=f

上述的地址,?后面是要传入到服务端的数据,username对应一个值,password对应一个值,gender对应一个值
而hobby对应两个值hobby与它的值就是1:N的情况

服务端的请求对象提供了相应的获取参数值的方法。  

方法1:String getParameter()  :  
       解析:获取的是1对1的参数值,  比如用户名或密码
       用法: String value = request.getParameter("key")
       注意: 如果没有获取值,那么返回的是null,而不是异常   


方法2:String[] getParameterValues():  
       解析:获取的是1对多的参数值,  比如 爱好
       用法:String[] values = request.getParameter("key")
       注意:如果没有获取值,那么返回的是null,而不是异常 

        参数:浏览器封装的参数是以键值对的形式体现的,比如username=zhangsan. username是参数名,zhangsan是参数值。

注意:input元素的name属性用于指定参数名。

2.4 响应对象

一个是HttpServletResponse类型的对象

1.web服务器会对浏览器进行响应,响应的所有数据都会被封装到HttpServletResponse类型的对象上。此类型提供了相关设置方法,可以设置状态行、消息头、实体内容等。
2.作用:
    设置客户端的输出内容
    设置响应状态码
    设置浏览器的解码方式
    设置cookies
    实现重定向 

 

2.5 中文乱码问题

两处乱码:

第一处: 后端响应浏览器时: response向浏览器返回中文时出现乱码

response.getWriter().println("你好,Servlet");

第二处: post请求时,浏览器向后端发送了中文时出现了乱码

String username = request.getParameter("username");      username=张三    是汉字时

乱码的情况原因很简单,就是编码过程使用的字符集与解码过程使用的字符集不一致造成的,不是逻辑问题。

编码:字符串变成字节数组的形式   "中国"-->[-86,-92,-78,-12,-64,-23]    

使用字符手册 UTF8   三个字节对应一个汉字 解码:

字节数组变成字符串[-86,-92,-78,-12,-64,-23]-->"中国"  

使用字符手册uncode 两个字节对应一个汉字

浏览器使用post请求方式提交中文时:

1. 确保浏览器的html页面是utf-8编码集
2. 在servlet中(也就是服务端)的service方法的第一行处,使用
   request.setCharacterEncoding("utf-8");即可

浏览器使用get请求方式提交中文时:

1. 确保浏览器的html页面是utf-8编码集
2. 因为服务端默认使用iso-8859-1进行解码。我们的解决方式就是在服务端再次使用iso-8859-1进行编码,然后在使用utf-8进行解码。
       String username = request.getParameter("username") // 
       byte[] bs =  username.getBytes("iso-8859-1") ; 
       //借助string的构造器,重新解码即可
       String str = new String(bs,"utf-8");// 

服务端向浏览器发送中文乱码情况:

只需要在服务端对中文进行编码前,写入这一行代码即可:
response.setContentType("text/html;charset=utf8");

2.6 Servlet调用DAO

第一步:引入第三方资源,比如相关依赖的jar包坐标, mysql驱动,druid数据源

第二步:在resources配置druid.properties

第三步:编写DruidUtil工具类,并测试(里面提供main方法)

第四步:根据ORM关系模型,编写emp表的实体类Emp

第五步:编写相关的Dao接口以及Dao接口的实现类

第六步:编写EmpServlet组件

第七步: 编写web.xml

第八步:File–>Project structure–>Artifacts–>Available Elements–>右键点击项目–>put into output root

第九步:重新部署项目(启动tomcat) 在浏览器上输入地址进行测试

2.7 总结 servlet的运行流程:

1: 浏览器发送地址请求
2: 根据ip和port号定位到tomcat容器
3: tomcat容器根据appName确定项目
4: 然后tomcat查找当前项目下的web.xml配置信息,用url-pattern与地址信息进行匹配
5: 根据两个相同的name找到对应的servlet组件
6: 执行servlet组件里的service方法(执行的是classes里的class文件)
7: 向浏览器发送响应信息。
8:浏览器收到响应信息后会进行解析和显示。 

三 Servlet对路径的处理

3.1 重定向

用户在浏览器输入一个地址,或者点击按钮触发一个请求地址,然后去往服务器端,此时服务端处理完相关计算后,再次向浏览器发送一个302状态和一个新的地址(比如www.baidu.com).   之后浏览器收到了302状态码和一个新的地址,然后浏览器就重新向这个新的地址发送请求。


302: 表示重定向,  当浏览器收到的状态码是302,表示需要重新发送请求,请求地址是和302一起过来的那个新的地址。

适合的场景:

用户使用浏览器触发了一次请求后,然后服务端向浏览器发送一个新的地址,由浏览器自动再次发送一个请求。

比如:添加一个新员工后,然后页面自动显示所有员工信息,包含两次请求
     第一次:insert,  用户主动触发的  
     第二次: select, 是服务端告诉浏览器再次触发
     
再比如: 登录成功后,跳转到主页面(所有员工信息) :
     第一次: 登录验证(LoginServlet)
                  --  调用DAO的checkLogin方法,返回true或者false
                  --  如果登录成功,此时应该向浏览器发送响应数据(302,新地址appName/findAll)
     第二次: 跳转到主页面(FindAllServlet)
                  -- 调用DAO的findAll方法,查询所有的员工信息,返回ResulSet
                  -- 遍历ResultSet ,然后使用流对象的println方法,拼接成一个table。
                  -- 响应对象将数据打包,返回给浏览器,浏览器解析成一个table

 

如何重定向 :

response.sendRedirect(String url)
url: 是重定向的新地址, 该地址可以是任意地址。

302状态码是响应对象自己设置的,不需要程序员设置 。

重定向的特点:

1. 重定向的地址可以是任何地址
2. 重定向后,浏览器的地址发生了变化
3. 重定向所涉及到的web组件并不共享同一个request和response
4. 重定向前,不可以关闭流 ,即不能调用 pw.close()

3.2 制作员工管理系统v1

3.2.0 准备工作

第一步:创建java的项目(注意,是module) employee_v1

第二步:添加web项目支持

第三步:引入相关jar包,放入lib下

第四步:定义项目的源码组织结构

com.employee.util
com.employee.vo
com.employee.dao
com.employee.dao.impl
com.employee.web
com.employee.test

第五步:编写DruidUtil连接池工具类

第六步:编写emp表的实体类Employee类型

第七步:编写emp表的Dao接口:EmployeeDao

public interface EmpDao {
    void addEmp(Emp emp);
    void delEmpById(int id);
    void modEmp(Emp emp);
    Emp findById(int id);
    ArrayList<Emp> findAll();
    ArrayList<Emp> findByPage(int page,int pageSize);
}

第八步:编写Dao接口的实现类:EmployeeDaoImpl

3.2.1 员工列表界面的实现

请求地址:  https://localhost:8088/employee_v1/findAll

1)编写员工列表的Servlet组件: FindAllServlet

2)编写web.xml

3)启动tomcat,进行测试。

3.2.2 添加员工的功能实现

1)在web目录下,编写一个addEmp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加员工信息页面</title>
</head>
<body>
    <div>
        <form action="addEmp"  method="post">
            员工编号:<input type="text" name="empno" placeholder="员工编号">  <br>
            员工姓名:<input type="text" name="ename" placeholder="员工姓名">  <br>
            员工职位:<input type="text" name="job" placeholder="员工职位">  <br>
            领导编号:<input type="text" name="mgr" placeholder="领导编号">  <br>
            入职日期:<input type="text" name="hiredate" placeholder="入职日期">  <br>
            员工工资:<input type="text" name="salary" placeholder="员工工资">  <br>
            员工奖金:<input type="text" name="bonus" placeholder="员工奖金">  <br>
            部门编号:<input type="text" name="deptno" placeholder="部门编号">  <br>
            <input type="submit" value="提交">
        </form>
    </div>
</body>
</html>

2)编写添加员工的组件AddEmpServlet

3)修改web.xml,新添加

4)重新部署tomcat,进行测试

- 先访问添加员工的HTMl页面。https://localhost:8088/employee_v1/addEmp.html
- 然后添加数据,点击提交

3.2.3 删除员工的功能实现

1)修改员工列表界面:添加删除按钮

2)修改web.xml,新添加一对配置信息

3)创建对应的组件 DelEmpServlet

4)部署tomcat,进行测试

3.2.4 修改员工的功能实现

逻辑应该经过一个查询组件,进行显示该员工原有的信息,然后在该页面中,进行修改部分值,最后点击提交,保存到数据库。

第一部分:编写跳转到修改页面的逻辑。

1)修改员工列表界面:添加去修改按钮

2)编写web.xml,新添加一对配置

2)编写ToUpdateEmp组件:获取浏览器传输过来的员工id,从数据库中查询出来,显示到一个form表单中,在浏览器中显示

3)启动tomcat,去测试

第二部分:编写在修改页面上修改信息,点击提交的逻辑

4)编写web.xml,新添加一对配置

5)编写对应的UpdateEmp组件

6)启动tomcat,去测试

3.3 处理请求资源路径

3.3.1 什么是请求资源路径

在浏览器地址栏中输入的地址格式如下:

https://ip:port/appName/xxx.html?.....   addEmp.html

http://localhost:8088/day44_servlet/findAll   findAllServlet    

https://ip:port/虚拟资源/具体资源

解析:

ip:  服务器所在IP地址
port: 服务器的端口号 
appName: 要访问的项目名称

/appName/xxx.html?.....    就是请求资源路径,也就是getRequestURI()方法的返回值。

3.3.2 处理请求资源路径的过程

当浏览器地址栏上输入https://ip:port/appName/xxx.htmlhttps://ip:port/appName/xxx.html

  1. 浏览器依据ipport,与servlet容器建立连接,然后将后面的请求资源路径发送给servlet容器

  2. servlet容器依据应用名/appName找到应用所在的文件夹,容器会默认请求的是一个servlet。

  3. 开始查找web.xml文件中的所有的servlet配置<url-pattern> ,查看是否有匹配的请求资源路径,如果有,就定位到对应的servlet组件

匹配方式以下有三种

1)精确匹配

        通过将请求资源路径中的具体资源名称与web.xml文件中的url-pattern进行对比,严格匹配相等后找到对应资源并执行。 如

<url-pattern>/abc.html<url-pattern>

        此时,尽管应用中有abc.html这个具体的页面,也会去执行该url-pattern对应的servlet组件,而不是返回这个具体的abc.html  

2)通配符匹配

使用“*”号来匹配0个或者多个字符,如下写法

<url-pattern>/*<url-pattern>

代表输入任何不同的url地址都将匹配成功,比如  

 http://ip:port/appName/abc.html
http://ip:port/appName/abc/def/ghi    这些地址都会匹配成功

3)后缀匹配

不能使用斜杠开头,使用*. 开头的任意多个字符.

使用*.具体后缀字符串,与浏览器发送过来的具体资源路径进行比较
web.xml中的后缀匹配url-pattern必须是"*.后缀字符串"这样的格式。
比如:
<url-pattern>*.account</url-pattern>
<url-pattern>*.emp</url-pattern>
<url-pattern>*.login</url-pattern>
建议:后缀是具体的模块名称,比如账务管理,员工管理,登录型等
小贴士:后缀匹配在web.xml中可以有多个,只要后缀不一样就可以

 后缀匹配的写法:
            *表示0个或者0个以上的任意字符,但是必须是后缀结尾的具体资源路径
            相对于字符串的endsWith(String str)方法,判断是否以某一个后缀结尾

<url-pattern>*.do<url-pattern>

4)无匹配的Servlet的处理

具体资源路径在web.xml中没有成功匹配到url-pattern。
    - 首先在servlet容器中找有没有叫这个具体资源路径的静态资源
    - 如果有,就将该静态资源,作为数据包相应数据包给浏览器
    - 如果没有,返回404

5)三者的优先级

精确匹配> 通配符匹配 > 后缀匹配 

 6)三种匹配方式的共存问题:

在web.xml文件中可以有精确匹配,也可以有通配符匹配
在web.xml文件中可以有精确匹配,也可以有后缀匹配
在web.xml文件中通配符匹配和后缀匹配可以共存的,但是通配符已经可以拦截所有的后缀匹配了,因此后缀匹配无效。所以写与不写都一样了。 

3.3.3 Servlet合并

一般情况下,Servlet的主要作用是充当控制器的角色,即接受请求后,分发给不同的资源,这时Servlet只需要有一个就可以完成分发的过程,所以需要将Servlet合并。

实现合并的步骤如下:

第一步:使用后缀匹配模式,修改web.xml文件

  • 将配置的多个相关的Servlet节点删除

  • 保留一对servlet、servlet-mapping

  • 修改url-pattern节点的内容为: *.emp

第二步:获取请求资源路径,分析具体请求资源后,依据分析结果调用不同的分支处理代码

  • 调用request.getRequestURI()方法获取请求资源路径

  • 分析对应资源后分发

String uri = request.getRequestURI();

if(uri.contains("/appName/findAll.emp")){
   //......
}else if(uri.contains("/appName/addEmp.emp")){
   //....
}else if(...){
   //....
}

3.4 员工管理系统v2

1)创建module名 employee_v2

2)添加web支持,即 add framework support

3)创建lib文件夹,将jar拷贝过来

4))将com包拷贝到新项目下、以及druid.properties拷贝过来

5))将web下的addEmp.html拷贝过来

6)修改web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
   <servlet>
        <servlet-name>emp</servlet-name>
        <servlet-class>com.employee.web.ActionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>emp</servlet-name>
   <!--        后缀匹配,千万不要写斜杠-->
        <url-pattern>*.emp</url-pattern>
    </servlet-mapping>
</web-app>

7)将五个Servlet组件合成一个ActionServlet

小贴士:

修改所有请求资源路径位置处的内容。添加.emp

1:  addEmp.html--->action="addEmp.emp"
2:  修改和删除按钮处的a链接,要添加.action
3:  三处重定向也要改
4:  修改页面的action的值也要改

8) 测试 

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值