Servlet学习

Tomcat目录

1.Tomcat目录学习1.Tomcat目录学习1.Tomcat目录学习

2.HTTP-浏览器和服务器的交互流程

3.浏览器中的书写格式

4.什么是Tomcat

5.设置注解:

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

知识点 学习

1.Http协议

2.写的格式 

标题

​ 

3.请求头

4.什么是Tomcat:

什么是Tomcat

5.设置注解:

       设置注解 在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源。 开发servlet项目,使用@WebServlet将一个继承于javax.servlet.http.HttpServlet 的类定义为Servlet组件。在 Servlet3.0中 .   

     可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请 求的 Servlet。

package com.xxxx.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
        System.out.println("Hello Servlet!");
        resp.getWriter().write("Hello World");
   }
}

 

6.Servlert 的访问流程:   

    Servlet的工作流程:

    1. 通过请求头获知浏览器访问的是哪个主机

    2. 再通过请求行获取访问的是哪个一个web应用

    3. 再通过请求行中的请求路径获知访问的是哪个资源

    4. 通过获取的资源路径在配置中匹配到真实的路径,

    5. 服务器会创建servlet对象,(如果是第一次访问时,创建servlet实例,并调用init方法进行初          始化操作)

    6. 调用service(request, response)方法来处理请求和响应的操作 

   7. 调用service完毕后返回服务器 由服务器讲response缓冲区的数据取出,以http响应的格式发           送给浏览器

      首先浏览器向Web 服务器发送一个HTTP请求,Web 服务器根据收到的请求,会创建一个HttpServltRequest 和 HttpServletResponse 对象,然后在调用相应的servlert 程序。

     在Svleret 程序运行的,他会首先从 HttpServlertRequest 对象中读取数据,然后通过service()的方法处理请求的信息,并将处理后的响应数据写入到HttpServlertResponse 对象中 ,最后Web 服务对从ServlertResponse 对象中读取到响应的数据,并发给浏览器。

   需要注意的是,在web浏览器服务运行的阶段,每一个Servlet 都会创建一个实例的对象,针对每次的Http请求,Web服务器都会调用请求的Servlert 实例的service (HttpServlertRequest request,HttpServlertRequest response) 方法,并创建一个response 对象。

7.HttpServletRequest对象和 HttpServletResponse对象

 HttpServletResponse对象
      Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的               request 对象和代表响应的response 对象。
 request和response对象代表请求和响应︰获取客户端数据,需要通过request对象;向客户端输出   数据,需要通过response对象。
  HttpServletResponse 的主要功能用于服务器对客户端的请求进行响应,将Web服务器处理后的    结果返回给客户端。service()方法中形参接收的是HttpServletResponse接口的实例化对象,这个    对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

    响应数据 接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流。 有两种形式: getWriter() 获取字符流(只能响应回字符) getOutputStream() 获取字节流(能响应一切数据) 响应回的数据到客户端被浏览器解析。

有两种形式

getWriter() 获取字符流

getOutputStream() 获取字节流 (能响应一切数据)

响应回的数据到客服端 被浏览器解析

注意:两者不能同时用

//字符输入流
PrintWriter writer = response.getWriter();
writer.writer("hello");
writer.writer("<h2> hell </h2>");
//字节流输出流
ServlertOutputStream out = response.getOutputStream();
out.writer("hello".getBytes());
out.writer("<h2>hello <h2>".getBytes());
//设置响应类型,默认是字符串
response.setHeader("content-type","text/html");

8.HttpServletRequest对象-常用方法和获取请求数据:

9.请求乱码问题:

// 设置服务端的编码
response.setCharacterEncoding("UTF-8");
// 设置客户端的响应类型及编码
response.setHeader("content-type","text/html;charset=UTF-8");
// 得到字符输出流
PrintWriter writer = response.getWriter();
writer.write("<h2>你好</h2>");

10.请求转发与重定向:

