Servlet学习笔记(一)--HttpServlet实现doGet和doPost请求的原理


Servlet--HttpServlet实现doGet和doPost请求的原理

本文转载自两个文章,主要介绍了Servlet和HttpServlet中的service()函数,他们的区别和不能覆盖的原因。以及当访问一个地址时,doGet()和doPost()函数都是如何工作的。其中还有一个实例以及两个service的源码。

https://blog.csdn.net/truong/article/details/17038687

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代码展示

     

[java]  view plain  copy
  1. package httpserve;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. public class HttpServ extends HttpServlet {  
  12.   
  13.       
  14.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  15.             throws ServletException, IOException {  
  16.           
  17.         System.out.println("发送get请求。。。。。。。。。。。");  
  18.           
  19.     }  
  20.   
  21.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  22.             throws ServletException, IOException {  
  23.         // TODO Auto-generated method stub  
  24.         resp.setContentType("text/html;charset=UTF-8");  
  25.         System.out.println("发送post方法。。。。。。。。。。");  
  26.     }  
  27.   
  28. }  

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

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="3.0"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
  6.   <servlet>  
  7.     <description>This is the description of my J2EE component</description>  
  8.     <display-name>This is the display name of my J2EE component</display-name>  
  9.     <servlet-name>HttpServ</servlet-name>  
  10.     <servlet-class>httpserve.HttpServ</servlet-class>  
  11.   </servlet>  
  12.   
  13.   <servlet-mapping>  
  14.     <servlet-name>HttpServ</servlet-name>  
  15.     <url-pattern>/http</url-pattern>  
  16.   </servlet-mapping>  
  17.   
  18. </web-app>  


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

[html]  view plain  copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'index.jsp' starting page</title>  
  13.     <meta http-equiv="pragma" content="no-cache">  
  14.     <meta http-equiv="cache-control" content="no-cache">  
  15.     <meta http-equiv="expires" content="0">      
  16.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  17.     <meta http-equiv="description" content="This is my page">  
  18.     <!-- 
  19.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  20.     -->  
  21.   </head>  
  22.     
  23.   <body>  
  24.     This is my JSP page. <br>  
  25.     <a href="http://localhost:8080/test06/http">get请求1</a><br/>  
  26.     <!-- 对于一个html页面来说,如果没有以http开始,则默认的前面会加上  
  27.         协议类型://目前这个页面所在的服务器:目前端口/目前项目/你给的这个名称 -->  
  28.     <a href="http">get请求2</a><hr/>  
  29.     <form method = "post" action="http">  
  30.         <input type="submit" value="提交"/>  
  31.     </form>  
  32.   </body>  
  33. </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、浏览器发送请求到HttpServ类调用HttpServ的service(servletRequest, servletReponse)方法

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

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

该方法在HttpSevlet的父类中。

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

[java]  view plain  copy
  1. public void service(ServletRequest req, ServletResponse res)  
  2.        throws ServletException, IOException {  
  3.   
  4.        HttpServletRequest  request;  
  5.        HttpServletResponse response;  
  6.          
  7.        try {  
  8.            request = (HttpServletRequest) req;  
  9.            response = (HttpServletResponse) res;  
  10.        } catch (ClassCastException e) {  
  11.            throw new ServletException("non-HTTP request or response");  
  12.        }  
  13.        service(request, response);  
  14.    }  

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

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

