IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Web基础:Servlet规范(一) -> 正文阅读

[Java知识库]Web基础:Servlet规范(一)

目录

1.概述

2.Servlet接口实现类的开发步骤

2.1 Servlet接口实现类

2.2 Servlet接口实现类开发步骤

3.Servlet对象的生命周期

4.HttpServletResponse接口

4.1 介绍

4.2 主要功能

4.3 实例

5.HttpServletRequest接口

5.1 介绍

5.2 功能

5.3 实例

6.请求对象与响应对象的生命周期

7.欢迎资源文件


1.概述

? ?servlet规范来自于JavaEE规范中的一种。

? ?作用

? ? ? ? ①在Servlet规范中,指定动态资源文件开发步骤

? ? ? ? ②在Servlet规范中,指定Http服务器调用动态资源文件规则

? ? ? ? ③在Servlet规范中,指定Http服务器管理动态资源文件实例对象规则

2.Servlet接口实现类的开发步骤

2.1 Servlet接口实现类

? ?Servlet接口来自于Servlet规范下的一个接口,这个接口存在Http服务器提供的jar包内。

? ?Tomcat服务器下的lib文件夹中有一个servlet-api.jar存放Servlet接口(javax.servlet.Servlet接口)。

? ?Servlet规范中认为Http服务器能调用的动态资源文件必须是一个Servlet接口实现类

2.2 Servlet接口实现类开发步骤

? ?①创建一个java类继承于HttpServlet父类(servlet-api.jar包内,javax.servlet.http.HttpServlet抽象类,而该类继承了GenericServlet抽象类,该父类实现了Servlet接口),使之成为一个Servlet接口实现类。

? ? ? ? 为什么不直接继承Servlet接口?

? ? ? ? ? ? ? ? 因为Servlet接口很多方法我们不需要使用,一般只需要使用到service()方法,因此通过

??????????????继承其他该接口的实现类,可以减少我们需要重写的方法数量。抽象类的作用就是降低接

??????????????口实现类对接口的实现难度,将接口中不需要使用的抽象方法交给抽象类进行完成,这样

??????????????接口实现类只需要对接口中需要使用的方法进行重写。

? ? ? ? Servlet接口中的方法

? ? ? ? ? ? ? ? 1.init()

? ? ? ? ? ? ? ? 2.getServletConfig()

? ? ? ? ? ? ? ? 3.getServeltInfo()

? ? ? ? ? ? ? ? 4.destory()

? ? ? ? ? ? ? ? 5.service()

? ? ? ? Tomcat根据Servlet规范调用Servlet接口实现类的规则

? ? ? ? ? ? ? ? 1.Tomcat有权自动创建Servlet接口实现类实例对象

? ? ? ? ? ? ? ? ? ? ? ? Servlet oneServlet = new OneServlet();

? ? ? ? ? ? ? ? 2.Tomcat根据实例对象调用service方法处理当前请求

? ? ? ? ? ? ? ? ? ? ? ? oneServlet.service();

? ? ? ? 各个类的关系:

????????????????oneServlet? ?extends? ?(abstract)HttpServlet? ?entends (abstract)GenericServlet? ????????????????????????????????????????????????????????????????????????????????????????implements Servlet接口

? ? ? ? ? ? ? ? 其中GenericServlet抽象类中实现了Servlet接口中我们不需要用到的四个方法:init()、

??????????????getServletConfig()、getServletInfo()、destory()。?

? ? ? ? ? ? ? ? HttpServlet抽象类中实现了service()方法。

? ? ? ? ? ? ? ? 自己定义的子类均可以继承这五个实现后的方法。

? ?②重写HttpServlet父类中的两个方法doGet()、doPost()。如果浏览器发送请求的方式为get,则调用的是doGet()方法;如果发送请求的方式为post,则调用的是doPost()方法。

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

? ? ? ? 在HttpServlet抽象类中实现的service()方法会根据浏览器请求的方式来调用doGet()或

??????doPost()方法。这种通过父类决定何种情况下调用子类中方法,是设计模式中的模板设计模

??????式

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);//调用子类中的doGet()方法
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);//调用子类中的doPost()方法
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

