Servlet

Servlet

1. Servlet 的三种创建方式
1.1 Servlet 程序基本架构
interface javax.servlet.Servlet 接口
	整个 Java WEB 程序中,所有 Servlet 程序总接口,规范了 Servlet 必须完成的方法有哪些

abstract class javax.servlet.GenericServlet implement Servlet
	其中完成的一些必要的方法,同时保留部分 abstract 修饰的抽象方法

abstract class javax.servlet.HttpServlet extends GenericServlet
	其中没有任何一个抽象方法
1.2 Servlet 接口中的方法
// 初始化当前 Servlet 程序/ Servlet 对象。方法参数为 ServletConfig Servlet 配置对象。
public void init(ServletConfig config);

// 获取 ServletConfig Servlet 配置对象
public ServletConfig getServletConfig();

// 【核心方法】Servlet 程序提供 WEB 服务核心方法,方法参数是用户请求 ServletRequest 和 对应响应 
// ServletResponse
public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;

// 获取 Servlet 字符串信息描述【鸡肋】
public String getServletInfo();

// Servlet 程序销毁操作,Tomcat 服务器在退出时,会将整个 Tomcat 服务器中的所有注册资源逐一 destroy
public void destroy();
1.3 遵从 Servlet 接口实现 Servlet 程序
package com.qfedu.a_createServlet ;

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

/**
 * @author Anonymous 2022/6/9 9:58
 */
@WebServlet("/servletImpl")
public class ServletImpl implements Servlet {
    public ServletImpl() {
        System.out.println("ServletImpl 无参数构造方法执行...");
    }

    // 初始化当前 Servlet 程序/ Servlet 对象。方法参数为 ServletConfig Servlet 配置对象。
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init 初始化方法执行...");
    }

    // 获取 ServletConfig Servlet 配置对象
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    // 【核心方法】Servlet 程序提供 WEB 服务核心方法,方法参数是用户请求 ServletRequest 和 对应响应
    // ServletResponse
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("Service 方法执行...");
        res.getWriter().append("<h1>Service Method Running....</h1>");
    }

    // 获取 Servlet 字符串信息描述【鸡肋】
    @Override
    public String getServletInfo() {
        return null;
    }

    // Servlet 程序销毁操作,Tomcat 服务器在退出时,会将整个 Tomcat 服务器中的所有注册资源逐一 destroy
    @Override
    public void destroy() {
        System.out.println("destroy 销毁方法执行...");
    }
}

1.4 继承 GenericServlet 实现 Servlet 程序
package com.qfedu.a_createServlet;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

/**
 * 继承 GenericServlet 有且只需要实现 service 其他与业务逻辑无关的方法,无需考虑,无需完成。
 * 降低了程序员开发压力,同时给予后期的业务实现,提供必要的自由度。
 * @author Anonymous 2022/6/9 10:07
 */
@WebServlet("/extendsGeneric")
public class ExtendsGenericServlet extends GenericServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        res.getWriter().append("<h1>ExtendsGenericServlet service running...</h1>");
    }
}
1.5 继承 HttpServlet 实现 Servlet 程序
package com.qfedu.a_createServlet;

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;

/**
 * 继承 HttpServlet 完成 Servlet 程序
 * 在 HttpServlet 中没有任何一个 abstract 修饰的抽象方法
 *
 * HttpServlet 类内自定义 service(HttpServletRequest request, HttpServletResponse response);
 * 在针对于用户请求方式进行了解析和分发操作
 * 用户请求
 *      GET ==> doGet(HttpServletRequest request, HttpServletResponse response)
 *      POST ==> doPost(HttpServletRequest request, HttpServletResponse response)
 *      并且在 doGet 和 doPost 要求程序员必须重写,如果没有重写 405 Method Not Allowed
 *
 * @author Anonymous 2022/6/9 10:27
 */
@WebServlet("/extendsHttpServlet")
public class ExtendsHttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().append("<h1>Extends HttpServlet to Create Servlet Program</h1>");
    }

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

1.6 三种方式对比
1. 遵从 Servlet 接口
	需要完成的方法很多,而且大部分方法和业务逻辑无关,并且存在操作的重复性。