[java]  view plain  copy
  1. protected void service(HttpServletRequest req, HttpServletResponse resp)  
  2.       throws ServletException, IOException {  
  3.   
  4.       String method = req.getMethod();  
  5.   
  6.       if (method.equals(METHOD_GET)) {  
  7.           long lastModified = getLastModified(req);  
  8.           if (lastModified == -1) {  
  9.               // servlet doesn't support if-modified-since, no reason  
  10.               // to go through further expensive logic  
  11.               doGet(req, resp);  
  12.           } else {  
  13.               long ifModifiedSince;  
  14.               try {  
  15.                   ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);  
  16.               } catch (IllegalArgumentException iae) {  
  17.                   // Invalid date header - proceed as if none was set  
  18.                   ifModifiedSince = -1;  
  19.               }  
  20.               if (ifModifiedSince < (lastModified / 1000 * 1000)) {  
  21.                   // If the servlet mod time is later, call doGet()  
  22.                   // Round down to the nearest second for a proper compare  
  23.                   // A ifModifiedSince of -1 will always be less  
  24.                   maybeSetLastModified(resp, lastModified);  
  25.                   doGet(req, resp);  
  26.               } else {  
  27.                   resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);  
  28.               }  
  29.           }  
  30.   
  31.       } else if (method.equals(METHOD_HEAD)) {  
  32.           long lastModified = getLastModified(req);  
  33.           maybeSetLastModified(resp, lastModified);  
  34.           doHead(req, resp);  
  35.   
  36.       } else if (method.equals(METHOD_POST)) {  
  37.           doPost(req, resp);  
  38.             
  39.       } else if (method.equals(METHOD_PUT)) {  
  40.           doPut(req, resp);          
  41.             
  42.       } else if (method.equals(METHOD_DELETE)) {  
  43.           doDelete(req, resp);  
  44.             
  45.       } else if (method.equals(METHOD_OPTIONS)) {  
  46.           doOptions(req,resp);  
  47.             
  48.       } else if (method.equals(METHOD_TRACE)) {  
  49.           doTrace(req,resp);  
  50.             
  51.       } else {  
  52.           //  
  53.           // Note that this means NO servlet supports whatever  
  54.           // method was requested, anywhere on this server.  
  55.           //  
  56.   
  57.           String errMsg = lStrings.getString("http.method_not_implemented");  
  58.           Object[] errArgs = new Object[1];  
  59.           errArgs[0] = method;  
  60.           errMsg = MessageFormat.format(errMsg, errArgs);  
  61.             
  62.           resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);  
  63.       }  
  64.   }  

解释:如果自己写的servlet中覆盖了service函数,就无法实现doGet()等函数的原因?

  1. 从上面可以看出 这里的service是用来转向的但是如果你在自己的servlet类中覆盖了service方法,比如说你的service是这样的: 
  2.  
  3. Java代码 
  4.  
  5.    1.publicvoid service(ServletRequest req, ServletResponse res)    
  6.    2.                   throws ServletException, IOException {    
  7.    3.          res.getOutputStream().print(    
  8.    4.         "image is <img src='images/downcoin.gif'></img><br>");    
  9.    5.      }   

    1. 那么这时service就不是用来转向的,而是用来处理业务的,现在不论你的客户端是用pos还是get来请求此servlet 
    2.  
    3. 都会执行service方法也只能执行servlet方法,不会去执行doPost或是doGet方法。 
    4.  
    5. 比如说:你的客户端代码是: 
    6. Java代码 
    7.  
    8.    1. <%@page contentType="text/html; charset=utf-8"%>    
    9.    2. <html>    
    10.    3. <head><title>选择</title></head>    
    11.    4. <body>    
    12.    5. 请选择你喜欢的水果:<br>    
    13.    6. <form action ="Test" method = "post">    
    14.    7. <input type="checkbox" name="fruit" value ="apple" >苹果<br>    
    15.    8. <input type="checkbox" name="fruit" value ="orange">桔子<br>    
    16.    9. <input type="checkbox" name="fruit" value ="mango">芒果<br>    
    17.   10. <input type="submit" value="提交">    
    18.   11. </form>    
    19.   12. </body>    
    20.   13. </html>    
    21.   14.    
    22.   15. 服务端servlet是:Test类    
    23.   16.    
    24.   17.import java.io.IOException;    
    25.   18.    
    26.   19.import javax.servlet.ServletException;    
    27.   20.import javax.servlet.ServletOutputStream;    
    28.   21.import javax.servlet.ServletRequest;    
    29.   22.import javax.servlet.ServletResponse;    
    30.   23.import javax.servlet.http.HttpServlet;    
    31.   24.import javax.servlet.http.HttpServletRequest;    
    32.   25.import javax.servlet.http.HttpServletResponse;    
    33.   26.    
    34.   27./**
    35.   28. * 演示service方法
    36.   29. */   
    37.   30.publicclass Testextends HttpServlet {    
    38.   31.    
    39.   32.publicvoid service(ServletRequest req, ServletResponse res)    
    40.   33.   throws ServletException, IOException {    
    41.   34.             res.getOutputStream().print("This is the service");    
    42.   35.    
    43.   36. }    
    44.   37.    
    45.   38.protectedvoid doGet(HttpServletRequest request,    
    46.   39.     HttpServletResponse response)throws ServletException, IOException {    
    47.   40.    doPost(request,response);    
    48.   41.    
    49.   42. }    
    50.   43.protectedvoid doPost(HttpServletRequest request,    
    51.   44.     HttpServletResponse response)throws ServletException, IOException {    
    52.   45.    ServletOutputStream out=response.getOutputStream();    
    53.   46.    String[] args=(String[])request.getParameterValues("fruit");    
    54.   47.  for(int i=0;i<args.length;i++){    
    55.   48.     out.print(args[i]+"<br>");    
    56.   49.    }    
    57.   50.       
    58.   51. }    
    59.   52. }   
    60. 点击提交后:页面输出结果为“This is the service“;

    61. 所以,我们在写servlet的时候,一般都是重写doGet或doPost方法,不会管service方法。


