详解Servlet

目录

特性

新增功能

Servlet 2.2

servlet 2.3

servlet 2.4

Servlet 2.5

Servlet 3.0

Servlet 4.0草案

常见容器


百度定义:

Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Servlet的声明周期    不会的自己去百度

特性

 

Servlet 3.12013年5月JavaEE 7Non-blocking I/O, HTTP protocol upgrade mechanism
Servlet 3.02009年12月JavaEE 6, JavaSE 6Pluggability, Ease of development, Async Servlet, Security, File Uploading
Servlet 2.52005年10月JavaEE 5, JavaSE 5Requires JavaSE 5, supports annotation
Servlet 2.42003年11月J2EE 1.4, J2SE 1.3web.xml uses XML Schema
Servlet 2.32001年8月J2EE 1.3, J2SE 1.2Addition of Filter
Servlet 2.21999年8月J2EE 1.2, J2SE 1.2Becomes part of J2EE, introduced independent web applications in .war files
Servlet 2.11998年11月未指定First official specification, added RequestDispatcher, ServletContext
Servlet 2.0 JDK 1.1Part of Java Servlet Development Kit 2.0
Servlet 1.01997年6月

 

 

 

新增功能

编辑

Servlet 2.2

:引入了 self-contained Web applications 的概念。

servlet 2.3

: 2000年10月份出来

Servlet API 2.3中最重大的改变是增加了 filters

Servlet 2.3 增加了 filters 和 filter chains 的功能。引入了 context 和 session listeners 的概念,当 context 或 session 被初始化或者被将要被释放的时候,和当向 context 或 session 中绑定属性或解除绑定的时候,可以对类进行监测。

servlet 2.4

: 2003年11月份推出

Servlet 2.4 加入了几个引起关注的特性,没有特别突出的新内容,而是花费了更多的功夫在推敲和阐明以前存在的一些特性上,对一些不严谨的地方进行了校验。

Servlet 2.4 增加了新的最低需求,新的监测 request 的方法,新的处理 response 的方法,新的国际化支持,RequestDispatcher 的几个处理,新的 request listener 类,session 的描述,和一个新的基于 Schema 的并拥有 J2EE 元素的发布描述符。这份文档规范全面而严格的进行了修订,除去了一些可能会影响到跨平台发布的模糊不清的因素。总而言之,这份规范增加了四个新类,七个新方法,一个新常量,不再推荐使用一个类。

注意:改为 Schema 后主要加强了两项功能:

(1) 元素不依照顺序设定;

(2) 更强大的验证机制。

主要体现在:

a.检查元素的值是否为合法的值

b.检查元素的值是否为合法的文字字符或者数字字符

c.检查 Servlet, Filter, EJB-ref 等等元素的名称是否唯一

2.新增 Filter 四种设定:REQUEST、FORWARD、INCLUDE 和 ERROR。

3.新增 Request Listener、Event和Request Attribute Listener、Event。

4.取消 SingleThreadModel 接口。当 Servlet 实现 SingleThreadModel 接口时,它能确保同时间内,只能有一个 thread 执行此 Servlet。

5.<welcome-file-list>可以为Servlet。

6.ServletRequest接口新增一些方法。

public String getLocalName();

public String getLocalAddr();

public int getLocalPort();

public int getRemotePort()

Servlet 2.5

2005 年 9 月发布 Servlet 2.5

Servlet 2.5 一些变化的介绍:

1) 基于最新的 J2SE 5.0 开发的。

2) 支持 annotations 。

3) web.xml 中的几处配置更加方便。

4) 去除了少数的限制。

5) 优化了一些实例

Servlet 的各个版本对监听器的变化有:

(1) Servlet 2.2 和 jsp1.1

新增Listener:HttpSessionBindingListener

新增Event: HttpSessionBindingEvent

(2) Servlet 2.3 和 jsp1.2

新增Listener:ServletContextListener,ServletContextAttributeListener

,HttpSessionListener,HttpSessionActivationListener,HttpSessionAttributeListener

新增Event: ServletContextEvent,ServletContextAttributeEvent,HttpSessionEvent

(3) Servlet 2.4 和 jsp2.0

新增Listener:ServletRequestListener,ServletRequestAttribureListener