2. 继承 GenericServlet 抽象类
	有且只需要实现 service 核心方法,其他与业务逻辑无关的功能,不需要实现,简化的实现过程,同时留给后期实现业务的自由度,方便后期拓展【承上启下】
3. 继承 HttpServlet 抽象类
	明确的协议类型 HTTP 协议。在满足 HTTP 协议的规范下完成 Servlet 程序,同时根据 HTTP 协议对请求方式完成对应方法处理的操作,在 HttpServlet 类内没有任何一个 抽象方法,但是使用 abstract 关键字修饰 HttpServlet 是为了保证执行任务目标的程序是程序员自行完成的程序。
	
4 BaseServlet 后期完成
2. Servlet 生命周期
2.1 涉及到的方法
1. Servlet 构造方法,而且一定是无参数构造方法。
2. init(ServletConfig config) Servlet 配置方法,在 Servlet 实例化之后,执行 service 功能之前,进行初始化操作
3. service 方法【核心方法】执行 Servlet 服务方法
4. destroy 销毁 Servlet 程序
实例化 --> 初始化 --> 服务(loop) --> 销毁
2.2 代码演示
package com.qfedu.b_lifecycle;

import javax.servlet.ServletConfig;
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;

/**
 * @author Anonymous 2022/6/9 11:11
 */
@WebServlet("/lifeCycle")
public class ServletLifeCycleServlet extends HttpServlet {
    // 无参数构造方法
    public ServletLifeCycleServlet() {
        System.out.println("----------------无参数构造方法,实例化当前 Servlet 程序----------------");
    }

    // 初始化方法
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 为了保证 Servlet 程序正常运行,保留 super 调用 GenericServlet 类内 init 方法形式
        super.init(config);
        System.out.println("----------------init 方法执行----------------");
    }

    // service 方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().append("<h1>我饿了</h1>");
    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("----------------servlet 程序销毁----------------");
    }
}
2.3 小总结
1. Servlet 程序可以认为是一个【单例模式】在整个 Tomcat 服务器中,资源名称匹配的 Servlet 程序有且只有一个,一旦创建初始化之后,后期只有唯一,提供 service 操作

2. Servlet 程序有且只有在被用户请求时才会被 Tomcat 服务器创建
	可以设置 Servlet 程序开机自启
3. Servlet 参数配置
3.1 Servlet 配置常用参数
主要参数
	1. 开机自启
	2. 初始化操作
其他参数:
	1. servlet 名称
	2. servlet 描述
3.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 程序相关参数信息 -->
    <servlet>
        <servlet-name>WebXMLConfigServlet</servlet-name>
        <servlet-class>com.qfedu.c_configServlet.WebXMLConfigServlet</servlet-class>
        <!-- init-param servlet 初始化参数 参数可以配置多个 -->
        <init-param>
            <!-- param-name 参数名称 -->
            <param-name>老黑</param-name>
            <!-- param-value 参数值 -->
            <param-value>人黑心不黑</param-value>
        </init-param>
        <init-param>
            <!-- param-name 参数名称 -->
            <param-name>Feri</param-name>
            <!-- param-value 参数值 -->
            <param-value>老邢上车油耗增加 0.2L/100KM</param-value>
        </init-param>
        <!-- load-on-startup Tomcat 启动对应 Servlet 程序同时启动 1 表示开机自启 0 默认值请求之后创建加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>WebXMLConfigServlet</servlet-name>
        <url-pattern>/webXml</url-pattern>
    </servlet-mapping>
</web-app>
package com.qfedu.c_configServlet;

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

/**
 * @author Anonymous 2022/6/9 11:32
 */
public class WebXMLConfigServlet extends HttpServlet {
    public WebXMLConfigServlet() {
        System.out.println("-------------WebXMLConfigServlet 构造方法-------------");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        /*
        Servlet 配置信息都在 ServletConfig 对象中,可以从 ServletConfig 对象中
        获取对应的配置参数
        通过参数名称获取对应参数值
         */
        String value1 = config.getInitParameter("老黑");
        String value2 = config.getInitParameter("Feri");
        System.out.println(value1);
        System.out.println(value2);
        System.out.println("-------------init 初始化操作-------------");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");

        ServletConfig servletConfig = getServletConfig();
        String value1 = servletConfig.getInitParameter("老黑");
        String value2 = servletConfig.getInitParameter("Feri");

        resp.getWriter().append("<h1>" + value1 + "</h1>");
        resp.getWriter().append("<h1>" + value2 + "</h1>");
        resp.getWriter().append("<h1>Servlet Config</h1>");
    }
}
3.3 注解方式
package com.qfedu.c_configServlet;

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;