? ?③将Servlet接口实现类注册到Tomcat服务器。

? ? ? ? 网站--->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">
         <!--Servlet接口实现类路径地址交给Tomcat-->
         <servlet>
             <servlet-name>oneServlet</servlet-name><!--声明一个遍历存储Servlet接口是西安类的类路径-->
             <!--suppress WebProperties -->
             <servlet-class>com.bjpowernode.controller.OneServlet</servlet-class><!--Servlet接口实现类路径-->
         </servlet>

         <!--为Servlet接口实现类提供一个简短的别名,降低用户访问Servlet接口实现类难度-->
         <servlet-mapping>
             <servlet-name>oneServlet</servlet-name>
             <url-pattern>/one</url-pattern><!--设置简短请求别名,别名在书写时必须以"/"开头-->
         </servlet-mapping>
</web-app>

3.Servlet对象的生命周期

? ?1.网站中所有Servlet接口实现类的实例对象,只能由Http服务器负责创建,开发人员不需要手动创建Servlet接口实现类的实例对象。

? ?2.在默认的请求下,Http服务器接收到对于当前Servlet接口实现类第一次请求时自动创建这个Servlet接口实现类的实例对象。

? ?在手动配置情况下,要求Http服务器在启动时自动创建某个Servlet接口实现类的实例对象,在向服务器注册该类时,加上一句:

<servlet>
    <servlet-name>oneServlet</servlet-name>
    <!--suppress WebProperties -->
    <servlet-class>com.bjpowernode.controller.OneServlet</servlet-class>
    <load-on-startup>30</load-on-startup><!--填写一个大于0的整数即可-->
</servlet>

? ?3.在Http服务器运行期间,一个Servlet接口实现类只能被创建出一个实例对象。多个用户访问时,也只有一个实例对象,相当于一个进程多个线程。

? ?4.在Http服务器关闭时刻,自动将网站中所有的Servlet对象进行销毁。

? ?IDEA快速创建Servlet接口的实现类:

4.HttpServletResponse接口

4.1 介绍

? ?①HttpServletResponse接口来自于Servlet规范中,在Tomcat中存在于servlet-api.jar包中。

? ?②HttpServletResponse接口实现类由http服务器负责提供

? ?③HttpServletResponse接口负责将doGet/doPost方法执行结果写入到响应体交给浏览器

? ?④开发人员习惯于将HttpServletResponse接口修饰的对象称为响应对象

4.2 主要功能

? ?①将执行结果以二进制形式写入到响应体

? ?②设置响应头中content-type属性值,从而控制浏览器使用对应编译器将响应体二进制数据编译为文字、图片、视频、命令

? ?③设置响应头location属性,将一个请求地址赋值给location,从而控制浏览器向指定服务器发送请求

4.3 实例

? ?1.通过HttpServletResponse接口实现类对象response获得需要的输出流。

public class OneServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String result = "Hello World";//执行结果

        //---------响应对象将结果写入响应体----------start
        //1.通过响应对象,向Tomcat索要输出流
        PrintWriter out = response.getWriter();
        //2.通过输出流,将执行结果以二进制形式写入到响应体
        out.write(result);
        //不是自己创建的输出流,不需要自己手动关闭
        //---------响应对象将结果写入响应体----------end
    }
    //doGet方法执行完毕
    //Tomcat将响应包推送给浏览器
}

? ?2.out.print()方法:

/**
 * 问题描述:浏览器接受到数据是2,不是50
 * 问题原因:
 *     out.write方法可以将“字符”,“字符串”,“ASCII码”写入到响应体
 *     参数放入数字,计算机认为是ASCII码,而2的ASCII码就是50
 *
 * 解决方法:实际开发中,都是通过out.print()将真实数据写入到响应体
 *
 */
public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int money = 50;
        PrintWriter out = response.getWriter();
        //out.write(money);
        out.print(money);//以后都使用这个方法即可
    }
}

? ?3.通过设置context-type属性来控制浏览器的编译格式。默认情况下context-type属性的值为"test"