新增Event: ServletRequestEvent,ServletRequestAttributeEvent

Servlet 3.0

Servlet 3.0 作为 Java EE 6 规范体系中一员[1] ,随着 Java EE 6 规范一起发布。该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发和部署。其中有几项特性的引入让开发者感到非常兴奋,同时也获得了 Java 社区的一片赞誉之声:[2] 

  1. 异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该 Servlet 线程。在接收到请求之后,Servlet 线程可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。[2] 

  2. 新增的注解支持:该版本新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得 web.xml 部署描述文件从该版本开始不再是必选的了。[2] 

  3. 可插性支持:熟悉 Struts2 的开发者一定会对其通过插件的方式与包括 Spring 在内的各种常用框架的整合特性记忆犹新。将相应的插件封装成 JAR 包并放在类路径下,Struts2 运行时便能自动加载这些插件。现在 Servlet 3.0 提供了类似的特性,开发者可以通过插件的方式很方便的扩充已有 Web 应用的功能,而不需要修改原有的应用。[2] 

Servlet 4.0草案

从3.1到4.0将是对Servlet 协议的一次大改动,而改动的关键之处在于对HTTP/2的支持。HTTP2将是是继上世纪末HTTP1.1协议规范化以来首个HTTP协议新版本,相对于HTTP1.1,HTTP2将带来许多的增强。在草案提议中,Shing Wai列举出了一些HTTP2的新特性,而这些特性也正是他希望在Servlet 4.0 API中实现并暴露给用户的新功能,这些新特性如下:[3] 

1.请求/响应复用(Request/Response multiplexing)
  2.流的优先级(Stream Prioritization)
  3.服务器推送(Server Push)
  4.HTTP1.1升级(Upgrade from HTTP 1.1)[3] 

 

为了简化开发流程,Servlet 3.0 引入了注解(annotation),这使得 web 部署描述符 web.xml 不再是必须的选择。

 

 

Pluggability可插入性

当使用任何第三方的框架,如 Struts,JSF 或 Spring,我们都需要在 web.xml 中添加对应的 Servlet 的入口。这使得 web 描述符笨重而难以维护。Servlet3.0 的新的可插入特性使得 web 应用程序模块化而易于维护。通过 web fragment 实现的可插入性减轻了开发人员的负担,不需要再在 web.xml 中配置很多的 Servlet 入口。

Asynchronous Processing 异步处理

另外一个显著的改变就是 Servlet 3.0 支持异步处理,这对 AJAX 应用程序非常有用。当一个 Servlet 创建一个线程来处理某些请求的时候,如查询数据库或消息连接,这个线程要等待直到获得所需要的资源才能够执行其他的操作。异步处理通过运行线程执行其他的操作来避免了这种阻塞。

Apart from the features mentioned here, several other enhancements have been made to the existing API. The sections towards the end of the article will explore these features one by one in detail.

除了这些新特性之外, Servlet 3.0对已有的 API 也做了一些改进,在本文的最后我们会做介绍。

Annotations in Servlet Servlet中使用注解

Servlet 3.0 的一个主要的改变就是支持注解。使用注解来定义 Servlet 和 filter 使得我们不用在 web.xml 中定义相应的入口。

@WebServlet

@WebServlet 用来定义 web 应用程序中的一个 Servlet。这个注解可以应用于继承了 HttpServlet。这个注解有多个属性,例如 name,urlPattern, initParams,我们可以使用者的属性来定义 Servlet 的行为。urlPattern 属性是必须指定的。

 

Servlet和容器之间是怎么工作的

https://www.cnblogs.com/whgk/p/6399262.html

 

常见容器

编辑

  1. Tomcat,
  2. Jetty
  3. resin
  4. Oracle Application server
  5. WebLogic Server
  6. Glassfish
  7. Websphere
  8. JBoss

(提供了 Servlet 功能的服务器,叫做 Servlet 容器。对 web 程序来说,Servlet 容器的作用就相当于桌面程序里操作系统的作用,都是提供一些编程基础设施)

 

 

Servlet 3.0  出现在jsr 315

 

ServletApi的讲解

api结构

Servlet API中共有5个包,约113个类或者接口

 

javax.servlet  
javax.servlet.http  
javax.servlet.jsp  
javax.servlet.annotation  
javax.servlet.descriptor  

 

 

 

