Servlet技术详解

Servlet教程

1、JAVAEE简介

在这里插入图片描述

2、Servlet简介

在这里插入图片描述

2.1 Servlet技术特点

在这里插入图片描述
在这里插入图片描述

2.2 Servlet在应用程序中的位置

在这里插入图片描述

3、服务器

3.1 JavaEE应用服务器(JavaEE Application Server)

在这里插入图片描述

3.2 Web容器(Web Server)

在这里插入图片描述

3.2.1 Tomcat的使用

3.2.1.1 Tomcat 安裝和配置

在这里插入图片描述

3.2.1.2 Tomcat 目录结构
3.2.1.2.1 bin

在这里插入图片描述

3.2.1.2.2 conf

在这里插入图片描述

3.2.1.2.3 lib

在这里插入图片描述

3.2.1.2.4 logs

在这里插入图片描述

3.2.1.2.5 temp

在这里插入图片描述

3.2.1.2.6 webapps

在这里插入图片描述

3.2.1.2.7 work

在这里插入图片描述

3.2.1.3 Tomcat 启动与关闭

在这里插入图片描述

3.2.1.3.1 Tomcat启动

在这里插入图片描述

3.2.1.3.2 Tomcat关闭
  • 方式一:
    在这里插入图片描述
  • 方式二:
    在这里插入图片描述
3.2.1.3.3 访问Tomcat

在这里插入图片描述

3.2.2 Tomcat 的配置

在这里插入图片描述

3.2.2.1 Tomcat 的配置文件介绍
3.2.2.1.1 context.xml

在这里插入图片描述

3.2.2.1.2 web.xml

在这里插入图片描述

3.2.2.1.3 server.xml

在这里插入图片描述

3.2.2.1.4 tomcat-users.xml

在这里插入图片描述

3.2.2.2 解决控制台乱码

在这里插入图片描述

3.2.2.3 修改Tomcat监听端口

在这里插入图片描述

3.2.2.4 配置Tomcat Manager

在这里插入图片描述

3.2.2.4.1 配置Tomcat Manger 的访问用户

在这里插入图片描述

  • manager-gui 角色
    在这里插入图片描述
  • manager-script 角色
    在这里插入图片描述
  • manager-jmx 角色
    在这里插入图片描述
  • manager-status 角色
    在这里插入图片描述
  • conf\tomcat-users.xml 配置用户角色
    在这里插入图片描述

热部署:是在tomcat的启动情况下,进行部署

3.2.3 Tomcat工作原理

3.2.3.1 Tomcat 作用

在这里插入图片描述

3.2.3.2 Tomcat 运行原理

在这里插入图片描述

3.2.4 Tomcat架构

在这里插入图片描述

3.2.5 Tomcat组件

3.2.5.1 Server组件

在这里插入图片描述

3.2.5.2 Service组件

在这里插入图片描述

3.2.5.3 Connector组件

在这里插入图片描述

3.2.5.4 Engine组件

在这里插入图片描述

3.2.5.5 Host组件

在这里插入图片描述

3.2.5.6 Context组件

在这里插入图片描述

3.2.6 Tomcat处理请求过程

在这里插入图片描述

3.2.7 在Tomcat中配置虚拟主机(Host)

3.2.7.1 需求

在这里插入图片描述

3.2.7.2 创建页面

在这里插入图片描述

3.2.7.3 修改server.xml添加Host配置

在这里插入图片描述

3.2.7.4 添加Context配置

在这里插入图片描述

3.2.7.5 修改windows的Host文件

在这里插入图片描述

3.2.7.5.1 Host文件位置

在这里插入图片描述

3.2.7.5.2 修改内容

在这里插入图片描述

3.2.7.5.3 访问资源测试结果

4、Servlet技术

4.1 Servlet 版本

Servlet4.0、Tomcat9以上、JDK8以上

4.2 创建第一个Servlet案例

4.2.1 创建Servlet

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