请求转发:
   请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对·           象进行保存,地址栏中的URL地址不会改变,得到响应后,服务器端再将响应发送给客户               端,从始至终只有一个请求发出。
        实现方式如下,达到多个资源协同响应的效果。

request.getRequestDispatcher(ur1).forward(request,response);

    1. 地址上显示的是请求servlet的地址。  返回200 ok

    2. 请求次数只有一次, 因为是服务器内部帮客户端执行了后续的工作。

    3. 只能跳转自己项目的资源路径 。  

    4. 效率上稍微高一点,因为只执行一次请求。

    5. 可以使用上一次的request对象。
 

重定向:

      举个例子来说,重定向就是一个客户向客服打电话咨询某某技术问题应该怎么处理,但客服也不    会,于是告诉了客户一个号码,说,你打这个电话,我们技术部的人会专门给你解答,然后客户    打了技术部电话,这就是重定向。

response.sendRedirect("login_success.html");

    1. 地址上显示的是最后的那个资源的路径地址

    2. 请求次数最少有两次, 服务器在第一次请求后,会返回302 以及一个地址, 浏览器在根据这个地址,执行第二次访问。

    3. 可以跳转到任意路径。 不是自己的工程也可以跳。

    4. 效率稍微低一点, 执行两次请求。

    5. 后续的请求,没法使用上一次的request存储的数据,或者 没法使用上一次的request对象,因为这是两次不同的请求。

请求转发和重定向的区别:

11.request作用域:

   通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,及服务器跳转有效

//设置域对象的内容
request.setAttribute(String name,String value);
//获取对象的内容
request.getAttribute(String name);
//删除域对象的内容
request.removeAttribute(String name)
//request 域对象中的数据在一次请求中有效,则经过请求转发,request域中的数据依然存在,
则在请求转发的过程中通过request 来传输、共享数据

12.Cookie对象

