`
lushuaiyin
  • 浏览: 704927 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

HttpServlet机制研究

 
阅读更多

写个例子吧

SignContractServlet

package org.test;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SignContractServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	public void destroy(){
		super.destroy();
		System.out.println(SignContractServlet.class.getName()+" is destried");
	}
	public void init()throws ServletException{
		System.out.println(SignContractServlet.class.getName()+" is inited");
    }
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("doGet here is SignContractServlet");
		doPost(req, resp);
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("doPost here is SignContractServlet");
		
		//所有访问都被转到这里,在这里进行编码设置,防止乱码。
		resp.setContentType("text/xml");
		resp.setHeader("Cache-Control", "no-cache");
		resp.setCharacterEncoding("UTF-8");
		
//		resp.sendRedirect("");
	}

	//如果有此方法,servlet默认走此方法,而不走doGet和doPost,在实际中我们可以把这个方法改革名字作为一个处理业务逻辑的方法
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("service here is revoking.I am the default method.");
	}
	
	
}

web.xml配置:

    <servlet>
		<servlet-name>signContractServlet</servlet-name>
		<servlet-class>
			 org.test.SignContractServlet
		</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>signContractServlet</servlet-name>
		<url-pattern>/crm/SignContractServlet</url-pattern>
	</servlet-mapping>

访问
http://localhost:8080/frame/crm/SignContractServlet

看后台打印:
org.test.SignContractServlet is inited
service here is revoking.I am the default method.

现在是不是有点奇怪了?doGet,doPost方法没被调用?是的,没被调用。
网上查了下,HttpServlet类中有个service方法:

protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException

这个方法处理请求,他会判断你的请求类型。
就好比是个代理,帮你处理所有请求,请求类型自动帮你判断。所以我们重写的
doGet,doPost方法就没被调用。

好了,现在为了调用doGet,doPost方法,我们把service方法注释掉(或者改个名字)。
再试一次,打印:

org.test.SignContractServlet is inited
doGet here is SignContractServlet
doPost here is SignContractServlet

结果已经证明就是如此。
现在我们看看这个service方法到底是什么玩意,HttpServlet源码中:

    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();
        if(method.equals("GET"))
        {
            long lastModified = getLastModified(req);
            if(lastModified == -1L)
            {
                doGet(req, resp);
            } else
            {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if(ifModifiedSince < (lastModified / 1000L) * 1000L)
                {
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else
                {
                    resp.setStatus(304);
                }
            }
        } else
        if(method.equals("HEAD"))
        {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else
        if(method.equals("POST"))
            doPost(req, resp);
        else
        if(method.equals("PUT"))
            doPut(req, resp);
        else
        if(method.equals("DELETE"))
            doDelete(req, resp);
        else
        if(method.equals("OPTIONS"))
            doOptions(req, resp);
        else
        if(method.equals("TRACE"))
        {
            doTrace(req, resp);
        } else
        {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object errArgs[] = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }
    }

源码之中,我们看到,service方法首先获取到请求的类型:
String method = req.getMethod();
类型有7个,分别是:
GET,HEAD,POST,PUT,DELETE,OPTIONS,TRACE。
如果有例外,就报出一个501错误,resp.sendError(501, errMsg);
这个方法我们最好不好重写,为什么呢?因为它已经有了自己的逻辑。
我们重写只会破坏它原本的逻辑。


还有为什么会有这7个请求类型呢?
网上搜到的资料:


#################################################################

HTTP 目前支持 7 种请求方法: GET 、 POST 、 PUT 、 DELETE 、 TARCE、HEAD 、 OPTIONS .
前四个都是客户端请求数据这类相关的方法.

GET 请求获取由Request-URI所标识的资源。
POST 在Request-URI所标识的资源后附加新的数据。
PUT 请求服务器存储一个资源,并用Request-URI作为其标识。
DELETE 请求服务器删除由Request-URI所标识的资源。

TRACE 请求服务器回送收到的请求信息,主要用语测试或诊断。
HEAD 请求获取由Request-URI所标识的资源的响应消息报头。
OPTIONS 请求查询服务器的性能,或查询与资源相关的选项和需求。

#################################################################

我们再看看HttpServlet的源码,下面手机所有方法:

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
protected long getLastModified(HttpServletRequest req)
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
private static Method[] getAllDeclaredMethods(Class c)
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
protected void service(HttpServletRequest req, HttpServletResponse resp)
private void maybeSetLastModified(HttpServletResponse resp, long lastModified)
public void service(ServletRequest req, ServletResponse res)
上面确实有对应的7个get方法,而service方法就是这7个的一个综合服务。
其实客户端使用的请求只有上面4个,GET 、 POST 、 PUT 、 DELETE 。对应
4个方法,doGet,doPost,doPut,doDelete。
而我们最常用的就是doGet,doPost方法,这2个方法的区别简单是一个是get请求,参数在url后,
在地址栏会看到,长度也有限制。而post请求把提交的数据则放置在是HTTP包的包体中,
理论上POST没有限制,适用于较大量的数据。

好,现在开始想想上面4个方法的区别,
GET 请求获取由Request-URI所标识的资源---简单的理解为查询资源。
POST 在Request-URI所标识的资源后附加新的数据---简单的理解为修改更新资源。
PUT 请求服务器存储一个资源,并用Request-URI作为其标识---简单的理解为新增资源。
DELETE 请求服务器删除由Request-URI所标识的资源---简单的理解为删除资源。

HttpServlet继承了父类抽象类GenericServlet如下:
public abstract class GenericServlet
其中:

    public void destroy()
    {
    }
    public void init()
        throws ServletException
    {
    }
public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse)
        throws ServletException, IOException;

destroy,init方法和service不同,service是抽象方法在子类HttpServlet已经继承实现了。
而destroy,init方法就是为了让我们重写用的,以实现我们的实际需求。








分享到:
评论

相关推荐

    查看httpServlet源码的包必须导入这个包才能看源代码

    总之,`apache-tomcat-7.0.67-src`包提供了查看`HttpServlet`源码的入口,让我们有机会学习和理解Servlet和Tomcat的底层机制。这对于我们提升Java Web开发技能,优化应用性能,以及参与开源项目都是非常有价值的。

    提升Web 应用系统性能研究

    ### 提升Web应用系统性能研究 #### 摘要与背景 随着互联网技术的发展与普及,Web应用系统已经成为人们日常生活中不可或缺的一部分。然而,随着用户数量的不断增加,Web应用系统的负载压力也越来越大,如何有效提升...

    深入研究Servlet线程安全性问题

    深入研究Servlet线程安全性问题,我们首先需理解Servlet在多线程环境下的行为与潜在的风险。Servlet作为一种在服务器端处理HTTP请求的技术,被设计成能够高效处理并发请求,这一特性使其在多用户环境下表现优越。...

    MVC架构下的ServletJSP在电子商务网站开发中的研究.pptx

    "MVC架构下的ServletJSP在电子商务网站开发中的研究" MVC架构是软件设计模式的一种,主要用于分离应用程序的数据访问、用户界面和业务逻辑,以提高代码的可维护性和可重用性。MVC架构包括三个组件:模型(Model)、...

    servlet-api_servlet_

    7. **Filter和FilterChain接口**:Servlet API也包含了过滤器(Filter)机制,允许在请求到达Servlet之前进行拦截和处理,如进行权限检查、数据转换等。FilterChain接口则用于管理和执行一系列过滤器。 8. **...

    servlet源码

    通过深入研究这些源代码,我们可以理解Servlet的内部工作机制,更好地调试和优化我们的Web应用,同时也能提高问题排查的能力。对于初学者,源码分析有助于形成扎实的Java Web基础,对于有经验的开发者,源码可以作为...

    Servlet文档

    7. **过滤器(Filter)**:Servlet 2.3引入了Filter机制,允许开发者在请求到达Servlet之前或之后对请求和响应进行拦截和修改,如实现认证、编码转换、日志记录等功能。 8. **监听器(Listener)**:Servlet 2.3还...

    javax-servlet源码包和jar文件

    通过深入研究`javax.servlet`和`javax.servlet.jsp`的源码,开发者能够更好地掌握Web应用的构建和运行机制,提升解决问题的能力。同时,通过实践和阅读源码,可以学习到如何有效地管理请求响应、处理并发、优化性能...

    Servlet 源码

    通过分析Servlet源码,我们可以了解到Servlet的工作机制,学习如何编写更高效、更健壮的Servlet,以及如何利用Servlet API提供的各种功能来提升Web应用的性能和可维护性。同时,源码研究也能帮助我们理解Java多线程...

    Servlet+API[China].chm

    但一般来说,这样的文档会详细介绍Servlet的生命周期、调度机制、会话管理、过滤器、监听器等关键概念,同时还会涵盖MVC模式、Servlet与JSP的协同工作,以及如何在实际项目中使用Servlet API进行开发。 总的来说,...

    servlet-api-private.zip

    深入研究"servlet-api-private.zip"中的私有实现,我们可以了解到Servlet容器如何解析和执行Servlet代码,以及如何处理线程安全、性能优化、错误处理等问题。例如,私有实现可能涉及到线程池的管理,以提高并发性能...

    struts1.2源码

    此外,还可以理解框架的可扩展性和插件机制,这对于进一步学习其他框架或开发自己的框架非常有帮助。 总之,研究Struts1.2源码是提升Java Web开发技能的重要步骤,不仅可以加深对MVC模式的理解,还能掌握Web应用...

    servletProject.rar

    Servlet项目实践详解 Servlet是Java Web开发中的一个重要组成部分,它是一种服务器端的Java应用程序,用于扩展Web服务器的功能,处理来自客户端...在深入研究项目代码和结构后,对Java Web开发的理解将会更加深入。

    servlet源码包

    4. **会话管理**:研究`HttpSession`接口,理解如何存储和检索会话数据,以及会话超时和失效的机制。 5. **JSP转换过程**:了解JSP文件是如何被编译成Servlet Java源码,再编译为字节码并加载到内存中执行的。 6. **...

    Hadoop源代码分析

    14. **`http`**:基于Jetty的HTTPServlet,允许用户通过浏览器查看文件系统状态和日志。 15. **`log`**:提供HTTP访问日志的记录功能。 #### 三、HDFS设计:NameNode与DataNode的角色 HDFS的核心组件包括NameNode...

    Tomcat 8源代码 Servlet源代码

    这里的“简单实用”可能是指通过研究源码,开发者可以更直观地了解Web服务器内部机制,从而更好地应用在实际项目中。 **Tomcat 8源代码解析:** 1. **结构与目录**:Tomcat的源码结构分为几个主要部分,如`common`...

    servlet源代码

    研究Servlet的源代码可以帮助我们更深入地理解其内部机制,比如`service()`方法如何根据请求类型分派到`doGet()`或`doPost()`,以及`init()`和`destroy()`如何参与Servlet的生命周期管理。 通过深入学习和分析`...

    深入剖析Spring_Web源码.pdf

    ### 深入剖析Spring Web源码 #### 1. 前言 Spring作为一款卓越的轻量级企业级应用开发框架,在Java开发...通过深入研究其源码,我们可以更好地理解框架内部的工作原理,从而更加高效地利用Spring进行Web应用开发。

    ssh项目实例

    开发者可以通过研究这些文件来了解各个组件如何协同工作,以及如何在实际项目中实现需求。这个实例不仅有助于提升个人技能,也是团队协作和代码组织的良好示例。通过深入学习和实践,开发者可以更好地掌握Java Web...

Global site tag (gtag.js) - Google Analytics