/**
 * @author Anonymous 2022/6/9 14:54
 */
@WebServlet(
        value = {"/anno", "/webAnno"}, // url-pattern 资源注册名称,可以是多个
        loadOnStartup = 1, // 当前 Servlet 程序 Tomcat 服务器启动自启动
        initParams = {@WebInitParam(name = "大哥", value = "SingleDog"), @WebInitParam(name = "黑邢", value = "黑黝黑黑黑")}
        // initParams 初始化参数
)
public class WebServletAnnotationConfigServlet extends HttpServlet {
    public WebServletAnnotationConfigServlet() {
        System.out.println("----------------WebServletAnnotationConfigServlet Constructor----------------");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        String value1 = config.getInitParameter("大哥");
        String value2 = config.getInitParameter("黑邢");
        System.out.println(value1);
        System.out.println(value2);
        System.out.println("----------------init method----------------");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        ServletConfig servletConfig = getServletConfig();

        PrintWriter writer = resp.getWriter();
        writer.append("<h1>" + servletConfig.getInitParameter("大哥") + "</h1>");
        writer.append("<h1>" + servletConfig.getInitParameter("黑邢") + "</h1>");
    }
}
4. HTML页面提交数据到 Servlet
4.1 HTML 页面

JavaWEB 项目中 静态资源(HTML CSS JS img) 在 web 目录下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<!--
action
    提交数据的目标资源路径,可以提交到当前 JavaWEB Application 中的 Servlet 资源
    需要明确当前 Servlet 资源名称
Method:
    GET

-->
<form action="registerUser" method="POST">
   <span>名称:</span><input type="text" name="username"> <br>
   <span>密码:</span><input type="password" name="password"> <br>
    <input type="submit" value="提交">
</form>
</body>
</html>
4.2 RegisterUserServlet
package com.qfedu.d_operation;

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;
import java.nio.charset.StandardCharsets;

/**
 * @author Anonymous 2022/6/9 15:25
 */
@WebServlet("/registerUser")
public class RegisterUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username + ":" + password);
    }

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

4.3 乱码问题
Tomcat 8, 9
	1. GET 请求中文OK
	2. POST 请求中文乱码

Tomcat 7 
	1. GET 请求中文 GG思密达
	2. POST 请求中文 GG思密达	

Tomcat 8, 9 中文乱码解决方案
/*
修改请求编码集
HttpServletRequest setCharacterEncoding(String encoding);
*/
req.setCharacterEncoding("utf-8");
Tomcat 7 解决方案
提交数据默认编码集为 ISO-8859-1
	需要将所有提交数据全部重新编码 ==> UTF-8
	username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
响应乱码需要通过:
	/*
	HttpServletResponse 符合 Http 协议 Servlet 规范的响应类对象
	setContentType ==> 修改,设置响应头内容 Response Header Content-Type 响应头内容
 	*/
 	resp.setContentType("text/html;charset=utf-8");
// 目前需要在 Servlet 程序中加上
// 解决请求乱码
req.setCharacterEncoding("utf-8");
// 解决响应乱码
resp.setContentType("text/html;charset=utf-8");
5. 梦幻联动(Bug联动)
5.1 HTML => Servlet => MySQL

在这里插入图片描述

5.2 MySQL => Servlet => HTML

在这里插入图片描述

合 Http 协议 Servlet 规范的响应类对象
setContentType ==> 修改,设置响应头内容 Response Header Content-Type 响应头内容
*/
resp.setContentType(“text/html;charset=utf-8”);


```java
// 目前需要在 Servlet 程序中加上
// 解决请求乱码
req.setCharacterEncoding("utf-8");
// 解决响应乱码
resp.setContentType("text/html;charset=utf-8");
5. 梦幻联动(Bug联动)
5.1 HTML => Servlet => MySQL

[外链图片转存中…(img-QS7tLAUz-1654935041360)]

5.2 MySQL => Servlet => HTML

[外链图片转存中…(img-6LhF5ms4-1654935041364)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值