Servlet API的层次结构图

 

Servlet接口

 

  
  1. package javax.servlet;  
  2. import java.io.IOException;  
  3. // Referenced classes of package javax.servlet:  
  4. // ServletException, ServletConfig, ServletRequest, ServletResponse  
  5. public interface Servlet  
  6. {  
  7.     public abstract void init(ServletConfig servletconfig)  
  8.         throws ServletException;  
  9.     public abstract ServletConfig getServletConfig();  
  10.     public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse)  
  11.         throws ServletException, IOException;  
  12.     public abstract String getServletInfo();  
  13.     public abstract void destroy();  

 

重要方法

init()  在容器启动时调用(当laod-onstart-up设置为负或者不设置,会在Servlet第一次用到才被调用),只会调用一次,接收一个ServletConfig由容器传入,在xml定义的init-param中的配置文件由ServletConfig保存

getServletConfig方法获取ServletConfig

service方法用于处理具体的一个请求

getServletInfo获取一些Servlet的相关信息,默认返回空字符串 需要自己实现

destory关闭服务器释放资源,只调用一次

==================================

StandardWrapper本身包含配置信息门面的Facade类

ServletConfig  包含了name,servletContent

ServletContent保存了Application级别的属性  setAttribute完成

用途传递初始化参数

 

GnericServlet

是Servlet默认实现

主要3件事实现了ServletConfig接口,提供了无参init方法 ,提供了log方法

 

主要完成了以下工作

将init方法中的ServletConfig赋值给一个类级变量,在里面将config设置给了内部config,然后调用了无参的init方法,而且使它可以通过调用getServletConfig来获取config。

其中init为模板方法在子类中可以通过覆盖它完成自己定义的初始化

为Servlet接口中的所有方法提供默认实现。

提供方法来包装ServletConfig中的方法。

但由于一般而言,servlet均为HttpServlet,因此GenericServlet并不常用,主要使用HttpServlet。

GericServlet提供了2个记录log方法

1记录日志

2.记录异常

具体是通过传给ServletContent的日志来实现     因为我们一般有自己日志   所以用的不多

GernicServlet 与协议无关

 

HttpServlet      作用是将不同的请求方式路由到不同的处理方法

用Http协议实现的Servlet基类,其实在SpringMvc中的DispatcherServlet就是继承了HttpServlet

