Servlet中常见的API详解

目录

1、核心方法:

HttpServletRequest关键方法: 

​HttpServletResponse关键方法:

 2、获取GET请求信息:

3、Post请求的构造

 4、Post请求信息的获取

x-www-form-urlencode格式:

json格式:

5、响应的构造

案例1: 设置响应状态码

案例2:自动页面刷新

 案例3:重定向案例


1、核心方法:

这些方法的调用时机,就构成了“Servlet”的生命周期 

 生命周期

注: 

  • 在写Servlet代码时,第一步就是先创建类,继承自HttpServlet,并且重写其中的某些方法
  • 在实际的开发中,主要重写doXXX方法,很少会重写init/destory/service 
  • HttpServlet的实例只是在程序启动时创建一次,而不是每次收到HTTP请求都重新创建实例
  • tomcat收到请求,实际上是先调用service,在service里面再去根据方法,调用不同的doXXX

HttpServletRequest关键方法: 

HttpServletResponse关键方法:


 2、获取GET请求信息:

请求对象提供的都是getXXX方法,用来获取的,修改是setXXX方法

        对于请求的信息,我们运用HttpServletRequest类的方法来进行请求信息的获取:
        比如我们访问的url为http://127.0.0.1:8080/Test/requestServlet?key=10&a=100&b=200,很明显这是使用查询字符串构造的一个GET请求,通过HttpServletRequest类一系列对应的方法,我们可以获取到这个请求的方法类型,协议版本,URL,查询字符串,头部的一些信息等。其中查询字符串与头部信息的获取先要使用getParameterNames方法或者getHeaderNames方法获取所有的查询字符串或头部信息的所有key值,这个一个枚举对象,然后在根据getParameter或者getHeader方法通过key值遍历枚举对象获取value。

代码测试看结果:

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.util.Enumeration;

@WebServlet("/requestServlet")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //访问链接:http://127.0.0.1:8080/hello_servlet/showreq?key=10&a=100&b=200
        StringBuilder stringBuilder = new StringBuilder();
        resp.setContentType("text/html; charset=utf-8");
        //1协议名称与版本
        stringBuilder.append("协议版本:");
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        //2方法类型
        stringBuilder.append("方法:");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        //3获取查URL路径
        stringBuilder.append("URL路径:");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        //4URL(不包括查询字符串后面的部分)
        stringBuilder.append("URL(不包括查询字符串后面的部分):");
        stringBuilder.append(req.getRequestURL());
        stringBuilder.append("<br>");

        //5一级路径
        stringBuilder.append("一级路径:");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        //6查询字符串
        stringBuilder.append("查询字符串:");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        //7正文编码格式
        stringBuilder.append("正文编码格式:");
        stringBuilder.append(req.getCharacterEncoding());
        stringBuilder.append("<br>");
        //8mine
        stringBuilder.append("mine:");
        stringBuilder.append(req.getContentType());
        stringBuilder.append("<br>");
        //9正文长度
        stringBuilder.append("正文长度:");
        stringBuilder.append(req.getContentLength());
        stringBuilder.append("<br>");
        //10获得每一个查询字符串的键值:
        stringBuilder.append("<h3>获得每一个查询字符串的键值:</h3>");
        Enumeration query = req.getParameterNames();
        while(query.hasMoreElements()) {
            String key = (String)query.nextElement();
            stringBuilder.append(key);
            stringBuilder.append(":");
            stringBuilder.append(req.getParameter(key));
            stringBuilder.append("<br>");
        }
        //11获得头部的键值
        stringBuilder.append("<h3>获得头部的键值:</h3>");
        Enumeration header = req.getHeaderNames();
        while(header.hasMoreElements()) {
            String key = (String)header.nextElement();
            stringBuilder.append(key);
            stringBuilder.append(":");
            stringBuilder.append(req.getHeader(key));
            stringBuilder.append("<br>");
        }
        resp.getWriter().write(stringBuilder.toString());
    }
}

        其中查询字符串与头部信息的获取先要使用getParameterNames方法或者getHeaderNames方法获取所有的查询字符串或头部信息的所有key值,这个一个枚举对象,然后在根据getParameter或者getHeader方法通过key值遍历枚举对象获取value。 

        成功启动后(如何部署程序,前面说过了,感兴趣的小伙伴可以自行去查看一下0,去浏览器查看结果:

         这里如果你出现乱码了,中文的编码有很多种,其中最常见就是utf8,如果没有显式的指定编码方式,则浏览器不能正确的识别编码,就会出现乱码,可以在代码中,通过resp.setContentType("text/html;charset=utf8");显式指定编码方法,一般情况就不会再有乱码了,但是,如果你还是乱码,可以去检查一下IDEA:

 这样设置后,应该就不会有问题啦!


3、Post请求的构造

        在同一webapp里面,关联路径不能够相同,不然Tomcat跑不起来,对于GET请求,可以使用URL的查询字符串进行构造,但是POST请求不行,需要使用form或者ajax。

构造Post请求(使用ajax构造):
        在webapp目录下创建一个HTML文件,用来构造POST请求,首先我们先的引入jquery依赖(https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js导入依赖),然后调用ajax构造请求。

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "post",
            url: "method",
            success: function (body){
                console.log(body);
            }
        })
    </script>

        注意上面的URL属性不能加/,加上表示的就是绝对路径了,当然你也可以使用./来表示相对路径,但是在Servlet注解关联路径必须得加上/。 

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;