@WebServlet("/") 这样配置时,不过滤(放行)jsp文件。只有jsp不进控制器(servlet),其他都      进
@WebServlet("/*") 过滤所有文件。

   (1.)Cookie 的创建和发送

     通过new Cookie(“key”,"value";来创建一个cookie 对象,要想要将Cookie 谁着响应发送到客户端,需要先添加到response 对象中,response.addCookie(cookie); 该时cookie 对象谁着响应发送到客服端,在浏览器上可以看见

    

//创建Cookie 对象
Cookie cookie = new Cookie("uname","zhangsan");
//发送Cookie 对象
response.addCookie(cookie);

 

 Cookie的获取

在服务器端只能提供一个getCookies() 的方法用来获取客户端回传的所有cookie 组成的一个数组,如果需要获取单个cookie 则需要通过遍历 ,getName() 来获取 Cookie 的名称 ,getValue() 获取Cookie的值。

//获取Cookie 的数组
Cookie[] cookies = request.getCookies();
//判断数组是不是为空
if(Cookie != null && cookies){
    //循环遍历Cookie 数组
     for(Cookie cookie : cookies){
      System.out.println(cookie.getName());
      System.out.println(cookie.getName());
    }
}

Cookie 到期的时间

   除了Cookie 的名称和内容外,我们还需要关系一个信息,到期的时间,到期时间用来指定cookie什么时候失效,默认为了当前浏览器关闭就失效,我们可以手动设置cookie的有效时间(通过到期的时间计算),通过setMaxAge(inttime);方法设定cookie 的最大有效时间,以秒为单位。

到期时间

     * 负整数

            如果为负数,表示不存放改cookie 。cookie的maxAge 的属性默认值计算-1,表示只能在浏览器中存活,一旦关闭浏览器,就算重新启动客户端电脑,cookie也会存活相应的时间

    *零

          如果为0,表示删除改cookie

          cookie 生命等于0 是一个特殊的值,他表示cookie 被作废,也就是说如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

Cookie的注意点:

    1.cookie保存在当前浏览器中,

         有一般的站点中常常有记住,用户名这样的操作,该操作只是保存在本机上面,然后换上电脑这些信息就没有用了,而且cookie还不能跨浏览器。

  2.Cookie存在中文问题

      Cookie中不能出现中文的问题

         Cookie 中不能出现中文,如果有中文则通过URLEcoder.encode() 来进行编码,获取则通过URLDecoder.decode()来进行编码

    

String name = "姓名";
String value = "张山";
//通过URLEncoder.encode(name);
value  = URLEncoder.encode(name):
value = URLEncoder.encode(value);
//创建cookie 对象
Cookie cookie = new Cookie(name,value);
//发送cookie对象
response.addCookie(cookie);

//获取的时候通过URLDecoder.decode()来进行编码
URLDecoder.decode(cookie.getName());
URLDecoder.decode(cookie.getValue());

3. 同名Cookie问题 如果服务器端发送重复的Cookie那么会覆盖原有的Cookie。

4. 浏览器存放Cookie的数量 不同的浏览器对Cookie也有限定,Cookie的存储有是上限的。Cookie是存储在客户端(浏览器)的,而且一般 是由服务器端创建和设定。后期结合Session来实现回话跟踪。

Cookie的路径:

  

 情景二: 当前项目下的资源可获取Cookie对象 (默认不设置cookie的path)

   /* 当前路径为 s01*/

  Cookie cookie = new Cookie("xxx","xxx");

  //设置路径为:s01表示当前目录下的任何项目都可以访问到Cookie 对象

  cookie。setPath("/s01"); //默认情况,可以不设置path的值

    response.addCookie()cookie;

情景三: 指定项目下的资源可以获取Cookie 对象

     /* 当前项目的资源可以获取Cookie 对象*/

Cookie cookie = new Cookie( "xxx","xxx");

cookie.setPath("/s02"); //只能在s02的项目下才可以访问到Cookie 对象 

response.addCokie(cookie);

 情景四: 指定目录下的资源可以获取Cookie 对象

/* 当前项目 的路径为 s01 */

Cookie cookie = new Cookie("xxx","xxx");

//设置路径为"/s01/cook" 表示s02/cook 目录下才可以访问到 Cookie 对象

cookie.setPath("/s01/cook");

response.addCookie(cookie);

cookie的路径指的是可以访问该cookie的顶层目录,该路径的子路径也可以访问该cookie。

总结:当访问的路径包含了cookie的路径时,则该请求将带上该cookie;如果访问路径不包含cookie路径,则该请 求不会携带该cookie。

13.HttpSession对象


 

     HttpSession对象是javax.servlet.http.HttpSession的实例,该接口并不像 HttpServletRequest或
HttpServletResponse还存在一个父接口,该接口只是一个纯粹的接口。这因为session本身就属于HTTP协议的范畴。
      对于服务器而言,每一个连接到它的客户端都是一个session,servlet容器使用此接口创建HTTP客户端和HTTP服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个session中,最重要的就是属性的操作。 

Session 的作用:

     为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数 据。我们可以通过 request.getSession()方法,来获取当前会话的 session 对象。

// 如果session对象存在,则获取;如果session对象不存在,则创建
HttpSession session = request.getSession();

标识符JSESSIONID

        Session既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是sessionld。
        每当一次请求到达服务器,如果开启了会话((访问了session),服务器第一步会查看是否从客户端回传一个名为JSESSIONID的cookie,如果没有则认为这是一次新的会话,会创建一个新的session对象,并用唯一的sessionld为此次会话做一个标志。如果有JESSIONID这个cookie回传,服务器则会根据]SESSIONID这个值去查看是否含有id为JSESSION值的session对象,如果没有则认为是一个新的会话,重新创建一个新的session对象,并标志此次会话;如果找到了相应的session对象,则认为是之前标志过的一次会话,返回该session对象,数据达到共享。

       这里提到一个叫做JSESSIONID的cookie,这是一个比较特殊的cookie,当用户请求服务器时,如果访问了session,则服务器会创建一个名为JSESSIONID,值为获取到的session(无论是获取到的还是新创建的)的sessionld的cookie对象,并添加到response对象中,响应给客户端,有效时间为关闭浏览器。
      所以Session的底层依赖Cookie来实现。

session 域对象

     Session 用来表示一次会话,在一次会话中数据是可以共享的,这时的session 作为域对象的存在,可以通过setAttribute(name,value)方向向域对象添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据。

// 获取session对象
HttpSession session = request.getSession();
// 设置session域对象
session.setAttribute("uname","admin");
// 获取指定名称的session域对象
String uname = (String) request.getAttribute("uname");
// 移除指定名称的session域对象
session.removeAttribute("uname");

数据存在session域对象中,当session 对象不存在了,或者是2个不同的session 对象 时,数据就不能共享了,这就不得不谈到session 的生命周期了。

session域对象 Session 用来表示一次会话

       在一次会话中数据是可以共享的,这时 session 作为域对象存在,可以通过 setAttribute(name,value) 方法向域对象中添加数据,通过 getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name) 从域对象中移除数据。