先查看源代码

 

    import java.io.IOException;  
    import java.io.Serializable;  
    import java.lang.reflect.Method;  
    import java.text.MessageFormat;  
    import java.util.Enumeration;  
    import java.util.ResourceBundle;  
    import javax.servlet.*;  
    // Referenced classes of package javax.servlet.http:  
    //            NoBodyResponse, HttpServletRequest, HttpServletResponse  
    public abstract class HttpServlet extends GenericServlet  
        implements Serializable  
    {  
        public HttpServlet()  
        {  
        }  
        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);  
        }  
        protected long getLastModified(HttpServletRequest req)  
        {  
            return -1L;  
        }  
        protected void doHead(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            NoBodyResponse response = new NoBodyResponse(resp);  
            doGet(req, response);  
            response.setContentLength();  
        }  
        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);  
        }  
        protected void doPut(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            String protocol = req.getProtocol();  
            String msg = lStrings.getString("http.method_put_not_supported");  
            if(protocol.endsWith("1.1"))  
                resp.sendError(405, msg);  
            else  
                resp.sendError(400, msg);  
        }  
        protected void doDelete(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            String protocol = req.getProtocol();  
            String msg = lStrings.getString("http.method_delete_not_supported");  
            if(protocol.endsWith("1.1"))  
                resp.sendError(405, msg);  
            else  
                resp.sendError(400, msg);  
        }  
        private Method[] getAllDeclaredMethods(Class c)  
        {  
            if(c.equals(javax/servlet/http/HttpServlet))  
                return null;  
            Method parentMethods[] = getAllDeclaredMethods(c.getSuperclass());  
            Method thisMethods[] = c.getDeclaredMethods();  
            if(parentMethods != null && parentMethods.length > 0)  
            {  
                Method allMethods[] = new Method[parentMethods.length + thisMethods.length];  
                System.arraycopy(parentMethods, 0, allMethods, 0, parentMethods.length);  
                System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, thisMethods.length);  
                thisMethods = allMethods;  
            }  
            return thisMethods;  
        }  
        protected void doOptions(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            Method methods[] = getAllDeclaredMethods(getClass());  
            boolean ALLOW_GET = false;  
            boolean ALLOW_HEAD = false;  
            boolean ALLOW_POST = false;  
            boolean ALLOW_PUT = false;  
            boolean ALLOW_DELETE = false;  
            boolean ALLOW_TRACE = true;  
            boolean ALLOW_OPTIONS = true;  
            for(int i = 0; i < methods.length; i++)  
            {  
                Method m = methods[i];  
                if(m.getName().equals("doGet"))  
                {  
                    ALLOW_GET = true;  
                    ALLOW_HEAD = true;  
                }  
                if(m.getName().equals("doPost"))  
                    ALLOW_POST = true;  
                if(m.getName().equals("doPut"))  
                    ALLOW_PUT = true;  
                if(m.getName().equals("doDelete"))  
                    ALLOW_DELETE = true;  
            }  
            String allow = null;  
            if(ALLOW_GET && allow == null)  
                allow = "GET";  
            if(ALLOW_HEAD)  
                if(allow == null)  
                    allow = "HEAD";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", HEAD").toString();  
            if(ALLOW_POST)  
                if(allow == null)  
                    allow = "POST";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", POST").toString();  
            if(ALLOW_PUT)  
                if(allow == null)  
                    allow = "PUT";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", PUT").toString();  
            if(ALLOW_DELETE)  
                if(allow == null)  
                    allow = "DELETE";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", DELETE").toString();  
            if(ALLOW_TRACE)  
                if(allow == null)  
                    allow = "TRACE";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", TRACE").toString();  
            if(ALLOW_OPTIONS)  
                if(allow == null)  
                    allow = "OPTIONS";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", OPTIONS").toString();  
            resp.setHeader("Allow", allow);  
        }  
        protected void doTrace(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            String CRLF = "\r\n";  
            String responseString = (new StringBuilder()).append("TRACE ").append(req.getRequestURI()).append(" ").append(req.getProtocol()).toString();  
            for(Enumeration reqHeaderEnum = req.getHeaderNames(); reqHeaderEnum.hasMoreElements();)  
            {  
                String headerName = (String)reqHeaderEnum.nextElement();  
                responseString = (new StringBuilder()).append(responseString).append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName)).toString();  
            }  
            responseString = (new StringBuilder()).append(responseString).append(CRLF).toString();  
            int responseLength = responseString.length();  
            resp.setContentType("message/http");  
            resp.setContentLength(responseLength);  
            ServletOutputStream out = resp.getOutputStream();  
            out.print(responseString);  
            out.close();  
        }  
        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);  
            }  
        }  
        private void maybeSetLastModified(HttpServletResponse resp, long lastModified)  
        {  
            if(resp.containsHeader("Last-Modified"))  
                return;  
            if(lastModified >= 0L)  
                resp.setDateHeader("Last-Modified", lastModified);  
        }  
        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);  
        }  
        private static final String METHOD_DELETE = "DELETE";  
        private static final String METHOD_HEAD = "HEAD";  
        private static final String METHOD_GET = "GET";  
        private static final String METHOD_OPTIONS = "OPTIONS";  
        private static final String METHOD_POST = "POST";  
        private static final String METHOD_PUT = "PUT";  
        private static final String METHOD_TRACE = "TRACE";  
        private static final String HEADER_IFMODSINCE = "If-Modified-Since";  
        private static final String HEADER_LASTMOD = "Last-Modified";  
        private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";  
        private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");  
    }  

 

 

 

 

 

重点关注如何处理请求

工作 主要重写了service方法

 

在service方法中

1.将ServletResponse和ServletRequest转化为HttpServletResponse和HttpServletRequest,源码中的实现如下

 

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);  
        }  

 

2.根据Http的请求类型不同将请求路由到不同的处理方法。源码中的实现如下

 

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);  
            }  
        }  

 

3.具体的方法是doXXX的结构,这些都是模板方法,如果没有子类实现抛出异常,

另外还发现

 

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);  
                    }  
                }  
            }   