public class HelloWorld extends HttpServlet{
    public void doGet(HttpServletRequest request, HttpServletResponse) throws ServletException,IOException{
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<HTML>");
        out.println("<HEAD><TITLE>AABB</TITLE></HEAD>")
        out.println("<BODY>");
        out.println("<font color=blue>Hello World</font>");
        out.println("</BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }
}

4.2.2 编译Servlet

  • 在编译的时候,需要在tomcat的libservlet-api.jar下编译,是由于引入了servlet-api的包,这样才能编译通过
    在这里插入图片描述

4.2.3 创建web.xml

在这里插入图片描述

4.2.3.1 web.xml文件中的头信息

在这里插入图片描述

4.2.3.2 web.xml文件中配置Servlet
<?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>helloworld</servlet-name>
    <!-- servlet全名 -->
		<servlet-class>com.test.servlet.HelloWorld</servlet-class>
	</servlet>
  <!-- 与Servlet映射 -->
  <servlet-mapping>
    <servlet-name>helloworld</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>	

4.2.4 部署Servlet

4.2.4.1 Web工程目录结构

在这里插入图片描述

4.2.4.2 访问servlet与测试结果

在这里插入图片描述

4.3 Servlet继承结构

在这里插入图片描述

4.3.1 Servlet接口

在这里插入图片描述

4.3.2 ServletConfig接口

在这里插入图片描述

4.3.3 GenericServlet抽象类

在这里插入图片描述

4.3.4 HttpServlet

在这里插入图片描述

4.4 Servlet的生命周期

在这里插入图片描述

4.5 Servlet处理请求的原理

在这里插入图片描述

4.6 Servlet的使用

在这里插入图片描述

4.7 Idea中开发Servlet

4.7.1 创建Web工程

4.7.1.1 创建java项目

在这里插入图片描述

4.7.1.2 创建web工程

在这里插入图片描述
在这里插入图片描述

4.7.1.3 web工程目录结构
  • servlet-api.jar在tomcat的lib目录中
  • idea:File---->Project Structure---->Libraries---->+---->Java---->选择tomcat的lib下的servlet-api.jar导入即可
    在这里插入图片描述
4.7.1.4 配置Tomcat

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.7.2 Web项目部署

在这里插入图片描述
在这里插入图片描述

4.7.2.1 默认部署方式

在这里插入图片描述

  • idea会在CATALINA_BASE的路径下创建一个独立的Tomcat副本
    在这里插入图片描述

  • 会在…\tomcat\11e7605d-34df-4b7b-82f2-b2790096ea5c\conf\Catalina\localhost目录中生成一个改项目的xml文件名称为:“项目名.xml”

  • 在xml文件中指定web项目编译后的artifacts目录的位置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.7.2.2 web项目部署到Tomcat的webapps中
  • idea:File---->Project Structure---->Artifacts---->Output directory在这里插入图片描述
    在这里插入图片描述

4.8 HttpServletRequest对象

在这里插入图片描述

4.8.1 获取请求信息

在这里插入图片描述

4.8.2 获取请求数据

4.8.2.1 在Servlet获取请求数据的方式

在这里插入图片描述

4.8.2.2 获取复选框(checkbox组件)中的值

在这里插入图片描述

4.8.2.3 获取所有提交数据的 key

在这里插入图片描述

4.8.2.4 使用 Map 结构获取提交数据

在这里插入图片描述

4.8.3 设置请求编码

在这里插入图片描述

4.8.4 资源访问方式

4.8.4.1 绝对路径

在这里插入图片描述

4.8.4.2 相对路径

在这里插入图片描述

  • 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>demoServlet</servlet-name>
        <servlet-class>com.test.servlet.DemoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demoServlet</servlet-name>
        <url-pattern>/demo.do</url-pattern>
    </servlet-mapping>
</web-app>
  • index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello Servlet</title>
    </head>
    <body>
        <!--action="demo.do" 跟的是相对路径  action="/demo.do" 跟的是绝对路径-->
        <form action="demo.do" method="post">
            用户名:<input type="text" name="username">
            <input type="submit" value="ok">
            用户爱好:<input type="checkbox" name="userlike" value="sport">体育
                    <input type="checkbox" name="userlike" value="music">音乐
        </form>
    </body>
</html>
  • 类DemoServlet
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;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class DemoServlet extends HttpServlet {
    // 获取请求信息
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        // 获取请求信息
        StringBuffer requestURL = req.getRequestURL();
        String requestURI = req.getRequestURI();
        String remoteAddr = req.getRemoteAddr();
        out.println("URL:" + requestURL + "\t" + "URI:" + requestURI + "\t" + "remoteAddr:" + remoteAddr);
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }

   // 获取请求数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        req.setCharacterEncoding("utf-8"); // 让请求对象解析出来的结果重新按照新的编码方式解析,只解决请求的中文乱码问题,但响应的乱码问题依然存在
        // 获取请求数据
        String username = req.getParameter("username");
//        username = new String(username.getBytes("iso-8859-1"),"utf-8"); // 只解决了控制台打印的中文乱码问题,但响应中文乱码未解决
        System.out.println(username);
        out.println("username:" + username + "<br>");
        //  获取复选框(checkbox组件)中的值
        String[] userlikes = req.getParameterValues("userlike");
        List<String> strings = Arrays.asList(userlikes);
        out.println("username:" + strings + "<br>");
        // 获取所有提交数据的 key
        Enumeration<String> parameterNames = req.getParameterNames();
        List<String> keys = new ArrayList<>();
        while (parameterNames.hasMoreElements()) {
            keys.add(parameterNames.nextElement());
        }
        out.println("keys:" + keys + "<br>");
        // 使用 Map 结构获取提交数据
        Map<String, String[]> parameterMap = req.getParameterMap();
        Iterator<Map.Entry<String, String[]>> iterator = parameterMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String[]> entry = iterator.next();
            out.println("keys:" + entry.getKey() + " values:" + Arrays.asList(entry.getValue()));
        }
        // 获取请求头
        String header = req.getHeader("Accept-Language");
        // 获取请求头中所有的key,该方法返回乜距类型
        Enumeration<String> headerNames = req.getHeaderNames();
        out.println("Header:" + header + "<br>");
        // 获取请求头Accept-Language的值,可做语言识别
        if (header.indexOf("zh-CN") != -1) {
            out.println("您好!!!");
        } else if (header.indexOf("en-US") != -1) {
            out.println("Hello");
        } else {
            out.println("sorry");
        }
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = req.getHeader(key);
            out.println("key:" + key + " value:" + value + "<br>");
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

4.8.5 获取请求头信息

在这里插入图片描述

4.8.6 HttpServletRequest 对象的生命周期

在这里插入图片描述

4.8 HttpServletResponse 对象

在这里插入图片描述

4.8.1 设置响应类型

在这里插入图片描述

4.8.1.1 设置字符型响应

在这里插入图片描述

4.8.1.2 设置字节型响应

在这里插入图片描述

4.8.2 设置响应编码

在这里插入图片描述