@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("POST请求");
    }
}

 打包部署,刷新页面:ok


 4、Post请求信息的获取

        我们知道post请求的请求信息在http格式中的body部分当中,而body中的请求内容的格式是有很多种的,比如最常见的有:

  1. x-www-form-urlencode格式,通过form表单或者postman构造。
  2. json格式
  3. form-data格式

x-www-form-urlencode格式:

key=value&key=value&...

form表单创建x-www-form-urlencode格式请求:

<!DOCTYPE html>
<html lang="ch">
<head>
    <meta charset="UTF-8">
    <title>post</title>
</head>
<body>
    <form action="./postParameter" method="post" accept-charset="utf-8">
        <span>userId</span>
        <input type="text" name="userId">
        <span>classId</span>
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>
</body>
</html>

Servlet程序接收和处理请求:
        对于x-www-form-urlencode格式请求可以直接使用HttpServletRequest中的getParameter方法依据key来获取value,然后再将获取到的数据返回,form表单构造的请求会自动跳转页面。

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;

@WebServlet("/postParameter")
public class GetPostParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取post请求body请求中的参数
        //设置请求与响应编码格式
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html; charset=utf8");
        //比如useId =   classId=
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        //写会数据
        resp.getWriter().write("userId=" + userId + ", " + "classId=" + classId);
    }
}

结果:

json格式:

{ \{{
k e y : v a l u e , key:value,key:value,
k e y : v a l u e , key:value,key:value,
k e y : v a l u e , key:value,key:value,
. . . ......
} \}}

        对于json格式,手动解析不容易,因为json里面的字段是可以嵌套的,但我们可以借助第三方库来解析处理json,比如Jackson,Jackson依赖导入过程如下【中央仓库】:

复制到pom.xml中:

 处理json请求步骤:
第一步,在前端js代码中构造出格式为json格式的请求。
其中ajax构造post请求,使用contentType来说明请求的类型,data属性来设置body的内容。

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>json</title>
</head>
<body>
    <!-- 前端HTML部分 -->
    <input type="text" id="userId"> 
    <input type="text" id="classId">
    <input type="button" id="submit" value="提交"> 
	<!-- 如果已经准备好本地的jQuery就导入本地的,否则可以找网上的jQuery cdn网络路径 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

    <script>
        let userIdInput = document.querySelector("#userId");
        let classIdInput = document.querySelector("#classId");
        let button = document.querySelector("#submit");

        button.onclick = function() {
            $.ajax({
                type : "post",
                url: "getJsonPost",
                contentType: "appliaction/json",
                data:JSON.stringify({
                    userId: userIdInput.value,
                    classId:classIdInput.value
                }),
                success: function(body){
                    console.log(body);
                }
            })
        }
    </script>