5、调用关系图



、注意事项:

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

因为service(ServletRequest,SerlvetResonse)是最高接口Servlet定义规范。

在tomcat调用时,一定会在最终的子类中去找这个方法且调用它。

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

具体原因上面提到了。

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


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HttpServlet类是Java Servlet API中的一个类,它提供了处理HTTP请求的方法。其中,doGet()和doPost()是两个最常用的方法。 doGet()方法用于处理HTTP GET请求,它通常用于获取数据或者显示页面。当客户端发送一个HTTP GET请求时,Servlet容器会调用doGet()方法来处理请求doPost()方法用于处理HTTP POST请求,它通常用于提交数据或者执行一些操作。当客户端发送一个HTTP POST请求时,Servlet容器会调用doPost()方法来处理请求。 需要注意的是,doGet()和doPost()方法都需要重写,以实现自定义的处理逻辑。在重写这两个方法时,需要根据具体的业务需求来实现相应的功能。 ### 回答2: HttpServlet是Java Servlet API中的一个类,用于处理客户端的HTTP请求和响应。在HttpServlet中,doGetdoPost是两个最基本和经常被使用的方法。 doGet方法是处理HTTP的GET请求,即获取数据。这个方法通常被用来从服务器获取一些信息并返回给客户端。当Web浏览器请求一个网页时,就会发起一个GET请求,服务器则会根据这个请求返回相应的内容。使用doGet方法实现该功能非常简单。 doPost方法是处理HTTP的POST请求,即提交数据。这个方法通常被用来接受客户端提交的一些数据,并对这些数据进行处理并返回结果。当用户在Web页面上提交表单时,就会发起一个POST请求,服务器则会根据这个请求对表单中的数据进行处理。使用doPost方法实现该功能也是非常简单的。 在有些情况下,使用doGetdoPost是不够的。例如,当一个Web应用程序需要处理HTTP的PUT或DELETE请求时,就不能使用doGetdoPost方法了。这时,我们需要使用其他的方法完成对客户端的响应。 总的来说,doGetdoPost方法是Java Servlet API中最基本和常用的两个方法之一。它们的主要区别是doGet方法用于获取数据,而doPost方法用于提交数据。虽然在某些情况下,我们需要使用其他的方法完成特别的需求,但在大多数情况下,我们都可以使用doGetdoPost方法实现Web应用程序的主要功能。 ### 回答3: Servlet 是用来处理 Web 请求的 Java 程序。HTTPServlet 是 javax.servlet.http 包中的一个类,是 Servlet 的一个子类,它提供了基于 HTTP 请求的 Web 服务。HTTP 请求可以通过 GET 和 POST 两种方法提交,通常用于查询和提交数据。在 HTTPServlet 中,doGet() 和 doPost() 方法用来处理这两种请求,它们的主要区别在于提交的数据量和提交方式。 doGet() 方法用于处理 GET 请求,即通过浏览器地址栏输入 URL 或者通过链接访问服务器时,服务器返回请求的资源。GET 请求提交的数据通常是在 URL 的参数部分追加一个字符串,为键值对的形式,可以在服务器端进行解析。例如: http://localhost:8080/TestServlet?username=admin&password=123456 在这个例子中,“?” 后面的内容就是 GET 请求提交的数据,可以通过 HttpServletRequest 对象的 getParameter() 方法获取到每一个参数的值。 而 doPost() 方法用于处理 POST 请求,它通常用于提交表单和上传文件等需要提交大量数据的场景。POST 请求把数据存储在请求头部,数据量比 GET 请求大。在 doPost() 中,可以通过 HttpServletRequest 对象的 getInputStream() 和 getReader() 方法获取请求的数据,然后对数据进行解析。 总的来说,它们的区别主要在于请求的提交方式和数据量大小。GET 请求通常用于查询和获取静态资源,而 POST 请求则适合用于提交大量数据和实现用户互动。在实际开发中,可以根据不同的应用场景选择适合的方式来处理请求,提高服务器的性能和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值