Servlet的相关API

🔥🔥🔥🔥Hello,我是栋zzzz,先祝各位端午节快乐!!那么接下来就继续来学习Servlet吧,我给大家整理了一些前置知识,方便更好的理解Servlet:

在这里插入图片描述

这里主要掌握Servlet提供的三个类,而要掌握一个类的使用,就得熟悉一下其的各种方法的使用,下面就来看一下下面三个类的各种方法吧🎨

🍌 一.HTTPServlet

  • init():在HTTPServlet实例化后进行一些初始化的操作(只进行一次);
  • service(): 在收到HTTP请求的时候调用各种方法(可能会进行多次);
  • destroy():在HTTPServlet实例不再被使用的时候进行一些资源释放的操作(只进行一次);上述三个方法也就是Servlet的生命周期了,不过一般不会重写这三个方法,主要会重写下面的方法!
  • doGet():收到GET请求的时候调用这个方法(由service方法调用);
  • doPost():收到POST请求的时候调用这个方法(由service方法调用);
  • doPut()/doDelete()/doOptions()…:收到各种其他请求的时候调用相匹配的方法(由service方法调用);

这里使用ajax构造一个POST请求,调用doPost方法得到响应:

 <!-- 要想使用ajax就需要先引入jquery,直接去搜 -->
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "post",
            url: "method",
            success: function(body){
                console.log(body);
            }
        })
    </script>

注意url这里是相对路径,不能加/,相当于当前html所在的路径,访问这个html使用的路径是/servletMethod/method,test.html所在的路径就是/servletMehod,在这个基础上加上method总路径就是可以访问的路径,而加上/就是绝对路径了,然后两级路径就只剩下这一级路径了那当然就会出现404了;
Java代码:

//此处必须加/,这个斜杠和相对绝对路径不是一个东西,这是硬性要求
@WebServlet("/method")
public class MyHttpServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");//这样就可以指定数据的格式和编码了
        resp.getWriter().write("POST 响应");
    }
}

由于这里是使用idea其字符编码是utf8,而浏览器是GBK编码,所以直接输出中文的话,是会出现乱码的问题的,因此这里就需要统一编码才可以,因此就需要加上resp.setContentType(“text/html;charset=utf8”);然后就可以访问了,但是由于这里构造的是POST请求,因此不能直接通过url的形式来访问,因此这里就直接访问test.html页面了:
在这里插入图片描述
这里在控制台就打印出了body的内容,想要打印在页面的话,可以将内容放到dom树里面,就可以了这里就不演示了,通过fiddler也可以看到请求和响应:
请求:
在这里插入图片描述
响应:
在这里插入图片描述
在这里插入图片描述


🍌 二.HTTPServletRequest

这里的各种方法就对应到了HTTP请求报文里面有什么,这里就有什么方法:

  • getProtocol():协议名和版本号;
  • getMethod():返回HTTP请求的方法;
  • getRequestURI():返回请求的url地址的一部分;
  • getContextPath():返回上下文路径(一级路径);
  • getQueryString():返回query string(路径后的查询字符串);
  • getParameterNames():以枚举的形式返回查询字符串中的所有key值
  • getParameter():返回通过查询字符串的key值得到的value值;
  • getHeaderNames:以枚举的形式返回请求报头中的所有key值;
  • getHeader():返回通过key值获得的value值;
  • getInputStream():得到一个输出流对象,从这个对象中读取数据,就可以得到请求中的body!

🍓 1. 获取GET请求中的内容

来获取一下get请求中的内容:

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("/showRequest")
public class MyHttpServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //把api得到的结果放到stringBuilder中去,方便后面放入body
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<h3>下面是首行部分</h3>");

        //得到协议名和版本
        stringBuilder.append("协议名和版本:" + req.getProtocol());
        stringBuilder.append("<br>");
        //得到方法
        stringBuilder.append("方法:" + req.getMethod());
        stringBuilder.append("<br>");
        //得到url(请求路径)
        stringBuilder.append("url:" + req.getRequestURI());
        stringBuilder.append("<br>");
        //得到上下文路径(一级路径)
        stringBuilder.append("context path:" + req.getContextPath());
        stringBuilder.append("<br>");
        //得到query string 有?后面的内容就是query string,没有就是null
        stringBuilder.append("query string:" + req.getQueryString());
        stringBuilder.append("<br>");
        //得到header部分
        stringBuilder.append("<h3>下面是header部分</h3>");
        //枚举
        Enumeration<String> headerNames = req.getHeaderNames();
        //迭代器
        while(headerNames.hasMoreElements()){
            //通过枚举得到每一个key
            String headerName = headerNames.nextElement();
            //再通过每一个key得到对应的value
            String headerValue = req.getHeader(headerName);
            stringBuilder.append(headerName + ":" + headerValue + "<br>");
        }
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(stringBuilder.toString());

    }
}

在这里插入图片描述
这些方法中比较常用的就是getParameter(),通过查询中字符串的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;
@WebServlet("/getParameter")
public class GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //构造一个形如/getParameter?userId=10&class=20的请求,通过name得到其value
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId=" + userId + ",classId=" + classId);
    }
}

在这里插入图片描述
请求:
在这里插入图片描述

响应:
在这里插入图片描述
在这里插入图片描述

🍓 2. POST请求的body格式

通过post请求来传递参数(一般会放在body中):
而post请求的body格式:①x-www-form-urlencoded②form-data③json,一般一和三用的多一些,二用的不是很多(主要用于上传数据)

而如果请求是x-www-form-urlencoded的话,服务器获取参数的方式也是和get一样使用getParameter:

🍎 2.1 form表单格式