/**
 * 问题描述:Java<br>Mysql<br>Html
 *          浏览器在接收到响应结果时,将<br>作为文字内容在窗口展示出来,没有将<br>当作HTML标签命令来执行
 *
 * 问题原因:
 *          浏览器在接收到响应包之后,根据响应头中的content-type属性的值,
 *          来采用对应的编译器对响应体中二进制内容进行编译处理。
 *
 *          在默认情况下,content-type属性的值为test 即content-type="test"
 *          此时浏览器会采用文本编辑器对响应体二进制数据进行解析。
 *
 * 解决方案:
 *          一定要在得到输出流之前,通过响应对象响应头中content-type属性进行一次重新赋值
 *          用于制定浏览器采用正确编译器。
 */
public class ThreeServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String result = "Java<br>Mysql<br>Html";//既有文字信息,又有HTML标签命令
        String result2 = "<br>红烧排骨<br>梅菜肘子<br>糖醋里脊";

        //在获得输出流之前,设置content-type属性
        response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();
        out.print(result);
        out.print(result2);
    }
}

? ?4.设置location属性设置响应头,向其他服务器发起请求。

public class FourServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String result = "http://www.baidu.com";

        //通过响应对象,将地址赋值给响应头中location属性
        response.sendRedirect(result);//[响应头 location="http://www.baidu.com"]
    }
    /**
     * 浏览器在接收到响应包之后,如果发现响应头中存在location属性,自动通过地址栏location指定网站发送请求
     *
     * sendRedirect方法远程控制浏览器请求行为【请求地址,请求方式,请求参数】
     */
}

5.HttpServletRequest接口

5.1 介绍

? ?①HttpServletRequest接口来自于Servlet规范中,在Tomcat中存在于servlet-api.jar包中。

? ?②HttpServletRequest接口实现类由http服务器负责提供

? ?③HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中的信息。

? ?④开发人员习惯于将HttpServletRequest接口修饰的对象称为请求对象

5.2 功能

? ?①可以读取Http请求协议包中请求行信息

? ?②可以读取保存在Http请求协议包中请求头或者请求体中请求参数信息

? ?③可以代替浏览器向Http服务器申请资源文件调用

5.3 实例

? ?1.读取请求行信息。

? ? ? ? URI:资源文件精准定位地址,在请求行没有uri这个属性。实际上uri是url中截取的一个字符

??????串,这个字符串格式"/网站名/资源文件名",uri用于让Http服务器对被访问的资源文件进行定

? ? ? 位。

public class OneServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.通过请求对象,读取请求行中url信息
        String url = request.getRequestURL().toString();
        //2.通过请求对象,读取请求行中method信息
        String method = request.getMethod();
        System.out.println("URL = " + url);
        System.out.println("method = " + method);
        //3.通过请求对象,读取请求行中uri信息
        /**
         * URI:资源文件精准定位地址,在请求行并没有URI这个属性。
         *      实际上是URL中截取的一个字符串,这个字符串格式"/网站名/资源文件名"
         *      URI用于让Http服务器对被访问的资源文件进行定位
         */
        String uri = request.getRequestURI();
        System.out.println("URI = " + uri);
    }
}

? ?2.读请求头里面的值(get方法)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <center>
        <!--利用一个超链接来输入请求参数-->
        <a href="/05_HttpServletRequest_war_exploded/two?usernmae=milk&password=123">通过超链接访问TwoServlet并且携带请求参数</a>
    </center>
</body>
</html>
public class Two1Servlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.通过请求对象获得请求头中所有请求参数名
        Enumeration paramNames = request.getParameterNames();//将所有请求参数名称保存到一个枚举对象进行返回
        while(paramNames.hasMoreElements()){
            String paramName = (String)paramNames.nextElement();
            System.out.println("请求参数: " + paramName);
            //2.通过请求对象读取指定的请求参数的值
            String value = request.getParameter(paramName);
            System.out.println("value: " + value);
        }
    }
}

