• Servlet--HttpServlet实现doGet和doPost请求的原理(转)


    • Servlet(Server Applet):全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。
      • 狭义的Servlet是指 Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
    • HttpServlet: 指能够处理 HTTP 请求的 servlet,它在原有 Servlet 接口上添加了一些与 HTTP 协议处理方法,它比 Servlet 接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
      • HttpServlet 在实现 Servlet 接口时,覆写了 service 方法,该方法体内的代码会自动判断用户的请求方式,如为 GET 请求,则调用 HttpServlet 的 doGet 方法,如为 Post 请求,则调用 doPost 方法。因此,开发人员在编写 Servlet 时,通常只需要覆写 doGet 或 doPost 方法,而不要去覆写 service 方法。

      参考:https://blog.csdn.net/HeatDeath/article/details/79057168

      

    转:https://blog.csdn.net/m0_38039437/article/details/75264012

    一、HttpServlet简介

    1、HttpServlet是GenericServlet的子类,又是在GenericServlet的基础上做了增强。

     2、HttpServlet方法

    二、HTTP实现doGet或doPost请求项目介绍

    1、通过实现doGet请求和doPost请求实例来了解内部的工作原理。

    2、doGet请求和doPost请求实例代码介绍:

      A:创建一个Servlet类继承HttpServlet类

      B:在index.jsp页面创建一个超链接请求

    3、doGet请求和doPost请求实例实施介绍:

      A、创建一个webproject项目。

       

      B、创建一个Servlet类的名称为HttpServ继承HttpServlet类同时覆写doGet方法和doPost方法。

    1、

     

    2、

     

    3、配置web.xml文件

     

    4、创建Servlet代码展示

    复制代码
    package httpserve;
     
    import java.io.IOException;
    import java.io.PrintWriter;
     
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    public class HttpServ extends HttpServlet {
     
        
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            System.out.println("发送get请求。。。。。。。。。。。");
            
        }
     
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            resp.setContentType("text/html;charset=UTF-8");
            System.out.println("发送post方法。。。。。。。。。。");
        }
    复制代码

    5、web.xml配置文件代码展示

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <servlet>
        <description>This is the description of my J2EE component</description>
        <display-name>This is the display name of my J2EE component</display-name>
        <servlet-name>HttpServ</servlet-name>
        <servlet-class>httpserve.HttpServ</servlet-class>
      </servlet>
     
      <servlet-mapping>
        <servlet-name>HttpServ</servlet-name>
        <url-pattern>/http</url-pattern>
      </servlet-mapping>
     
    </web-app>
    复制代码

    C、在index.jsp页面创建一个超链接请求

    复制代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
      </head>
      
      <body>
        This is my JSP page. <br>
        <a href="http://localhost:8080/test06/http">get请求1</a><br/>
        <!-- 对于一个html页面来说,如果没有以http开始,则默认的前面会加上
            协议类型://目前这个页面所在的服务器:目前端口/目前项目/你给的这个名称 -->
        <a href="http">get请求2</a><hr/>
        <form method = "post" action="http">
            <input type="submit" value="提交"/>
        </form>
      </body>
    </html>
    复制代码

    D、发送doGet请求和doPost请求

    a、在浏览器中输入测试地址,http://127.0.0.1:8080/test06/

    b、打开项目的首页后分别点击get请求1、get请求2、和 post请求(提交按钮)

    c、在控制台可以观察到分别调用了doGet和doPost方法。

    三、HTTP实现doGet或doPost请求原理介绍

      1、浏览器发送请求到HttpSevr类调用HttpServ的service(servletRequest, servletReponse)方法

      2、由于没有找到这个方法,去调用父类(HttpServlet) 的同名方法。

      3、父类的service方法将ServletRequest req请求转换成HttpServletRequest请求,再去调用service(request, response) 方法。

     将ServletRequest req请求转换成HttpServletRequest请求再调用service(request, response) 方法源码如下:

    复制代码
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
     
            HttpServletRequest  request;
            HttpServletResponse response;
            
            try {
                request = (HttpServletRequest) req;
                response = (HttpServletResponse) res;
            } catch (ClassCastException e) {
                throw new ServletException("non-HTTP request or response");
            }
            service(request, response);
        }
    复制代码

    4、 调用的service(request, response) 方法功能是判断用户发出是什么请求,如果是get则调用子类(HttpSevr)的doGet方法,如果是post则调用子类(HttpSevr)的doPost方法。

    service(request, response) 方法源码如下:

    复制代码
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
     
            String method = req.getMethod();
     
            if (method.equals(METHOD_GET)) {
                long lastModified = getLastModified(req);
                if (lastModified == -1) {
                    // servlet doesn't support if-modified-since, no reason
                    // to go through further expensive logic
                    doGet(req, resp);
                } else {
                    long ifModifiedSince;
                    try {
                        ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                    } catch (IllegalArgumentException iae) {
                        // Invalid date header - proceed as if none was set
                        ifModifiedSince = -1;
                    }
                    if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                        // If the servlet mod time is later, call doGet()
                        // Round down to the nearest second for a proper compare
                        // A ifModifiedSince of -1 will always be less
                        maybeSetLastModified(resp, lastModified);
                        doGet(req, resp);
                    } else {
                        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    }
                }
     
            } else if (method.equals(METHOD_HEAD)) {
                long lastModified = getLastModified(req);
                maybeSetLastModified(resp, lastModified);
                doHead(req, resp);
     
            } else if (method.equals(METHOD_POST)) {
                doPost(req, resp);
                
            } else if (method.equals(METHOD_PUT)) {
                doPut(req, resp);        
                
            } else if (method.equals(METHOD_DELETE)) {
                doDelete(req, resp);
                
            } else if (method.equals(METHOD_OPTIONS)) {
                doOptions(req,resp);
                
            } else if (method.equals(METHOD_TRACE)) {
                doTrace(req,resp);
                
            } else {
                //
                // Note that this means NO servlet supports whatever
                // method was requested, anywhere on this server.
                //
     
                String errMsg = lStrings.getString("http.method_not_implemented");
                Object[] errArgs = new Object[1];
                errArgs[0] = method;
                errMsg = MessageFormat.format(errMsg, errArgs);
                
                resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
            }
        }
    复制代码

    5、调用关系图

    四、注意事项:

    1、如果在HttpServ中覆盖了service(ServletRequest,SerlvetResonse)方法则这个类的所实现的doGet/doPost都不会再执行了。

    因为service(ServletRequest,SerlvetResonse)是最高接口Servlet定义规范。在tomcat调用时,一定会在最终的子类中去找这个方法且调用它。

           如果最终的子类没有则会调用父的service(ServletRequest,SerlvetResonse)。

    2、如果覆盖了serivce(HttpServletRequest,HtpServletResponse)则会执行httpServlet中的service(ServletRequest,SerlvetResonse),但是由于子类中已经覆盖了serivce(HttpServletRequest,HtpServletResponset)所以,httpServlet中的serivce(HttpServletRequest,HtpServletResponset)就不再执行了,而是直接执行子类中同名同参数方法,且doXxxx也不会执行了,因为子类的serivce(HttpServletRequest,HtpServletResponset)没有调用doXxxx.

    3、如果继承了HttpServlet没有实现任何的doXxx方法则会抛出一个异常

     五:客户端请求和返回数据用到的常用方法 https://www.cnblogs.com/xdp-gacl/p/3798347.html

  • 相关阅读:
    $.getJSON()
    seconds
    ini_set
    validation
    component
    ini_set();
    长期阅读英文技术博客的好处
    用xml还是json
    单​手​打​字
    洛谷P1141 01迷宫
  • 原文地址:https://www.cnblogs.com/wxdlut/p/14949782.html
Copyright © 2020-2023  润新知