• Servlet API详解


    在这里插入图片描述

    请添加图片描述

    ⭐️前言⭐️

    本文我们主要介绍Servlet里的关键API,也就是HttpServlet、HttpServletRequest、HttpServletResponse这三个类中一些方法的使用。

    🍉博客主页: 🍁【如风暖阳】🍁
    🍉精品Java专栏【JavaSE】【备战蓝桥】、【JavaEE初阶】【MySQL】【数据结构】
    🍉欢迎点赞 👍 收藏留言评论 📝私信必回哟😁

    🍉本文由 【如风暖阳】 原创,首发于 CSDN🙉

    🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

    🍉博客中涉及源码及博主日常练习代码均已上传码云(gitee)GitHub


    请添加图片描述

    请添加图片描述

    🍅1.HttpServlet

    我们在写Servlet代码的时候,首先第一步就是先创建类,继承自HttpServlet,并重写其中的某些方法。

    1.1 核心方法

    方法名称调用时机
    init在HttpServlet实例化后被调用一次
    destory在HttpServlet实例不再使用的时候调用一次
    service收到HTTP请求的时候调用
    doGet收到GET请求的时候调用(由service方法调用)
    doPost收到POST请求的时候调用(由service方法调用)
    doPut/doDelete/doOptions/…收到其他请求的时候调用(由service方法调用)

    在实际开发中主要重写doXXX方法,很少会重写init/destory/service.

    这些方法的调用时机,就称为“Servlet生命周期”(也就是描述了一个Servlet实例从生到死的过程)
    在这里插入图片描述

    注意:HttpServlet的实例只是在程序启动时创建一次,而不是每次收到HTTP请求都重新创建实例。

    1.2 代码示例:处理GET请求

    创建MethodServlet.java,创建doGet方法

    @WebServlet("/method")
    public class MethodServlet extends HelloServlet{
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("GET RESPONSE");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们知道,在浏览器中直接输入URL就可以构造一个GET请求,现在我们来测试服务器的处理:
    在这里插入图片描述

    1.3 代码示例:处理POST请求

    在MethodServlet.java中,新增doPost方法

    @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().write("POST 响应");
        }
    
    • 1
    • 2
    • 3
    • 4

    完成了服务器端的代码,我们需要构造一个POST请求来进行测试,并不能通过直接输入URL的方式来构造POST请求;构造POST请求的方法有两种,一种是基于form表单,另一种是通过ajax来构造,下边我们主要来看看通过ajax的方式来如何构造post请求。(该流程的详情也可见文章【构造HTTP请求与HTTPS加密1.2】

    首先我们需要先在webapp目录下创建一个HTML文件,用来构造POST请求。
    在这里插入图片描述
    然后我们需要引入jQuery依赖(搜索jQuery mdn进行复制,也可本地导入)
    在这里插入图片描述
    最后使用jQueryajax函数.
    在这里插入图片描述
    注意:ajax请求中的URL不能加/,但是Servlet类的注解必须加上/.

    我们访问http://localhost:8080/maven_1102/testMethod.html,出现如下图结果:
    在这里插入图片描述
    也就是出现了乱码的情况,这是因为我们在编译器上,字体的默认编码方式为utf-8,而浏览器字体的默认编码方式为GBK,因为编码方式的不同,导致同一文件在不同地方的展示出现了乱码的情况;我们可以通过响应,显式的告诉浏览器通过utf8的方式进行编码,就可以避免乱码的情况了。
    在这里插入图片描述
    上述红框中代码的含义为,响应的返回类型为html格式,编码方式为utf8.

    重新打包部署并测试:
    在这里插入图片描述

    🍅2.HttpServletRequest

    当Tomcat通过Socket API读取HTTP请求(字符串),并且按照HTTP协议格式把字符串解析成HttpServletRequest对象。

    2.1 核心方法

    方法描述
    String getProtocol()返回请求协议的名称和版本
    String getMethod()返回请求的HTTP方法的名称,例如,GET、POST或PUT
    String getRequestURI()从协议名称直到HTTP请求的第一行的查询字符串中,返回该请求的URL的一部分。
    String getContextPath()返回指示请求上下文的请求URI部分
    String getQueryString()返回包含在路径后的请求URL中的查询字符串
    Enumeration getParameterNames()返回一个String 对象的枚举,包含在该请求中包含的参数的名称(即键值对中的Key)
    String getParameter(String name)以字符串形式返回请求参数的值,或者如果参数不存在则返回null(即通过键值对中的Key来拿到value)
    String[] getParameterValues(String name)返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回null
    Enumeration getHeaderNames()返回一个枚举,包含在该请求中包含的所有的头名(请求报头也是键值对结构,此处活动Key)
    String getHeader(String name)以字符串形式返回指定的请求头的值(Value)
    String getCharacterEncoding()返回请求主体中使用的字符编码的名称
    String getContentType()返回请求主体的MIME类型,如果不知道类型则返回null
    int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回-1.
    InputStream getInputStream()用于读取请求的body内容,返回一个InputStream对象

    通过这些方法可以获取到一个请求中的各个方面的信息。

    注意:请求对象是服务器收到的内容,不应该修改。因此上面的方法也都只是“读”方法,而不是“写”方法。

    2.2 代码示例:打印请求信息

    创建ShowRequestServlet类,调用一下在2.1中涉及到的几个关键API,并把得到的结果组织到一个html中,并作为响应的body.

    @WebServlet("/showRequest")
    public class ShowRequestServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //把API执行的结果,放到stringBuilder中
            StringBuilder stringBuilder=new StringBuilder();
            stringBuilder.append("

    首行部分

    "
    ); stringBuilder.append(req.getProtocol()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getMethod()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getRequestURI()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getContextPath()); stringBuilder.append("
    "
    ); stringBuilder.append(req.getQueryString()); stringBuilder.append("
    "
    ); stringBuilder.append("

    header部分

    "
    ); Enumeration<String> headerNames=req.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName= headerNames.nextElement(); String headerValue=req.getHeader(headerName); stringBuilder.append(headerName+":"+headerValue+"
    "
    ); } resp.setContentType("text/html;charset=utf8"); resp.getWriter().write(stringBuilder.toString()); } }
    • 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

    在这里插入图片描述

    2.3 代码示例:获取GET请求中的参数

    最常用的其实是getParameter这个方法,能够获取到query string中的详细内容。创建一个GetParameterServlet类来获取Get请求中的参数。

    @WebServlet("/getParameter")
    public class GetParameterServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String userId=req.getParameter("userId");
            String classId=req.getParameter("classId");
            resp.getWriter().write("userId="+userId+",classId="+classId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    浏览器构造如下请求。
    在这里插入图片描述

    2.4 代码示例:获取POST请求中的参数

    POST请求的body格式主要有以下三种:

    1.x-www-form-urlencoded
    2.form-data
    3.json

    最为常见的是第一种和第三种,我们可以通过form表单或者ajax的方式来构造出这样的POST请求。

    1)基于form表单构造x-www-form-urlencoded这种格式的请求。

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <form action="postParameter" method="post" accept-charset="utf-8">
            <span>userIdspan>
            <input type="text" name="userId">
            <span>classIdspan>
            <input type="text" name="classId">
            <input type="submit" value="提交">
        form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    服务器获取参数的方式和GET方法一样,也是getParameter。

    @WebServlet("/postParameter")
    public class PostGetParameterServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //设置请求与响应中的编码格式
            req.setCharacterEncoding("utf-8");
            resp.setContentType("text/html; charset=utf8");
            //获取post请求中的参数
            String userId=req.getParameter("userId");
            String classId=req.getParameter("classId");
            resp.getWriter().write("userId="+userId+",classId="+classId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试效果演示:
    请添加图片描述
    2)基于ajax构造json这种格式的请求.

    1.在浏览器的前端代码中,通过js构造出bodyjson格式的请求

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        
        <input type="text" id="userId">
        <input type="text" id="classId">
        <input type="button" id="submit" value="提交">
    
        
        <script src="https://code.jquery.com/jquery-3.6.1.min.js">script>
    
        <script>
            let userIdInput=document.querySelector('#userId');
            let classIdInput=document.querySelector('#classId');
            let button=document.querySelector('#submit');
            button.onclik=function() {
                $.ajax({
                    type:'post',
                    url:'postJson',
                    contentType:'application/json',
                    data:JSON.stringify({
                        userId:userIdInput.value,
                        classId:classIdInput.value
                    }),
                    success:function(body) {
                        console.log(body);
                    }
                })
            }
        script>
    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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

    2.因为json格式的数据,不便于手动解析,所以在Java后端代码中,通过Jackson来进行处理(在maven中央仓库引入Jackson依赖)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    后端代码:

    class User {
        public int userId;
        public int classId;
    }
    @WebServlet("/postJson")
    public class PostJsonServlet extends HttpServlet {
        //1.创建一个jackson的核心对象
        private ObjectMapper objectMapper=new ObjectMapper();
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //2.读取body中的请求,然后使用ObjectMapper来解析成需要的对象
            //readValue就是把JSON格式的字符串,转成Java的对象
            //第一个参数,表示对哪个字符串进行转换(这个参数可以是一个String,也可以是
            // 一个InputStream对象,还可以是一个File对象)
            //第二个参数,表示要把这个JSON格式的字符串,转换成哪个Java对象
            User user=objectMapper.readValue(req.getInputStream(),User.class);
            resp.getWriter().write("userId:"+user.userId+",classId:"+user.classId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    readValue方法解析:
    在这里插入图片描述
    1.先把getInputStream对应的流对象里面的数据读取出来。
    2.针对这个json字符串进行解析,从字符串转换成键值对
    3.遍历键值对,依次获取到每一个Key,根据这个Key的名字,和类对象Uer里面的属性名字对比(利用反射获取到内部属性),如果匹配就进行赋值,不匹配就跳过
    4.当把所有的键值对都遍历过后,此时User对象就被构造好了。

    测试效果演示:
    请添加图片描述

    🍅3.HttpServletResponse

    Servlet中的doXXX方法的目的是根据请求计算得到响应,然后把响应的数据设置到HttpServletResponse对象中。

    然后Tomcat就会把这个HttpServletResponse对象按照HTTP协议的格式,转成一个字符串,并通过Socket写回给浏览器。

    3.1 核心方法

    方法描述
    void setStatus(int sc)为该响应设置状态码
    void setHeader(String name,String value)设置一个带有给定的名称和值的header,如果name已经存在,则覆盖掉旧的值,可以实现页面的刷新
    void addHeader(String name,String value)添加一个带有给定的名称和值的header,如果name已经存在,不覆盖旧的值,并列添加新的键值对
    void setContentType(String type)设置被发送到客户端的响应的内容类型
    void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码(MIME字符集)例如,UTF-8
    void sendRedirect(String location)设置指定的重定向位置URL,发送临时重定向响应到客户端
    PrintWriter getWriter()用于往body中写入文本格式数据
    OutputStream getOutputStream()用于往body中写入二进制格式数据

    注意:响应对象是服务器要返回给浏览器的内容,这里的重要信息都是程序猿设置的。因此上面的方法都是“写”方法
    对于状态码/响应头的设置,要放到getWriter/getOutputStream之前,否则可能设置失效

    3.2 代码示例:设置状态码

    代码:

    @WebServlet("/status")
    public class StatusServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setStatus(404);
            resp.getWriter().write("hello");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    效果预览:
    在这里插入图片描述
    状态码虽然是404,但页面仍然能够显示出内容,就像b站的404页面一样
    在这里插入图片描述

    3.3 代码示例:自动刷新

    代码:

    @WebServlet("/autoRefresh")
    public class AutoRefreshServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setHeader("Refresh","1");
            resp.getWriter().write("timeStamp:"+System.currentTimeMillis());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    效果预览:
    请添加图片描述

    3.4 代码示例:重定向

    代码:

    @WebServlet("/redirect")
    public class RedirectServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.sendRedirect("https://www.bilibili.com");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    效果预览:
    请添加图片描述

    下期预告:Servlet综合案例:表白墙


    ⭐️最后的话⭐️
    总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

    请添加图片描述

  • 相关阅读:
    编程堆芯熔融物自然对流的
    双位置继电器JDP-1440/DC110V
    C++调用OpenCV实现图像平滑处理
    第 2 章 线性表(学生健康登记表实现)
    工程机械比例阀电流采集方案
    C++设计模式——Proxy代理模式
    B2B企业常用的邮件营销推广策略
    UE4 Android端使用MediaPlayer注意事项
    Audio Hijack for Mac 激活版:音频录制与处理软件
    【转】ES, 广告索引
  • 原文地址:https://blog.csdn.net/qq_60856948/article/details/127647201