</body>
</html>

 第二步,在java后端代码中使用Jackson处理。

  • 创建Jackson核心对象ObjectMapper对象。
  • 读取请求中的body信息,该过程通过ObjectMapper对象的readValue方法实现。
  • 创建用来接受json数据的类。
  • readValue方法的参数有两个,第一个参数用来表示请求的来源,可以是路径字符串,与可以是InputSream对象,也可以是File对象,第二个参数表示接收json数据的类对象。
  • 处理并响应请求。 
import com.fasterxml.jackson.databind.ObjectMapper;

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;

class User {
    public String userId;
    public String classId;
}
@WebServlet("/JsonPost")
public class GetJsonPostServlet extends HttpServlet {
    //1.创建一个Jackson的核心对象
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式
        resp.setContentType("text/html; charset=utf8");
        //处理
        //2.读取body请求的内容,使用ObjectMapper对象的readValue方法来解析
        //就是将字符串转换成java的对象,readValue方法的第一个参数可以是路径字符串可以是输入流对象,引入可以是File对象
        //第二个参数,表示需要将请求的json格式数据转换成哪一个java对象
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        System.out.println(user.userId);
        System.out.println(user.classId);
        resp.getWriter().write("userId=" + user.userId + "  ,classId=" + user.classId);
    }
}

结果;

readValue方法基本原理:

        读取json格式的数据,并解析成键值对。
        便利这些键值对,获得key,并与所需传入的对象中的属性(反射)相比,如果key与属性的名字相同,则把key对应的value赋值给这个属性,否则就跳过,所有的键值对便利完后,这个对象差不多就被构造的差不多了。


5、响应的构造

案例1: 设置响应状态码

设置方法很简单,只需要调用httpServletResponse对象中的setStatus方法就可以了

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;

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式
        resp.setContentType("text/html; charset=utf8");
        //设置状态码
        int status = 200;
        resp.setStatus(status);

        resp.getWriter().write("hello,这是" + status + "状态码的响应内容!");
    }
}

网页显示:1

 我把状态码修改为404,网页显示如下:2

案例2:自动页面刷新

        自动页面刷新只要在响应中设置一个header: Refresh就能实现页面的定时刷新了,对于响应header的设置,我们可以通过HttpServletResponse对象中的setHeader方法来设置Refresh属性和刷新频率。

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;

@WebServlet("/autorefresh")
public class AutoRefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式
        resp.setContentType("text/html; charset = utf8");
        //设置Refresh,第二个参数表示刷新频率,单位是秒
        resp.setHeader("Refresh", "1");
        //响应
        resp.getWriter().write("时间戳:" + System.currentTimeMillis());
    }
}

页面显示:

效果

 案例3:重定向案例

第一步,设置状态码为302
第二步,设置header:Location,调用setHeader方法时,第一个参数填Location,表示设置header字段为Location,第二个参数为重定向的目的地址,你要重定向到哪一个网址就传入哪一个地址的字符串。

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;

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式
        resp.setContentType("text/html; charset = utf8");
        //设置状态码
        resp.setStatus(302);
        //设置重定向字段与地址,如跳转到力扣官网
        resp.setHeader("Location", "https://leetcode.cn/");
    }
}

效果: 

3

         当然,servlet提供了更为简便的重定向方法,就是使用HttpServletResponse类中的sendRedirect方法。

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //格式
        resp.setContentType("text/html; charset = utf8");
        //设置状态码
//        resp.setStatus(302);
//        //设置重定向字段与地址,如跳转到力扣官网
//        resp.setHeader("Location", "https://leetcode.cn/");
        resp.sendRedirect("https://leetcode.cn/");
    }
}

效果与上面是一样的。

本期结束啦!下期见~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙洋静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值