博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HttpServlet中的service()、doPost()、doGet()方法解析
阅读量:3942 次
发布时间:2019-05-24

本文共 4678 字,大约阅读时间需要 15 分钟。

1.service()方法源码解析

先来看HttpServlet的service()方法:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取http request的method参数,其实就是html的form标签 //中method属性对应的字符串 String method = req.getMethod(); long errMsg; //判断请求方式 if(method.equals("GET")) {
//获取最后被修改时间 errMsg = this.getLastModified(req); if(errMsg == -1L) {
/**如果servlet不支持http request header的if-modified-since属性 * 则继续处理 **/ this.doGet(req, resp); } else {
//如果支持这个属性 long ifModifiedSince; try {
ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException var9) {
ifModifiedSince = -1L; } /** * 如果客户端的文件最后修改时间和服务器端的文件最后修改时间一致则返回304不需要修改状态 * 这样服务器就不返回html,浏览器读取本地缓存文件,否则重新获取服务器端的对应html文件 **/ if(ifModifiedSince < errMsg / 1000L * 1000L) {
this.maybeSetLastModified(resp, errMsg); this.doGet(req, resp); } else {
resp.setStatus(304); } } } else if(method.equals("HEAD")) {
errMsg = this.getLastModified(req); this.maybeSetLastModified(resp, errMsg); this.doHead(req, resp); } else if(method.equals("POST")) {
this.doPost(req, resp); } else if(method.equals("PUT")) {
this.doPut(req, resp); } else if(method.equals("DELETE")) {
this.doDelete(req, resp); } else if(method.equals("OPTIONS")) {
this.doOptions(req, resp); } else if(method.equals("TRACE")) {
this.doTrace(req, resp); } else {
//如果请求不是以上的所有请求方式,该方法就会响应501错误,也就是不支持这种请求 String errMsg1 = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[]{
method}; errMsg1 = MessageFormat.format(errMsg1, errArgs); resp.sendError(501, errMsg1); } } public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request; HttpServletResponse response; try {
request = (HttpServletRequest)req; response = (HttpServletResponse)res; } catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response"); } this.service(request, response);}

       显然HttpServlet这个类里面有两个service()方法。首先要知道的是用户自定义的Servlet都是HttpServlet的子类,也就是要继承HttpServlet,而HttpServlet是从GenericServlet继承而来,GenericServlet类要实现javax.servlet.Servlet接口。而GenericServlet类提供的除service()方法以外所有接口方法都默认实现。所以service()是一个抽象方法,GenericServlet的派生类必须对该方法覆写才能实现期望的业务逻辑。

       先说以上HttpServlet的第二种service()方法,该方法是来自父类GenericServletHttpServlet将其覆写。该方法收到客服端请求后,创建request对象和response对象,并强制转化为HttpServletRequestHttpServletResponse类型的对象,在处理请求期间发生错误,会主动抛出异常。最后调用HttpServlet自身的service()方法,也就是第一种service()方法。

       然后我们来看第一种service()方法,客服端发送请求至服务器端,服务器将请求发送到Servlet,首先会调用init()方法初始化Servlet,然后Servlet的执行时期会调用service()方法,该方法会自动判断来自客服端的请求方式,根据不同请求方式调用不同方法,如果是get请求,则调用doGet()方法,如果是post请求,则调用doPost()方法。我们可以看到里面的请求方式有HEAD、GET、POST、DELETE、OPTIONS、TRACE。

       根据不同的请求会调用不同方法,当我们使用这些方法时根据不同的需求重写方法实现业务逻辑。如果请求不是以上的所有请求方式,该方法就会响应501错误,也就是不支持这种请求。处理完请求后自然要返回响应,最后调用destory()方法销毁Servlet。

在这里插入图片描述

2.doGet()和doPost()方法源码解析

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取协议 String protocol = req.getProtocol(); //获取http.method_get_not_supported的国际化字符串 String msg = lStrings.getString("http.method_get_not_supported"); if(protocol.endsWith("1.1")) {
//如果是HTTP/1.1,返回405禁止访问方法错误 resp.sendError(405, msg); } else {
//如果不是HTTP/1.1,返回400错误的请求错误 resp.sendError(400, msg); } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if(protocol.endsWith("1.1")) {
resp.sendError(405, msg); } else {
resp.sendError(400, msg); } }

       两个方法如果不被重写,那执行时默认会调用HttpServlet的代码,首先获取协议,然后获取国际化字符串,最后判断协议,

(1)如果协议为HTTP/1.1,返回405禁止访问方法错误;
(2)如果不是HTTP/1.1,返回400错误的请求错误。

原文链接:HttpServlet中的service()、doPost()、doGet()方法解析(仅用于学习,如有侵权联系我!!!)

转载地址:http://xejwi.baihongyu.com/

你可能感兴趣的文章
color vector using in plotting example points and lines between corresponding vertices
查看>>
mex 里面调用matlab函数
查看>>
matlab中cuda编程中分配grid和block dimension的时候的注意事项
查看>>
GPU CUDA and MEX Programming
查看>>
arrayfun用法
查看>>
矩阵积分
查看>>
optimization on macOS
查看>>
Template-Based 3D Model Fitting Using Dual-Domain Relaxation
查看>>
install libfreenect2 on ubuntu 16.04
查看>>
how to use automake to build files
查看>>
using matlab drawing line graph for latex
查看>>
How package finding works
查看>>
build opencv3.3.0 with VTK8.0, CUDA9.0 on ubuntu9.0
查看>>
how to compile kinfu_remake with cuda 9.0 opencv2.4.13.4
查看>>
qtcreator4.4.1中cmake 与cmake3.5.1本身generate出来的setting是有区别的解决方法
查看>>
ubuntu下解决csdn网页打不开的问题
查看>>
MySQL server has gone away 问题的解决方法
查看>>
MySQL十大优化技巧
查看>>
PHP中文件读写操作
查看>>
php开发常识b_01
查看>>