• Web服务连接器:Servlet


    概述

    Servlet(Server Applet)是Java Servlet的简称,称为服务器小程序或服务连接器。它是在服务器端运行的Java小程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据(即实现前后端的交互),生成动态Web内容。

    工作原理图

    在这里插入图片描述

    其中,Tomcat可以通过HTTP提供HTML页面等静态内容的请求访问;也实现了Servlet规范,可以运行Servlet程序;同时可以通过Servlet容器调用Servlet处理动态请求,所以Tomcat可以是Web服务器或Servlet容器或Web轻量级应用服务器。

    工作流程

    1)客户端(通常都是浏览器)访问Web服务器,发送HTTP请求。
    2)Web服务器接收到请求后,将请求传递给Servlet容器。
    3)Servlet容器解析请求,加载Servlet,同时Servlet容器分别创建一个HttpRequest对象和一个HttpResponse对象。HttpRequest对象将传递的请求信息封装起来。
    4)Servlet容器调用HttpServlet对象的service()方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet对象。HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息;调用HttpResponse对象的有关方法,生成响应数据。
    5)Servlet容器把HttpServlet的响应结果返回给Web服务器。

    Servlet的生命周期

    Servlet的生命周期是Servlet从启动到关闭的过程,如下:

    • 加载和实例化:如果Servlet容器还没实例化一个Servlet对象,此时容器装载和实例化一个 Servlet。如果已经存在一个Servlet对象,此时不再创建新实例。
    • 初始化:在产生 Servlet 实例后,容器负责调用该 Servlet 实例的 init() 方法,对Servlet 进行初始化。
    • 响应请求:当 Servlet 容器接收到一个 Servlet 请求时,便运行与之对应的 Servlet 实例的 service() 方法,service() 方法根据用户的请求调用相对应的doGet或doPost 方法来处理用户请求。然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。
    • 销毁:当Servlet在Web应用被卸载前执行,释放Servlet占用的计算机资源。
      注意:(1)(2)(4) 在Servlet的整个生命周期中只会被执行一次。

    代码如下,ServletLifeCycle.java:

    package com.edu.ServletStudy;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class ServletLifeCycle implements Servlet {
        public ServletLifeCycle() {
            //构造方法被调用,创建一个实例对象
            System.out.println("第一步:实例对象");
        }
    
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            //对servlet进行初始化,只执行一次
            System.out.println("第二步:初始化");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            //返回一个ServletConfig对象用来返回初始化参数和ServletContext
            return null;
        }
    
        @Override
        public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
            System.out.println("第三步:提供服务");
            //中文乱码解决
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
            //响应请求的信息
            HttpServletResponse res = (HttpServletResponse)response ;
            res.getWriter().write("Hello Servlet,我是啊Q老师");
        }
    
        @Override
        public String getServletInfo() {
            //提供有关servlet的信息
            return null;
        }
    
        @Override
        public void destroy() {
            System.out.println("销毁");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    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>ServletLifeCycle</servlet-name>
            <!--servlet类的全名-->
            <servlet-class>com.edu.ServletStudy.ServletLifeCycle</servlet-class>
        </servlet>
    
        <!--servlet映射配置-->
        <servlet-mapping>
            <!--servlet的内部名称,与上面的保持一致-->
            <servlet-name>ServletLifeCycle</servlet-name>
            <!--servlet的映射路径(地址一般是action里面的内容,获取数据请求)-->
            <url-pattern>/ServletLifeCycle</url-pattern>
        </servlet-mapping>
    </web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行如图:控制台

    在这里插入图片描述

    页面

    在这里插入图片描述

    当点击停止时,Servlet便会执行destroy()方法

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    ServletConfig对象

    ServletConfig对象的作用主要是配置servlet的初始化参数。具体的实现由Servlet容器开发商决定的。我们以Tomcat为例。

    代码如下,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>ServletLifeCycle</servlet-name>
            <servlet-class>com.edu.ServletStudy.ServletLifeCycle</servlet-class>
            <!--可以用一个或多个<init-param>标签配置本Servlet的初始化参数-->
            <init-param>
                <!--键-->
                <param-name>username</param-name>
                <!--值-->
                <param-value>啊Q老师</param-value>
            </init-param>
            <init-param>
                <param-name>pwd</param-name>
                <param-value>123</param-value>
            </init-param>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>ServletLifeCycle</servlet-name>
            <url-pattern>/ServletLifeCycle</url-pattern>
        </servlet-mapping>
    </web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    ServletLifeCycle.java:

    package com.edu.ServletStudy;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Enumeration;
    
    public class ServletLifeCycle implements Servlet {
        @Override
         //当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init( )方式传入一个	ServletConfig对象
        public void init(ServletConfig servletConfig) throws ServletException {
            //获取配置servlet所有初始化参数的键
            Enumeration<String> enumeration = servletConfig.getInitParameterNames();
            //遍历输出键与值
            while (enumeration.hasMoreElements()){
                String names = (String)enumeration.nextElement();
                String values = servletConfig.getInitParameter(names); //获取servlet配置的初始化参数
                System.out.println("ParamName = " + names + "ParamValue = " + values);
            }
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {}
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    控制台如图:

    在这里插入图片描述

    ServletContext对象

    ServletContext是在Web容器启动时,每个Web应用程序会创建一个对应的ServletContext对象(也称为Context对象)。一个Web应用中的所有Servlet共享同一个ServletContext对象,所以Servlet对象之间可以通过ServletContext对象来实现通讯。

    ServletContext对象中,配置Servlet参数时使用 context-param标签可以实现共享获取;而上述的ServletConfig对象中,配置Servlet参数只能在 servlet 内的 init-param标签,只能是本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的初始化参数-->
        <context-param>
            <param-name>username</param-name>
            <param-value>啊Q老师</param-value>
        </context-param>
        <context-param>
            <param-name>pwd</param-name>
            <param-value>123</param-value>
        </context-param>
        
        <servlet>
            <servlet-name>ServletConextTest</servlet-name>
            <servlet-class>com.edu.ServletStudy.ServletConextTest</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>ServletConextTest</servlet-name>
            <url-pattern>/ServletConextTest</url-pattern>
        </servlet-mapping>
    </web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    ServletConextTest.java:

    package com.edu.ServletStudy;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Enumeration;
    
    public class ServletConextTest implements Servlet {
        public void init(ServletConfig servletConfig) throws ServletException {
            //访问ServletContext
            ServletContext context = servletConfig.getServletContext();
            //获取配置servlet所有初始化参数的键
            Enumeration<String> paramNames = context.getInitParameterNames();
            //遍历输出键与值
            while (paramNames.hasMoreElements()) {
                String name = paramNames.nextElement();
                String value = context.getInitParameter(name);
                System.out.println(name + " = " + value);
            }
        }
    
        public ServletConfig getServletConfig() {
            return null;
        }
    
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {}
        
        public String getServletInfo() {
            return null;
        }
        
        public void destroy() { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在这里插入图片描述

    HttpServlet

    HttpServlet的作用是获取HTTP请求,响应HTTP结果。在IDEA中选中HttpServlet,“ctrl + 鼠标左键单击” 会跳转到HttpServlet类中,这时会发现HttpServlet是抽象类GenericServlet的子类。同时,HttpServlet类中写入了doGet()、doPost()、doOptions()、doDelete()等方法,他们是对应给HTTP中的Get、Post、Options、Delete等请求提供服务的。

    下面简单介绍常用的doGet()、doPost()方法: 表单提交数据到服务器中有两种方式,即 < form action = “***” method= " get / post " >属性method中的get或post。它们分别对应HttpServlet的doGet()、doPost()方法。
    doGet():该方式传递的数据会按照< key , value >的方式在URL中显示出来,安全性不高。
    doPost():该方式传递的数据存放在HTTP协议的消息体中,通过实体的方式传送到服务器。即将数据封装发出去,安全性高。

    Servlet的实现

    接下来,我们进一步对Servlet的实现,获取Register.html页面表单提交的参数。
    在web文件目录下创建Register.html,代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Servlet学习</title>
        <link rel="stylesheet" type="text/css" href="CSS/Register.css">
    </head>
    <body>
        <form action="http://localhost:8080/MSW/Register" method="post">
        	<h1>Welcome</h1>
            <label>账号:</label>
            <input type="text" name="username"/><br>
            <label>密码:</label>
            <input type="password" name="pwd"/><br>
            <label>性别:</label>
            <input type="radio" name="sex" value=""/><input type="radio" name="sex" value=""/><br>
            <label>生日:</label>
            <select name="birthday">
                <optgroup label="请选择年份">请选择年份</optgroup>
                <option value="2000">2000</option>
                <option value="2001">2001</option>
                <option value="2002">2002</option>
            </select><br>
            <input type="submit" value="注 册">&nbsp;&nbsp;&nbsp;&nbsp;
            <input type="reset" value="重 置">
        </form>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在web/CSS目录下创建Register.css,代码如下:

    body{
        text-align:center;
        background-color: antiquewhite;
    }
    
    • 1
    • 2
    • 3
    • 4

    在src创建com.edu.ServletStudy包,再创建RegisterServlet.java,代码如下:

    package com.edu.ServletStudy;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class RegisterServlet extends HttpServlet {
        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //解决响应结果中文显示乱码
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
    
    		//数据获取
            String username = request.getParameter("username");
            String pwd = request.getParameter("pwd");
            String sex = request.getParameter("sex");
            String birthdayStr = request.getParameter("birthday"); //获取字符串类型的数据
            Integer birthday = Integer.parseInt(birthdayStr); //字符串转整型
    
            //控制台上打印
            System.out.println("username = " + username);
            System.out.println("pwd = " + pwd);
            System.out.println("sex = " + sex);
            System.out.println("birthday = " + birthday);
    
            //跳转在新网页上打印
            response.getWriter().println(request.getParameter("username"));
            response.getWriter().println(request.getParameter("pwd"));
            response.getWriter().println(request.getParameter("sex"));
            response.getWriter().println(Integer.parseInt(birthdayStr));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在web/WEB-INF目录下的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">
        <!--
        首先,用户发起请求,action=Register;
        然后Tomcat中的web.xml先寻找url-pattern = /Register,到servlet-mapping中的servlet-name = RegisterServlet;
        再到servlet寻找对应servlet-mapping的servlet-name的servlet;
        再找到servlet-class的com.edu.ServletStudy.RegisterServlet;
        最后由于用户发送的是post请求(method = post),所以Tomcat执行doPost方法。
        -->
        <servlet>
            <servlet-name>RegisterServlet</servlet-name>
            <servlet-class>com.edu.ServletStudy.RegisterServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>RegisterServlet</servlet-name>
            <url-pattern>/Register</url-pattern>
        </servlet-mapping>
    </web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在RegisterServlet.java点击运行,效果如图:
    在这里插入图片描述

    控制台结果:

    在这里插入图片描述

    网页结果:

    在这里插入图片描述

    实现过程遇到的问题解决

    解决Address localhost:1099 is already in use的问题

    在Intellij idea运行中端口出现Address localhost:1099 is already in use的问题(即端口被占用)。 解决办法是:
    1.win+R, 输入cmd命令,打开dos命令行,输入netstat -ano | find “1099”,得到PID (即最后一列数字)
    2.通过PID找到进程,输入:tasklist | find “那一列数字”
    3.最后输入命令关闭进程:taskkill /f /t /im java.exe

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

    解决Servlet获取radio的值为on的问题

    如图:

    在这里插入图片描述

    导致这个问题的主要原因可能是代码有错误的地方,无法识别获取到值
    正确的代码:

    <input type="radio" name="sex" value=""/><input type="radio" name="sex" value=""/><br>
    
    • 1
    • 2

    IDEA中的clean工程

    clean功能清除项目中缓存重新加载校验。
    步骤如图:
    1.点击File—>Invalidate Caches / Restart…
    在这里插入图片描述
    2.点击Invalidate and Restart,缓存将在下一次启动时失效并重新构建,当地历史也将被清除。
    在这里插入图片描述
    3.IDEA重启
    在这里插入图片描述

  • 相关阅读:
    借势热点:如何快速讲今日热点跟我们的视频结合起来?支招三把斧
    Web安全—Web漏扫工具NetSparker安装与使用
    接口测试(jmeter和postman 接口使用)
    网络安全(黑客)自学
    罗勇军 →《算法竞赛·快冲300题》每日一题:“游泳” ← DFS+剪枝
    代码随想录算法训练营第四十二天| 494. 目标和、474. 一和零 、52. 携带研究材料(第七期模拟笔试)、518. 零钱兑换 II
    计算机网络-网络安全(二)
    uni-app 中的 picker 组件基于后台对象数组数据格式的使用
    git更新代码时显示“auto-detection of host provider took too long“移除方法
    Java InputStream.mark()方法具有什么功能呢?
  • 原文地址:https://blog.csdn.net/qq_56886142/article/details/124482407