通过form表单:

    <form action="postParameter" method="post">
        <input type="text" name="userId">
        <input type="text" name="classId">
        <input type="submit" 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;

/**
 * Creared with IntelliJ IDEA.
 * Description:
 * User:yxd
 * Date:2022-05-30
 * Time:14:10
 */
@WebServlet("/postParameter")
public class PostRequest extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //假设传来的参数格式是形如:userId=10&classId=20
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId=" + userId + ",classId=" + classId);
    }
}

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

🍎 2.2 json格式

json方式对于body为json格式来说,如果手动解析,其实并不容易解析(json里面的字段可以嵌套),因此这里就使用第三方库来解决这个问题,而处理json的第三方库有很多,这里就使用Jackson,引入Jackson的方式将如下代码放到pom.xml的dependencies标签里面就可以了

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.6.1</version>
</dependency>

①先来写前端代码:

      <!-- 这里想要构造json格式的body就需要使用ajax来构造,就不能使用form表单来构造了 -->
    <input type="text" id="userId">
    <input type="text" id="classId">
    <input type="button" value="提交" id="submit">
    <!-- 引入jquery -->
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        let button = document.querySelector('#submit');
        let userIdInput = document.querySelector('#userId');
        let classIdInput = document.querySelector('#classId');

        button.onclick = function(){
            $.ajax({
                type: "post",
                url: "postParameter2",
                //另外contentType也是需要修改为json格式
                contentType: "application/json",
                //data就表示当前的body以什么样的方式来构造,对于post这样的请求,ajax就允许使用data属性来构造请求的body部分
                data: JSON.stringify({
                    userId: userIdInput.value,
                    classId: classIdInput.value
                }),
                success:function(body){
                    console.log(body);
                }
            })
        }
    </script>

而此处构造的body就是一个js对象,也就是这样的键值对的结构,然后把这个js对象通过JSON.stringify转成一个字符串的结构,而这个字符串的格式就正是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 int userId;
    public int classId;
}
@WebServlet("/postJson")
public class PostJsonServlet extends HttpServlet {
    //这里需要使用Jackson的核心对象:
    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //而这里就通过Jackson的对象把请求中的内容给读取出来
        //有两个参数,第一个参数表示把哪个字符串进行转换,可以是一个String,也可以是一个inputStream,也可以是一个file,
        //第二个参数表示要把读出来的JSON字符串放到哪个java对象里面
        User user = objectMapper.readValue(req.getInputStream(),User.class);//(.class)
        //然后这个对象里面的所能匹配的属性就表示了读取出来的JSON内容了
        resp.getWriter().write("userId: " + user.userId + ",classId: " + user.classId);
    }
}

在这里插入图片描述
请求:在这里插入图片描述
响应:
在这里插入图片描述
通过JSON的格式构造body也就完成了!!!

🍓 3.postman

postman:可以直接使用一个第三方软件来模拟构造请求来获取响应

在这里插入图片描述
这样直接就可以获得响应了,就方便很多了!!!
在这里插入图片描述


🍌 三.HTTPServletResponse

这里的各种方法就对应到了HTTP响应报文里面有什么,这里就有什么方法:

  • setStatus():为该响应设置状态码;
  • setHeader():设置一个带有给定名称和值的header,如果name已存在,就会覆盖旧的值;
  • addHeader():添加一个带有给定名称和值的header,如果name已经存在,就再添加新的键值对;
  • setContentType():设置被发送到客户端的响应的内容类型;
  • setCharacterEncoding():设置被发送到客户端的响应的字符编码;
  • sendRedirect():构造一个302重定向响应;
  • getWrite():往body里面写数据;
  • getOutputStream();往body里面写入二进制格式数据;

下面通过一些例子来演示一下上面的方法:

🍓 1. 设置状态码

通过直接改状态码,就可以来改变返回的响应的状态码

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.setStatus(404);
        resp.getWriter().write("hello");
    }
}

可以获得的响应:
在这里插入图片描述

在这里插入图片描述
这里可以看到虽然响应是404,但是页面依然打印了hello,所以这里的状态码只是在告诉浏览器,当前的响应是什么状态的,而并不会影响到浏览器去正常显示body内容!

🍓 2. 自动刷新页面

通过设置setHeader就可以实现自动刷新页面的效果:


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 AutoRefresh extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过设置setHeader就可以实现自动刷新
        //第一参数就表示刷新,第二个参数表示每隔一秒刷新一次
        resp.setHeader("Refresh","1");
        //保证不会乱码
        resp.setContentType("text/html;charset=utf8");
        //为了更明显的看出来页面有刷新的痕迹,这里就设置一个时间戳
        resp.getWriter().write("当前时间戳:" + System.currentTimeMillis());
    }
}

在这里插入图片描述
在这里插入图片描述
时间也是在不停的发生变化,而且通过fiddler抓取看到的也是有很多请求和响应:
在这里插入图片描述
这样一个自动刷新页面的效果也就出来了!!!

🍓 3. 构造一个重定向响应

通过修改状态码和header就可以实现重定向:


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.setStatus(302);
        //在通过设置setHeader的方式来构造重定向页面,这里直接跳转到搜狗主页
        resp.setHeader("Location","https://www.sogou.com");
    }
}

然后输入url:http://127.0.0.1:8080/servletMethod/redirect,就可以直接重定向到搜狗主页了
在这里插入图片描述
通过响应也可以看出来:
在这里插入图片描述
Servlet提供了更简单的构造重定向的方法sendRedirect,通过这一个方法就可以直接实现重定向了:


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.sendRedirect("https://www.sogou.com");
    }
}

在这里插入图片描述
也可以实现和上面同样的效果!!!
在这里插入图片描述

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 47
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

栋zzzz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值