session对象的销毁 :

       默认时间到期 当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。 那么 session 的默认时间可以改么?答案是肯定的。 可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。

<wep-app>

    <!-- session 默认的最大不活动时间。单位:分钟。 -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

</web-app>

自己设定到期时间:      

     当然除了以上的修改方式外,我们也可以在程序中自己设定 session 的生命周期,通过 session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。

// 获取session对象 HttpSession session = request.getSession(); 
// 设置session的最大不活动时间 session.setMaxInactiveInterval(15); // 15秒 

当然我们也可以通过 getMaxInactiveInterval() 方法来查看当前 Session 对象的最大不活动时间

// 获取session的最大不活动时间 int time = session.getMaxInactiveInterval();

 ServletContext对象:

       每一个 web 应用都有且仅有一个ServletContext 对象,又称 Application 对象,从名称中可知,该对象是与应用程 序相关的。在 WEB 容器启动的时候,会为每一个 WEB 应用程序创建一个对应的 ServletContext 对象。 该对象有两大作用,第一、作为域对象用来共享数据,此时数据在整个应用程序中共享; 第二、该对象中保存了当 前应用程序相关信息。例如可以通过 getServerInfo() 方法获取当前服务器信息 ,getRealPath(String path) 获取资 源的真实路径等。

ServletContext对象的获取:

 获取 ServletContext 对象的途径有很多。比如:

1. 通过 request 对象获取

ServletContext servletContext = request.getServletContext();

//2. 通过 session 对象获取

    ServletContext servletContext = request.getSession().getServletContext();   

//3. 通过 servletConfig 对象获取,在 Servlet 标准中提供了 ServletConfig 方法

    ServletConfig servletConfig = getServletConfig();
    ServletContext servletContext = servletConfig.getServletContext();

//4. 直接获取,Servlet 类中提供了直接获取 ServletContext 对象的方法常用方法
   ServletContext servletContext = getServletContext();

常用方法: 

 //获取当前服务器的真实路径  如:F:\FirstServlet\out\artifacts\FirstServlet_war_exploded\

    String realPath = request.getServletContext().getRealPath("/");
    System.out.println(realPath);
      
  // 获取当前服务器的版本信息  如:Apache Tomcat/8.5.66

    String serverInfo = request.getServletContext().getServerInfo();
    System.out.println(serverInfo);

14.文件的上传:

   

//前端的代码

<!-- 
   文件上传表单
        1.表单提交类型 method = "post"
        2.表单类型 enctype = "multipart/form-data"
        3.表单的元素类型 文件域设置 name 的属性值
-->

    <!--设置表单为 上传文件 -->
    <!--默认情况下这个表单类型是  " application/x-www-form-date "  不能上传文件 只有 
         multipart/form-data才可以
     -->

  <form method="post" action="uploadServlet" enctype="multipart/from-date"> 

   姓名:<input type="text" name="uname"> <br>
   文件:<input type="text" name="myfile"> <br>
    <button type="submit"> 提交 </button>

  </form>