在调用doGet方法之前还对是否过期做了检查,如果没有过期直接返回304状态码并使用缓存

 

 if(method.equals("HEAD"))  
            {  
                long lastModified = getLastModified(req);  
                maybeSetLastModified(resp, lastModified);  
                doHead(req, resp);  
            } 

doHead调用了doGet的请求,然后返回空body的Response

下面在分析下内部的doXXX方法

 

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

 

 

发现doXXX()方法只是判断协议类型,然后抛出相应的异常,其他什么都没做。所以,在实现自己的Servlet时,需要重写这些方法,以符合自己的需求。一般不需要重写service方法。

 

 

 

HTTP的请求方式包括DELETE,GET,OPTIONS,POST,PUT和TRACE,在HttpServlet类中分别提供了相应的服务方法,它们是doDelete(),doGet(),doOptions(),doPost(),doPut()和doTrace().

doOptions和doTrace正常不使用主要用来做一些调试工作,由于doOptions和doTrace功能非常固定,所以提供了默认实现

 

protected void doOptions(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            Method methods[] = getAllDeclaredMethods(getClass());  
            boolean ALLOW_GET = false;  
            boolean ALLOW_HEAD = false;  
            boolean ALLOW_POST = false;  
            boolean ALLOW_PUT = false;  
            boolean ALLOW_DELETE = false;  
            boolean ALLOW_TRACE = true;  
            boolean ALLOW_OPTIONS = true;  
            for(int i = 0; i < methods.length; i++)  
            {  
                Method m = methods[i];  
                if(m.getName().equals("doGet"))  
                {  
                    ALLOW_GET = true;  
                    ALLOW_HEAD = true;  
                }  
                if(m.getName().equals("doPost"))  
                    ALLOW_POST = true;  
                if(m.getName().equals("doPut"))  
                    ALLOW_PUT = true;  
                if(m.getName().equals("doDelete"))  
                    ALLOW_DELETE = true;  
            }  
            String allow = null;  
            if(ALLOW_GET && allow == null)  
                allow = "GET";  
            if(ALLOW_HEAD)  
                if(allow == null)  
                    allow = "HEAD";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", HEAD").toString();  
            if(ALLOW_POST)  
                if(allow == null)  
                    allow = "POST";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", POST").toString();  
            if(ALLOW_PUT)  
                if(allow == null)  
                    allow = "PUT";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", PUT").toString();  
            if(ALLOW_DELETE)  
                if(allow == null)  
                    allow = "DELETE";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", DELETE").toString();  
            if(ALLOW_TRACE)  
                if(allow == null)  
                    allow = "TRACE";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", TRACE").toString();  
            if(ALLOW_OPTIONS)  
                if(allow == null)  
                    allow = "OPTIONS";  
                else  
                    allow = (new StringBuilder()).append(allow).append(", OPTIONS").toString();  
            resp.setHeader("Allow", allow);  
        }  

doOptions返回所有支持的处理数据类型的集合,正常情况下可以禁用

 protected void doTrace(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException  
        {  
            String CRLF = "\r\n";  
            String responseString = (new StringBuilder()).append("TRACE ").append(req.getRequestURI()).append(" ").append(req.getProtocol()).toString();  
            for(Enumeration reqHeaderEnum = req.getHeaderNames(); reqHeaderEnum.hasMoreElements();)  
            {  
                String headerName = (String)reqHeaderEnum.nextElement();  
                responseString = (new StringBuilder()).append(responseString).append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName)).toString();  
            }  
            responseString = (new StringBuilder()).append(responseString).append(CRLF).toString();  
            int responseLength = responseString.length();  
            resp.setContentType("message/http");  
            resp.setContentLength(responseLength);  
            ServletOutputStream out = resp.getOutputStream();  
            out.print(responseString);  
            out.close();  
        }  

doTrace是用来远程诊断服务器的,它会将接收到的header原封不动的返回

 

但最好还是把doTrace和doOptions禁用掉,防止黑客利用安全漏洞。

 

但是在SpringMVC将请求合并到同一的一个方法中进行处理

手都写麻了 ,未完待续。

 

 

欢迎关注我的个人订阅号,我会推送更好的文章给大家

订阅号

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值