Servlet中请求对应的方法

GET 请求

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

在 Service 中:

 检查之前是否访问过,如果没有访问过,调用doGet

 否则获取If-Modified-Since属性。

 注: If-Modified-Since是标准的HTTP请求头标签,在发送HTTP请求时,把浏览器端缓存页面的最后修改时间一起发到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行比较。如果时间一致,那么返回HTTP状态码304(不返回文件内容),客户端接到之后,就直接把本地缓存文件显示到浏览器中。如果时间不一致,就返回HTTP状态码200和新的文件内容,客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示到浏览器中。

 参考链接1:https://www.cnblogs.com/moxiaotao/p/9670109.html

 参考链接2:https://blog.csdn.net/weixin_34023863/article/details/92065577

 HttpServlet假装实现了这个功能,其实并没有。因为getLastModified方法始终返回-1。我们可以同重写该方法去覆盖HttpServlet的getLastModified。

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);
        } else {
            long ifModifiedSince = req.getDateHeader("If-Modified-Since");
            if (ifModifiedSince < lastModified) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } 
    ...
}

protected long getLastModified(HttpServletRequest req) {
    return -1L;
}

实验:

 重写getLastModified方法, 然后利用http_request、postman、burp等工具去构造请求

@Override
protected long getLastModified(HttpServletRequest req) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(2021, Calendar.FEBRUARY, 1, 1, 1, 1);
    Date date = calendar.getTime();
    return date.getTime();
}

 构造请求

GET /basic/Exp2 HTTP/1.1
Host: localhost:8080
GET /basic/Exp2 HTTP/1.1
Host: localhost:8080
If-Modified-Since: Fri, 26 Feb 2022 18:00:01 GMT

实验结果:

 第一条请求返回200 OK, 第二条请求返回304 Not Modified

POST 请求

POST 请求通常来自于一个特别指定了 METHOD 为 POST 的 HTML 表单、或者客户端需要传输实体,它由 doPost() 方法处理。

可以重写doPost方法去解决请求。

实验:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    logger.info("doPost_HttpServletRequest_HttpServletResponse single parameter:" + request.getParameter("test_single_parameter"));
    for(String mp : request.getParameterValues("test_multi_parameter")) {
        logger.info("doPost_HttpServletRequest_HttpServletResponse multi parameter:" + mp);
    }
    Enumeration<String> ap = request.getParameterNames();
    while (ap.hasMoreElements()) {
        logger.info("doPost_HttpServletRequest_HttpServletResponse :" + ap.nextElement());
    }
}

构造请求:

POST /basic/Exp2 HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: f9b026c5-5ea6-0af6-30d8-f4133f80b97a

test_single_parameter=1&test_multi_parameter=2&test_multi_parameter=3&test_other_parameter=4

实验结果:

doPost_HttpServletRequest_HttpServletResponse single parameter:1
doPost_HttpServletRequest_HttpServletResponse multi parameter:2
doPost_HttpServletRequest_HttpServletResponse multi parameter:3
doPost_HttpServletRequest_HttpServletResponse: test_single_parameter
doPost_HttpServletRequest_HttpServletResponse: test_multi_parameter
doPost_HttpServletRequest_HttpServletResponse: test_other_parameter

实验结果

HEAD 请求

检查一个对象是否存在, HttpServlet实现了该方法,此请求通常无需复写。

protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    NoBodyResponse response = new NoBodyResponse(resp);
    this.doGet(req, response);
    response.setContentLength();
}

PUT 请求

向Web服务器发送数据并存储在Web服务器内部

DELETE 请求

从Web服务器上删除一个文件

OPTIONS 请求

查询Web服务器的性能

TRACE 请求

跟踪到服务器的路径

HttpServlet 中 doGet、doPost、doPut、doDelete的默认行为

注:400:告诉客户端它发送了一条异常请求。400页面是当用户在打开网页时,返回给用户界面带有400提示符的页面。其含义是你访问的页面域名不存在或者请求错误。主要分为两种。1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。2、请求参数有误。

注:405:请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。


protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_get_not_supported");
    if (protocol.endsWith("1.1")) {
        resp.sendError(405, msg);
    } else {
        resp.sendError(400, msg);
    }
}

出于以上环节,重写doGet、doPost、doPut、doDelete的时候不能调用super.doGet()、super.doPost()、super.doPut()、super.doPut()、super.doDelete()