//后端的代码


package com.openhome;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;

/*
文件上传
使用注解@MultipartConfig将一个ServLet 标识为支持文件上传。
ServLet 将 muLtipart/form-data 的 POST 请求封装成Part对象,通过 Part对上传的文件进行操作。
* */


@WebServlet("/uploadServlert")
@MultipartConfig //如果是文件上传,就一定要加这个注解
public class UploadServlert extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("上传文件");
        // 1.设置请求编码的格式
        request.setCharacterEncoding("UTF-8");
        // 2. 获取普通表单像
        String uname = request.getParameter("uname");   // "uname" 代表的是文本框的name 属性值
        // 3.通过getPart 方法获取Part 对象 (name 代表的是页面的file 文件域的name 属性值)
        Part part = request.getPart("myfile");   // 参数的 name =“myfile”
        // 通过表单file控件(<input type="file" name="file">)的名字直接获取Par
        // 4.通过part 获取上传文件的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("文件存放路径的名称 "+fileName);
        // 5。获取上传文件需要存放的路径(得到项目的正时路径)
         String realpath = request.getServletContext().getRealPath("/");
        System.out.println(" 上传文件需要存放的路径 "+realpath);
        // 将文件上传到指定的位置
         part.write(realpath +"/"+ fileName);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}

 控制台显示:

上传文件
 文件存放路径 学生管理系统.txt
 上传文件需要存放的路径 F:\练习\FirstServlet\out\artifacts\FirstServlet_war_explode

然后文件是会被放到  F:\练习\FirstServlet\out\artifacts\FirstServlet_war_explode 这个文件夹里面去

15.文件的下载:

文件下载

文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性

来下载;第二种是通过代码下载。

超链接下载

当我们在 HTML JSP 页面中使用a标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的资源时会自

动下载;当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txtpngjpg 等。当然我们也可以通

download 属性规定浏览器进行下载。但有些浏览器并不支持。

默认下载

 指定的download属性下载

<!-- 当超链接遇到浏览器识别的资源时,默认不会下载,通过download 属性进行下载 -->
<a href="test.txt" download> 超链接下载 </a>

download 属性可以不写任何的信息,会自动使用默认的文件名,如果设置了 download 属性的值,则用设置的值为文件名。当用户打开浏览器点击链接的时候会直接下载文件。

后端代码:

实现步骤

 1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活

 某个程序来处理的 MIME 类型,例 "application/octet-stream" "application/x-msdownload" 等。

2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 "attachment;filename=文件名"

3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件传输</title>
</head>
<body>
   <form action="download">


       文件<input type="text" name="fileName" placeholder="请输入你要的文件">

       <button> 提交 </button>

   </form>

</body>
</html>


//后端代码

package com.openhome;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

@WebServlet("/download")
public class DownloadSerclet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("文件下载...");

        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");

        response.setContentType("text/html;charset=UTF-8");
        // 获取参数 (得到要下载的文件名)
        String fileName = request.getParameter("fileName");

        // 参数的非空判断  trim():去除字符串的前后空格
        if (fileName == null || "".equals(fileName.trim())) {
            response.getWriter().write("请输入要下载的文件名!");
            response.getWriter().close();
            return;
        }
        // 得到图片存放的路径
        String path = request.getServletContext().getRealPath("/download/");
        // 通过路径得到file对象
        System.out.println("通过路径得到file对象" + path);
        File file = new File(path + fileName);
        // 判断文件对象是否存在并且是一个标准文件
        if (file.exists() && file.isFile()) {
            // 设置响应类型 (浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型)
            response.setContentType("application/x-msdownload");
            // 设置响应头
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            // 得到file文件输入流
            InputStream in = new FileInputStream(file);
            // 得到字节输出流
            ServletOutputStream out = response.getOutputStream();
            // 定义byte数组
            byte[] bytes = new byte[1024];
            // 定义长度
            int len = 0;
            // 循环输出
            while ((len = in.read(bytes)) != -1){
                // 输出
                out.write(bytes,0,len);
            }
            // 关闭资源
            out.close();
            in.close();
        } else {
            response.getWriter().write("文件不存在,请重试!");
            response.getWriter().close();
        }

    }
}