  • 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>respCharacterServlet</servlet-name>
        <servlet-class>com.test.servlet.RespCharacterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>respCharacterServlet</servlet-name>
        <url-pattern>/char.do</url-pattern>
    </servlet-mapping>
</web-app>
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class RespCharacterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // =====================字符响应类型===============================
        // 默认的响应类型"text/html"
        // 设置普通文本响应类型
        // 给响应头设置字符编码,客户端/服务端的字符编码都设置了,解决乱码更彻底一些
        resp.setContentType("text/plain;charset=utf-8");
        // 设置字符编码
//        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("您好!!!");
        out.println("<body>");
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
        // =====================字节响应类型===============================
        // 读取图片文件
//        File file = new File("C:\\img\\1.png");
//        FileInputStream fis = new FileInputStream(file);
//        byte[] buf = new byte[fis.available()];
//        fis.read(buf);
//        // 设置响应类型
//        resp.setContentType("image/png");
//        // HttpServletResponse对象中获取字节输出流对象
//        OutputStream os = resp.getOutputStream();
//        os.write(buf);
//        os.flush();
//        os.close();
//        fis.close();
    }
}

4.8.3 在响应中添加附加信息

4.8.3.1 重定向响应

在这里插入图片描述

4.8.3.2 文件下载

在这里插入图片描述