? ?3.读请求体里面的值(post方法)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <center>
        <form action="/05_HttpServletRequest_war_exploded/three" method="get">
            请求参数:<input type="text" name="userName"/><br>
            <input type="submit" value="get方式访问ThreeServlet"/>
        </form>
        <form action="/05_HttpServletRequest_war_exploded/three" method="post">
            请求参数:<input type="text" name="userName"/><br>
            <input type="submit" value="post方式访问ThreeServlet"/>
        </form>
    </center>
</body>
</html>
/**
 * 问题:
 *      以GET方式发送中文参数内容“张三”时,可以得到正常结果
 *      以POST方式发送中文参数内容时,得到一堆乱码?????
 *
 * 原因:
 *      浏览器以GET方式发送请求时,请求参数保存在请求头内,在Http请求协议包到达Http服务器之后,第一件事就是进行解码,
 *      请求头二进制内容由Tomcat负责解码,Tomcat9.0默认使用utf-8字符集,可以解释一切国家文字。
 *
 *      浏览器以POST方式发送请求,请求参数保存在请求体内,在Http请求协议包到大Http服务器之后,第一节是就是进行解码,
 *      请求体二进制内容由当前请求对象request负责解码。request默认使用[ISO-8859-1]字符集,一个东欧语系字符集,
 *      此时如果请求体参数内容是中文,将无法解码,只能得到乱码
 *
 * 解决方案:
 *      在POST请求方式下,读取请求体的内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码。
 */

public class  ThreeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通知请求对象使用utf-8字符集
        request.setCharacterEncoding("utf-8");
        //通过请求对象,读取请求体中参数信息
        Enumeration paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()){
            String paramName = (String) paramNames.nextElement();
            String value = request.getParameter(paramName);
            System.out.println("从请求体得到参数值 " + value);
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象,读取请求头参数信息
        String value = request.getParameter("userName");
        System.out.println("从请求头的到参数值:" + value);
    }
}

? ? ? ? ①当浏览器以GET方式发送请求时,请求参数保存在请求头,在Http请求协议包到达Http服务

? ? ? ? ? 器之后,第一件事就是进行解码。请求头二进制内容由Tomcat负责解码,Tomcat9.0默认使

? ? ? ? ? 用UTF-8字符集,可以解释一切国家语言。?

? ? ? ? ②当浏览器以POST方式发送请求时,请求参数保存在请求体,在Http请求协议包到达Http服

? ? ? ? ? 务器之后,第一件事就是进行解码。请求体二进制内容由当前请求对象request负责解码

? ? ? ? ? request默认使用ISO-8859-1字符集,一个东欧语系字符集,此时如果请求体参数内容是中

? ? ? ? ? 文,将无法正常解码,只能获得乱码。

6.请求对象与响应对象的生命周期

? ?①在Http服务器接收到浏览器发送的Http请求协议包之后,自动为当前的Http请求协议包生成一个请求对象和一个响应对象。

? ?②在Http服务器调用doGet/doPost方法时,负责将请求对象和响应对象作为实参传递到方法,确保doGet/doPost方法正确执行。

? ?③在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的请求对象和响应对象销毁。

? ?请求对象和响应对象生命周期贯穿一次请求的处理过程中。

? ?请求对象和响应对象相当于用户在服务端的代言人。

7.欢迎资源文件

? ?用户一般可以记住网站名,但记不住网站资源名。因此产生了默认欢迎资源文件。

? ?默认欢迎资源文件:用户发送了一个针对某个网站的默认请求时,此时由Http服务器自动从当前网站返回的资源文件。

? ? ? ? 正常请求:http://localhost:8080/myWeb/index.html

? ? ? ? 默认请求:http://localhost:8080/myWeb/

? ?Tomcat服务器对于默认欢迎资源文件的定位规则

? ? ? ? ①规则位置:Tomcat安装位置/conf/web.xml

? ? ? ? ②定义语法:

? ?设置当前网站的默认欢迎资源文件的规则:

? ? ? ? ①规则位置:网站/web/WEB-INF/web.xml

? ? ? ? ②定义语法:在web.xml文件中添加。

? ? ? ? ③网站设置自定义默认文件定位规则后,此时Tomcat自带定位规则将失效

PS:根据动力节点课程整理,如有侵权,联系删除。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:15:46  更:2021-10-18 17:16:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:59:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码