16.Filter 过滤器

16.1  现有问题
    在以往的Servlet中,有没有冗余的代码,多个servlet都要进行编写。


16.2  概念
    过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。

16.3过滤器作用
      执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter,可以解决多个Servlet共性代码的冗余问题(例如:乱码处理、登录验证)


16.4编写过滤器
      Servlet API中提供了一个Filter接口,开发人员编写一个Java类实现了这个接口即可,这个Java类称之为过滤器(Filter)

16.5实现过程
     编写Java类实现Filter接口。                                                                                                              在doFilter方法中编写拦截逻辑。                                                                                                        设置拦截路径

    

16.7过滤器配置
16.8注解配置
         在自定义的Filter类上使用注解@WebFilter(value=“/过滤目标资源”)
 

xml设置

package com.avaliable;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.util.logging.LogRecord;

//需要拦截的资源
@WebFilter(value="/t")
public class Myfilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("myfilter");
        filterChain.doFilter(servletRequest,servletResponse); //返回 刚刚设置 T的目录
        System.out.println("------ end -----");  //成功打印end 
    }

    @Override
    public void destroy() {
        System.out.println("正在销毁。。。。");
    }
}

 

package com.avaliable;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name ="TargetServlet", value="/t")
public class TargetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           doPost(request,response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("-------/t targetServlet ");
    }
}

 16.9过滤器链和优先级
 16.9.1过滤器链
      客户端对服务器请求之后,服务器调用Sservlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
     每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用 FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

 

 

19.10.1过滤器优先级
    在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。优先级:
        1.如果为注解的话,是按照类全名称的字符串顺序决定作用顺序。   (字母顺序)                                                 2. 如果web.xml,按照filter-mapping注册顺序,从上往下
        3. web.xml配置高于注解方式。如果注解和web.xml同时配置,会创建多个过滤器对象,造成            过滤多次。

精确拦截 html 的请求 

package com.avaliable;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(value="*.html") // 拦截所有后缀为 HTML 的语句 (不显示)
public class HtmlFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截HTML的请求");
    }

    @Override
    public void destroy() {
        System.out.println("销毁---");
    }
}

 拦截所有请求

package com.avaliable;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/*
   也可以拦截 a/b/* 
  a目录下的b目录下的所有资源
*/

@WebFilter("/*") ///* 拦截所有请求
public class AllFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("/* 拦截所有请求  ");
    }

    @Override
    public void destroy() {
        System.out.println("销毁----------");
    }
}

实战:过滤器解决编码问题:

  前端



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>  过滤器的经典应用(解决乱码) </title>
</head>
<body>

  <form action="login" method ="post">
    用户名 :<input type="text" name = "username" >
    密  码 :<input type="text" name = "password">
    <input type="submit" value="登入">

  </form>

</body>
</html>



//后端1(过滤器 拦截所有)

package com.avaliable;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/*
   也可以拦截 a/b/*
  a目录下的b目录下的所有资源
*/

@WebFilter("/*") ///* 拦截所有请求
public class AllFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.setContentType("text/html;charset=utf-8");
        servletRequest.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse); // 转换
        System.out.println("/* 拦截所有请求  ");

    }

    @Override
    public void destroy() {
        System.out.println("销毁----------");
    }
}




//后端2(servlet 的后端编码)

package com.avaliable;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("username");
        String pass = request.getParameter("password");
        System.out.println(" 姓名 " + name + " " +pass);

        PrintWriter out = response.getWriter();
        out.write(" 性名 " + name+ "  密码 "+ pass );
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }
}


 

其他:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值