4.8.3.3 解决文件名中文乱码问题

在这里插入图片描述

4.9 ServletContext对象

在这里插入图片描述

4.9.1 ServletContext 对象的作用

在这里插入图片描述

4.9.2 ServletContext 对象的使用

4.9.2.1 相对路径转绝对路径

在这里插入图片描述

4.9.2.2 获取容器的附加信息

在这里插入图片描述

4.9.2.3 获取 web.xml 文件中的信息

在这里插入图片描述

4.9.2.4 全局容器

在这里插入图片描述

4.9.3 ServletContext 对象生命周期

在这里插入图片描述

4.10 ServletConfig 对象

在这里插入图片描述

  • 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">
    <context-param>
        <param-name>key1</param-name>
        <param-value>AAA1</param-value>
    </context-param>
    <context-param>
        <param-name>key2</param-name>
        <param-value>AAA2</param-value>
    </context-param>
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.test.servlet.TestServlet</servlet-class>
        <init-param>
            <param-name>servletConfig_key1</param-name>
            <param-value>servletConfig_AAA1</param-value>
        </init-param>
        <init-param>
            <param-name>servletConfig_key2</param-name>
            <param-value>servletConfig_AAA2</param-value>
            <init-param>
            <param-name>path</param-name>
            <param-value>image</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/servlet.do</url-pattern>
    </servlet-mapping>
</web-app>
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * 自启动Servlet
 */
public class AutoStartServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        ServletConfig servletConfig = this.getServletConfig();
        String value = servletConfig.getInitParameter("path");
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("path",value);
    }
}
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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;
import java.util.Enumeration;

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 重定向响应
         */
//        req.setCharacterEncoding("utf-8");
//        String search = req.getParameter("search");
//        // 在URL(地址栏)需要对中文进行编码处理
//        resp.sendRedirect("https://www.baidu.com/s?wd="+ URLEncoder.encode(search, "utf-8")/*中文字符做编码处理*/);
        /**
         *  文件下载
         */
        // 获取ServletContext对象
//        ServletContext servletContext = this.getServletContext();
//		  String path = servletContext.getAttribute("path")	
//        // 路径转换
//        String realPath = servletContext.getRealPath(path + "/1.png");
//        System.out.println(realPath);
//        // 读文件
        File file = new File("c:/img/你好.png");
//        File file = new File(realPath);
//        System.out.println(file.getName());
//        FileInputStream fis = new FileInputStream(file);
//        byte[] buf = new byte[fis.available()];
//        fis.read(buf);
//
//        // 在响应头添加附加信息
//        // 文件名是中文,需要做字符编码处理
//        resp.addHeader("Content-Disposition","attachment;filename=" + new String(file.getName().getBytes("utf-8"),"iso-8859-1"));
//        OutputStream os = resp.getOutputStream();
//        os.write(buf);
//        os.flush();
//        os.close();
        /**
         *  获取容器的附加信息
         */
        // 获取ServletContext对象
//        ServletContext servletContext = this.getServletContext();
//        // 设置响应的字符编码
//        resp.setContentType("text/html;charset=utf-8");
//        // 获取Servlet容器的名称和版本号
//        String servletInfo = servletContext.getServerInfo();
//        int majorVersion = servletContext.getMajorVersion();
//        int minorVersion = servletContext.getMinorVersion();
//        PrintWriter out = resp.getWriter();
//        out.println("<!DOCTYPE html>");
//        out.println("<html lang=\"en\">");
//        out.println("<head>");
//        out.println("<title>Hello Servlet</title>");
//        out.println("</head>");
//        out.println("<body>");
//        out.println("Servlet容器的名称和版本: " + servletInfo  + "\nServlet的主版本:" + majorVersion + "\nServlet的副版本" + minorVersion);
//        out.println("</body>");
//        out.println("</html>");
//        out.flush();
//        out.close();
        /**
         * ServletContext对象读取web.xml文件中的信息
         */
        // 设置响应的字符编码
//        resp.setContentType("text/html;charset=utf-8");
//        // 获取ServletContext对象
//        ServletContext servletContext = this.getServletContext();
//        Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
//        PrintWriter out = resp.getWriter();
//        out.println("<!DOCTYPE html>");
//        out.println("<html lang=\"en\">");
//        out.println("<head>");
//        out.println("<title>Hello Servlet</title>");
//        out.println("</head>");
//        out.println("<body>");
//        while (initParameterNames.hasMoreElements()) {
//            String name = initParameterNames.nextElement();
//            out.println("获取context-param中的name:" + name + " value:" + servletContext.getInitParameter(name));
//        }
//        out.println("</body>");
//        out.println("</html>");
//        out.flush();
//        out.close();
        /**
         * 全局容器
         */
        // 获取ServletContext对象
//        ServletContext servletContext = this.getServletContext();
//        servletContext.setAttribute("key1","BBB1");
//        servletContext.setAttribute("key2","BBB2");
//        PrintWriter out = resp.getWriter();
//        out.println("<!DOCTYPE html>");
//        out.println("<html lang=\"en\">");
//        out.println("<head>");
//        out.println("<title>Hello Servlet</title>");
//        out.println("</head>");
//        out.println("<body>");
//        String value1 = (String)servletContext.getAttribute("key1");
//        String value2 = (String)servletContext.getAttribute("key2");
//        out.println("value1:" + value1 + "<br>" +"value2:" + value2);
//        out.println("</body>");
//        out.println("</html>");
//        out.flush();
//        out.close();
        // 获取ServletConfig对象
        ServletConfig servletConfig = this.getServletConfig();
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        while (initParameterNames.hasMoreElements()) {
            String name = initParameterNames.nextElement();
            out.println("name:" + name + "<br>" + "value:" + servletConfig.getInitParameter(name)+ "<br>");
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

5、Cookie 对象与 HttpSession 对象

在这里插入图片描述

5.1 Cookie 对象

5.1.1 Cookie 对象的特点

在这里插入图片描述

5.1.2 Cookie 对象的创建

在这里插入图片描述

5.1.3 获取 Cookie 中的数据

在这里插入图片描述

5.1.4 解决 Cookie 不支持中文

在这里插入图片描述

5.1.5 Cookie跨域问题

在这里插入图片描述

5.1.6 状态 Cookie 与持久化 Cookie

在这里插入图片描述

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建Cookie对象
//        Cookie cookie = new Cookie("name", "hello");
//        resp.addCookie(cookie);
        // 创建Cookie对象
        // Servlet4.0之前的版本是不支持的中文,需要对中文做编码处理
        Cookie cookie = new Cookie("name",URLEncoder.encode("你好","utf-8"));
        // 设置Cookie的失效时间,一旦设置了失效时间,该Cookie就持久化了
        cookie.setMaxAge(60);
        resp.addCookie(cookie);
        // 由于Cookie有中文,需要对字符进行编码处理
        resp.setContentType("text/html;charset=utf-8");
        // 获取Cookie对象
        Cookie[] cookies = req.getCookies();
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        for (int i = 0; i < cookies.length; i++) {
            Cookie cookiee = cookies[i];
            // Servlet4.0之前版本是不支持中文,需要对字符做解码处理
            out.println("name:" + cookiee.getName() + "<br>" + "value:" + URLDecoder.decode(cookiee.getValue(),"utf-8") + "<br>");
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

5.1.7 通过 Cookie 实现客户端与服务端会话的维持

在这里插入图片描述

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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 TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取Cookie
        Cookie[] cookies = req.getCookies();
        boolean flag = false;
        if (cookies != null) {
            for (Cookie cookie:cookies) {
                if ("first".equals(cookie.getName())) {
                    flag = true;
                }
            }
        }
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        if (flag) {
            // flag: true 表示第二次访问
            out.print("欢迎您回来!");
        } else {
            // flag: false 表示第一次访问,创建Cookie
            out.print("您好,欢迎您第一次访问!");
            Cookie cookie = new Cookie("first","first");
            cookie.setMaxAge(60);
            resp.addCookie(cookie);
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

5.1.8 Cookie 总结

在这里插入图片描述

5.2 HttpSession 对象

5.2.1 HttpSession 对象的特点

在这里插入图片描述

5.2.2 HttpSession 对象的使用

5.2.2.1 HttpSession 对象的创建

在这里插入图片描述

5.2.2.2 获取 HttpSession 中的数据

在这里插入图片描述

5.2.2.3 HttpSession 的销毁方式

在这里插入图片描述

5.2.2.4 通过 HttpSession 实现客户端与服务端会话的维持

在这里插入图片描述

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 使用HttpSession对象维持客户端与服务端的会话状态
 */
public class WelcomeSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        boolean flag = true;
        if (session == null) {
            flag = false;
            session = req.getSession(true);
        }
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        if (flag) {
            out.print("欢迎您回来!");
        } else {
            out.print("您好,欢迎您第一次访问!");
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}
5.2.2.5 HttpSession 生命周期

在这里插入图片描述

5.2.2.6 HttpSession 对象总结
5.2.2.6.1 HttpSession 与 Cookie 的区别

在这里插入图片描述

5.2.2.6.2 HttpSession 的使用建议

在这里插入图片描述

5.2.2.6.3 HttpSession 与 Cookie 的总结
  • cookie是由服务器端创建(new Cookie()),存储在客户端浏览器上的文件,用来跟踪客户端和服务器之间的会话,cookie的安全性能较低,并且存储的最大数据不能超过4k。
  • 不支持跨一级域名访问,但是可以跨二级域名访问。
  • 分为状态cookie和持久化cookie,
  • 状态cookie会在用户关闭浏览器时自动销毁。
  • 持久化cookie存储在用户硬盘中,设置的失效时间,到达时间后,系统会自动删除该文件,导致持久化cookie失效。
  • session时在服务器创建并存储在服务器上的,创建时间取决于我们什么时候调用getSession()或getSession(true)方法。安全性能较高。
  • 原则上session的存储大小不受限制,但是因为会占用服务器内存,如果session数量级过大,对服务器性能有影响。
  • session的销毁形式有两种,调用invalidate()方法和设置失效时间,
  • cookie和session的关系:
    session对象创建后,会生成一个sessionID放到cookie中,客户端每次向服务器端发出请求时,会把所有的请求信息和sessionID放到cookies中发送到服务器端,服务器端通过解析cookie对象,如果包含sessionID,服务器端会将和sessionID向对应的session取出。如果没有对应的session ID,服务器端会重新创建一个session对象。因为cookie记录着sessionID,如果cookie被销毁,服务器端对应的session将失效。因为cookie中的sessioID被销毁,客户端下次请求时就不再是之前的sessionID,而服务器端存储的仍然是之前的sessionID及session信息,所以无法找到相对应的session文件。

6、自启动 Servlet

在这里插入图片描述

  • 必须是整数,整数越小,自启动的优先级越高

7、Servlet 线程安全问题

在这里插入图片描述

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;

/**
 * Servlet线程安全问题
 */
public class ThreadSafeServlet extends HttpServlet {
    // 定义成员变量,会造成线程安全问题
    private PrintWriter pw;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        // 加锁解决了线程安全,因此两个不同浏览器都会有结果返回
        synchronized (this) {
            pw = resp.getWriter();
            try{
                Thread.sleep(5000);
                pw.println(name);
                pw.flush();
                pw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

8、Servlet 的 url-pattern 配置

8.1 URL 的匹配规则

8.1.1 精确匹配

在这里插入图片描述

8.1.2 扩展名匹配

在这里插入图片描述

8.1.3 路径匹配

在这里插入图片描述

8.1.4 任意匹配

在这里插入图片描述

8.1.5 优先顺序

在这里插入图片描述
在这里插入图片描述

8.2 URL 映射方式

在这里插入图片描述

8.2.1 方式一

在这里插入图片描述

8.2.2 方式二

在这里插入图片描述

9、基于注解式开发 Servlet

在这里插入图片描述

9.1 @WebServlet 注解中属性

在这里插入图片描述

9.2 @WebInitParam 注解中的属性

在这里插入图片描述

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

@WebServlet(urlPatterns = "/initParam.do", initParams = {@WebInitParam(name="key1", value = "value1"), @WebInitParam(name = "key2", value = "value2")}, loadOnStartup = 1)
public class AnnotationServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        ServletConfig servletConfig = this.getServletConfig();
        System.out.println(servletConfig.getInitParameter("key1"));
        System.out.println(servletConfig.getInitParameter("key2"));
    }

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig servletConfig = this.getServletConfig();
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("value1:" + servletConfig.getInitParameter("key1"));
        out.println("value2:" + servletConfig.getInitParameter("key2"));
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

10、文件上传

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import javax.servlet.ServletContext;
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;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.UUID;

@WebServlet("/fileupload.do")
@MultipartConfig
public class FileUploadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 中文字符做编码处理
        req.setCharacterEncoding("utf-8");
        String desc = req.getParameter("desc");
        Part part = req.getPart("file");
        // 获取文件上传的字节流
//        InputStream inputStream = part.getInputStream();
        // 给文件改名
        String fileName = UUID.randomUUID().toString() +  part.getSubmittedFileName().substring(part.getSubmittedFileName().indexOf("."))/*文件的后缀名*/; // getSubmittedFileName()获取原始的文件名
        // 路径转换
        ServletContext servletContext = this.getServletContext();
        String path = servletContext.getRealPath("image/" + fileName);
        part.write(path); // 文件上传
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>");
        out.println("<title>Hello Servlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("上传成功!!!" + desc);
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}

11、Filter 过滤器

在这里插入图片描述

11.1 过滤器作用

在这里插入图片描述

11.2 Filter 的使用

11.2.1 Filter 对象的创建

在这里插入图片描述

11.2.2 FilterConfig 对象的使用

在这里插入图片描述

<?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">
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>com.test.testfilter.EncodingFilter</filter-class>
        <init-param>
            <param-name>code</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
import javax.servlet.*;
import java.io.IOException;

/**
 * 处理请求编码Filter
 */
public class EncodingFilter implements Filter {
    private String encode;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String code = filterConfig.getInitParameter("code");
        this.encode = code;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        if (this.encode == null) {
            servletRequest.setCharacterEncoding("utf-8");
        } else {
            servletRequest.setCharacterEncoding(this.encode);
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

11.3 FilterChain(过滤器链)

在这里插入图片描述

11.4 Filter 的生命周期

在这里插入图片描述

11.5 基于注解式开发 Filter

在这里插入图片描述

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

@WebFilter(urlPatterns = {"/*","/filter/*"}, initParams = {@WebInitParam(name = "name1", value = "filter1")})
public class AnnotationFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Annotaion Filter.....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

12、Listener监听器

在这里插入图片描述

12.1 监听器分类

在这里插入图片描述

12.2 ServletContext 监听器

12.2.1 ServletContext 对象的生命周期监听器

在这里插入图片描述

12.2.2 ServletContext 对象的属性操作监听器

在这里插入图片描述

12.3 HttpSession 监听器

12.3.1 HttpSession 对象的生命周期监听器

在这里插入图片描述

12.3.2 HttpSession 对象的属性操作监听器

在这里插入图片描述

12.4 HttpServletRequest 监听器

12.4.1 HttpServletRequest 对象的生命周期监听器

在这里插入图片描述

12.4.2 HttpServletRequest 对象的属性操作监听器

在这里插入图片描述

12.5 基于注解式开发监听器

在这里插入图片描述

13、Filter 与 Listener 设计模式

13.1 Filter 的设计模式

在这里插入图片描述

13.1.1 责任链模式特点

在这里插入图片描述

13.1.2 责任链的优缺点

在这里插入图片描述

13.2 Listener 的设计模式

在这里插入图片描述

13.2.1 观察者模式的特点

在这里插入图片描述

13.2.2 观察者模式的优缺点

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值