JavaEE三日通

1. url地址

url地址 = 应用层协议+主机IP地址或域名+端口号+资源所在路径/文件名

/s表示文件路径
?表示查询字符串和url地址的分隔符
然后服务器就可以搜到url以及后面连着的查询字符串。
查询字符串用名值对的形式表示
汉字转换为ascii码用的是base64

2. HTTP协议(应用层;HTTP=TCP+80)

HTTP请求格式

  • 请求方法+URI+HTTP协议版本
  • 请求头(包括浏览器类型,所用语言,请求正文类型等)
  • 请求正文(和请求头之间用只有CRLF(\r\n)的行(空行)间隔;请求头里面可以包括客户以POST方式提交的表单)

常见请求方式:GET POST HEAD PUT DELETE

HTTP响应格式

  • HTTP协议版本、状态码(404客户端错误,405服务器不支持客户端请求方式,500服务器内部错误)、描述
  • 响应头HEAD
  • 响应正文

3. Servlet组件

3.1. javax.servlet.Servlet接口

  1. The servlet is constructed, then initialized with the init method.
  2. Any calls from clients to the service method are handled.
  3. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
package javax.servlet;
public interface Servlet{
    public void init(ServletConfig config){
		//Servlet指行构造函数创建后,
		//由init负责初始化Servlet对象。即容器在创建好Servlet对象后会调用init方法。
    }
    public void service(ServletRequest req,ServletResponse res)
    	throws ServletException,IOException{
		//负责响应客户端请求,为客户提供相应服务。
		//当容器接收到客户端要求访问特定Servlet对象的请求时,就会调用改Servlet对象的service()方法。
    }
    public void destroy(){
		//负责释放Servlet对象占用的资源。
		//当Servlt对象结束生命周期时,容器会调用该方法。 
    }
}

3.2 javax.servlet.http.HttpServlet

3.2.1 GenericServlet
package javax.servlet;
public abstract class GenericServlet{
    public void init(ServletConfig config)throws ServletExcpeiton{
        this.config = config;
        init();
    }
    public void init()throws ServletException{
        //do something to init. e.g. getInitParameter...
        
    }
    public java.lang.String getInitParameter(java.lang.String name){}
    public java.util.Enumeration getParameternames(){}
    ServletContext	getServletContext(){
        //只是提供方便,实际上还是从ServletConfig处调用config.getservletContext().
    }
}
3.2.2 HttpServlet

抽象类,为了快速开发http协议的servlet而创造。

package javax.servlet.http;
public abstract class HttpServlet extends GenericServlet
    implements java.io.Serializable{
    
	public void service(ServletRequest req,ServletResponse res)
    	throws SevrletException,IOExcepiton{
        //这个是为了实现GenericServlet的service方法
    	HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)res;
        service(request,response);//这里调用下面的那个保护方法
    }
    protected void service(HttpServletRequest request,HttpServletResponse response)
    	throws ServletException,IOException{
        String method = "do" + request.getMethod();
    	//doGet,doPost,doHead,doDelete,doTrace,doPut,...
        Method m = null;
        try{
            m = this.getClass().getDeclaredMethod(method,
                                                 HttpServletRequest.class,
                                                  HttpServletResponse.class);
            m.invoke(this.request);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    protected void doPost(HttpServletRequest req,HttpServletResponse res)
    	throws ServletException,IOException{
        //...
    }
}

一个例子:

@WebServlet(
		urlPatterns = { "/a" }, 
		initParams = { 
				@WebInitParam(name = "server", value = "www.dlut.edu.cn"), 
				@WebInitParam(name = "port", value = "80")
		})
public class AServlet extends HttpServlet {
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");//在PrintWriter之前,是有效的charset设置。
		PrintWriter out = response.getWriter();
		Enumeration<String> params = getServletConfig().getInitParameterNames();
		
		while(params.hasMoreElements()) {
			String param_name = params.nextElement();
			String param_value = getServletConfig().getInitParameter(param_name);
			out.println("param-name: " + param_name + ", param-value: " + param_value + "<br>");
		}
		
		out.println("---------------------------------------------<br>");
		ServletContext context = getServletContext();
		params = context.getInitParameterNames();
		while(params.hasMoreElements()) {
			String param_name = params.nextElement();
			String param_value = context.getInitParameter(param_name);
			out.println("context param-name: " + param_name + ", context param-value: " + param_value + "<br>");
		}	
	}

3.3. javax.servlet.ServletRequest接口

package javax.servlet;
public interface ServletRequest{
    Object getAttribute(String name){}
    void setAttribute(String name, Object o){}
    Enumeration<String>	getAttributeNames(){}
    String	getParameter(String name){}//url中?后面带的用这个←
    Enumeration<String>	getParameterNames(){}
    String[] getParameterValues(String name){}
    String	getContentType(){
        //Returns the MIME type of the body of the request, 
        //or null if the type is not known.
    }
    RequestDispatcher	getRequestDispatcher(String path){
        //可以相对路径也可以绝对路径。所谓相对路径就是指相对当前Servlet组件的路径;
        //所谓绝对路径就是以符号/开头,/表示当前Web应用的url入口。
    }
    ServletContext	getServletContext(){
    }
}

3.4 javax.servlet.ServletResponse

headers+两次回车换行+context
写为主。服务器通过网络向浏览器传数据。

package javax.servlet;
public interface ServletResponse
{
    PrintWriter	getWriter(){
        //返回一个PrintWriter
        //默认charset是ISO-8859-1
    }
    ServletOutputStream	getOutputStream(){
        //Returns a ServletOutputStream suitable for writing binary data in the response.
    }
    void	setCharacterEncoding(String charset){}
    void	setContentType(String type){
        //response.setContextType("text/html;charse=tutf-8");
        //如果在getWriter以前写setContextType的话就要写charset.
        //如果在getWriter以后or相应提交以后写setContextType的话就没法改charset了,只能用PrintWriter的charset
    }
}

在Servlet的service中可能调用ServletResponse和ServletRequest的抛出IllegalStateException的方法,但是service只是throw ServletExcpetion和IOExcpetion的原因:

IllegalStatementException是RuntimeExcpetion,不是检查异常,是由Java运行自动抛出、自动处理,不用我们捕获

3.5 javax.servlet.http.HttpServletRequest

HttpServletRequest接口是ServletRequest接口的子接口。HttpServlet类的重载service方法以及doGet和doPost等方法都有一个HttpServletRequest参数。

注意!上下文路径是请求URI的开始部分;上下文路径总是以/开头,但是结尾没有/。

比如请求URI为/sample/foo/bar,那么上下文路径是/sample.

package javax.servlet.http;
public interface HttpServletRequest extends ServletRequest
{
    public String	getContextPath(){
        //返回客户端所请求访问Web应用的URL入口(或者说是URI)。比如客户端访问http://localhost:8080/helloapp/info的话,调用该方法就返回/helloapp。这和ServletContext.getContextPath不同:ServletContext.getContextPath()返回的是Web项目的路径。
    }
    public String	getServletPath(){
        //返回调用这个Servet的request的URL。如果url-pattern是/*的话返回空字符串。
    }
    public String getPathInfo(){
        //返回与客户端发送请求URL相联系的额外路径信息。额外的路径信息实在Servlet路径之后,查询字符串之前的路径,以/开头。比如MyServlet映射为/MyServlet/*,用户请求的URL为/MyServlet/test/foo,则返回/test/foo。如果唯有额外路劲信息则返回null。
    }
	public Collection<String>	getHeaderNames(){}
	public Collection<String>	getHeaders(String name){}
	public String	getHeader(String name){}
	public Cookie[]	getCookies(){}
    public String	getMethod(){/* GET, POST,PUT, HEAD, DELETE, TRACE*/}
    public HttpSession	getSession(){}
}

3.6 javax.servlet.http.HttpServletResponse

package javax.servlet.http;
public interface HttpServletResponse{
    public void addCookie(Cookie cookie){}
    public void addHeader(Striing name,String value){}
    public String encodeURL(String url){/*使用session id对url进行编码。不需要编码的话就不变*/}
    public String encodeRedirectURL(String url){}
	public void	sendRedirect(String location){}
	public void	sendError(int sc, String msg)throws java.io.IOException{}
}

一个例子:

public class LoginSevrlet extends HttpServelt{
    public void doGet(HttpServletRequest req,HttpServtelResponse res)
        throws ServletExcpetion,IOExcetion{
        res.setContentType("text/html;charset=utf-8");
        String name = req.getParamenter("name");
        if("master".equals(name)){
            res.sendRedirect("success.html")
        }else{
            res.sendError(HttpServeltResponse.SC_SERVICE_UNAVALIABLE,"服务器繁忙,请稍后再试");
        }
    }
    public void doPost(HttpServletRequest req,HttpServletResponse res){
        doGet(req,res);
    }
}

HttpServletResponse节后的sendRdirect()方法和RequestDispatcher接口的forward()方法都可以利用另外的资源(Servlet/JSP/HTML)来为客户端服务。但是这两种方法有本质区别:重定向URL会变,forward的URL不变;重定向可不仅可以搞位于同意主机上的不同web应用程序,还可以搞到qi’ta服务器上的web应用程序资源。

3.7.javax.servlet.ServletConfig接口

Servlet接口的void init(ServletConfig config)方法有一个ServletConfig类型的参数。当Servlet容器初始化一个Servlet对象的时候,会为这个Servlet对象创建一个ServletConfig对象。在ServletConfig对象中包含了Servlet的初始化信息。
1)String getInitParameter(String name):根据给定的初始化参数名,返回匹配的初始化参数值
2) Enumeration<String> getInitParameterNames():返回所有初始化参数名

因为Servlet可以getServletConfig(),所以可以通过ServletConfig来getInitParameter()

<servlet>
	<servlet-name>Font</servlet-name>
	<servlet-class>mypack.FontServer</servlet-class>
	<init-param>
		<param-name>color</param-name>
		<param-value>blue</param-value>
	<init-param>
	<init-param>
		<param-name>color</param-name>
		<param-value>green</param-value>
	<init-param>
</servlet>
<servlet-mapping>
	<servlet-name>Font</servlet-name>
	<url-pattern>/font</url-pattern>
</servlet-mapping>

3)getServletName():返回web.xml中ret的ret位置的值。
4)getServletContext():返回一个ServletContext对象。

3.8 javax.servlet.ServletContext 接口

ServletContext是Servlet和Servlet容器之间季节通信的接口。Servlet容器在创建一个Web应用时,会为他创建一个ServletContext对象。
每个web应用都有唯一的ServletContext做总管家,每个Servlet对象通过这个总管家来访问容器中的各种资源。

ServletContext的方法由如下几种:

package javax.servlet;
public interface ServletContext{
   //1)用于在Web应用范围内获取共享数据:
   public Object getAttribute(String name){}
   public void setAttribute(String name, java.lang.Object object){}
   public Enumeration<String> getAttributeNames(){}
   //2) 用于访问当前Web应用资源:
   public getContextPath(){}/*返回web应用的项目根目录*/
   public getInitParameter(String name){}
   public getInitParameterNames(){}
   public getServletContextName(){}
   public RequestDispatcher 
       getRequestDispatcher(String path){}/*path必须是绝对路径,被解释为上下文根路径*/
   //3)访问Servlet容器中的其他Web应用
   public getContext(String uripath){}/*根据参数指定的uri,返回当前Servlet容器中其他Web应用的ServletContext对象。*/
   //4) 访问服务器端的文件系统资源
   public getRealPath(String path){}/*根据参数指定的虚拟路径,返回文件系统中的一个真实路径*/
   public getResource(String path){}/*返回一个用于读取参数指定的文件的输入流*/
   public getResourceAsStream(String path){}/*返回一个用于读取参数指定的文件的输入流。在ServletContextListener中有所体现*/
}

3.9 javax.servelt.http.HttpSession接口

Session用来跟踪用户跨页面request,并且可用于存储用户信息。比如用来保存购物车数据。这个数据保存在session里面最合适,ServletContext和ServletConfig都不合适。Serlet container使用这个接口来创建HTTP Server和HTTP Client之间的session。当application在一个session中存储了一个object或者删除了一个object,session检查这个object有木有实现HttpSessionBindingListener接口。如果实现了的话就notifies这个object,告诉它它被绑定/解绑于这个session。如果session到期了或者invalidated了,也会发通知。

package javax.servlet.http;
public interface HttpSession{//需要存储到硬盘文件的session需要实现Seriaziable序列化接口
    //1)在HttpSession对象中查找,移除,设置属性
	public java.lang.Object getAttribute(String name){}
    public java.util.Enumeration getAttributeNames(){}
    public void removeAttribute(java.lang.String name){}
	public void setAttribute(java.lang.String name,java.lang.Object value){}
	//2)和生存时间有关的参数
    public long getCreationTime(){}//获取session创建时间,起点为Jan 1, 1970 GMT
    public long getLastAccessedTime(){}//获取上次与服务器交互时间,起点为 Jan 1, 1970 GMT. 毫秒
	public setMaxInactiveInterval(int interval){/*在ServletAPI中设置超时时间(session最大的不活动间隔时间),单位是秒;负值的话永不失效*/}
}

超时时间也可以在web.xml里面设置:

<session-config>
	<session-time-out>30 <!--单位为分钟,针对单个应用--></session-time-out>
</session-config>

项目的web.xml中设置的话针对单个应用,Tomcat的/conf/web.xml中设置的话针对的是整个容器。

优先级: Servlet中API设置>程序web.xml设置> Tomcat/conf/web.xml设置。

如果超时了(本次访问和上次访问间隔时间大于session最大不活动时间),上次会话结束,客户端服务器之间产生新session,和新的sessionID;原来session中的属性全部丢失。

**session的获取:**HttpServletRequest 的 getSession() 方法

HttpSession session = request.getSession();
Cart cart = new Cart();//Cart类已经实现了序列化接口
session.setAttribute("mycart",Cart);

request.getSession使得当前HttpServlet支持会话。如果会话已经存在,就返回相应的HttpSession对象。否则就创建一个新会话,并返回新建的HttpSession对象。相当于request.getSession(true)。

注意:jsp中,如果制定了<%@page session=“false”%>,那么JSP中无法直接访问内置的session变量。同时也不会主动创建session。因为此时JSP未能自动指行request.getSession()操作获取session。

request如何携带ID(跟踪会话)

  1. cookie实现session。

  2. url重写来跟踪会话

<a href="maillogin.hsp">
    改为
<a href="%=response.encodeURL("maillogin.jsp")%>">
  1. 隐藏域

孙鑫P457

3.10 javax.servlet.http.Cookie

Cookie使在客户端访问Web服务器的时候,客户端在硬盘上存放的信息。就好像是服务器送给客户端的小点心一样。服务器可以根据Cookie来判断跟踪客户的状态。

Cookie的运行机制由HTTP协议规定,多数Web服务器和浏览器都支持Cookie。Web服务器为了支持Cookie,要具备以下功能:

  • 在HTTP相应结果中添加Cookie数据。
  • 解析HTTP请求中的Cookie数据。

客户端浏览器为了支持Cookie,需要支持一下功能:

  • 解析HTTP相应结果中的Cookie数据
  • 把Cookie数据保存到本地硬盘
  • 读取本地硬盘上的Cookie数据,把它添加到HTTP请求中。

Tomcat作为Web服务器,提供了javax.servlet.http.Cookie 来让服务器访问Cookie。

package javax.servlet.http;
public class Cookie extends Object implements Clonable, Serializable{
	//服务器从客户端读
    String	getName(){}
    String	getValue(){}
    //服务器向客户端写
    void	setMaxAge(int expiry){}
    void	setValue(String newValue)    
}
//服务器从客户端读Cookie:
PrintWriter out = response.getWriter();
Cookie [] cookies = request.getCookies(); 
if(cookies != null){
    for(int i = 0;i < cookies.length;i ++){
        out.println("name" + cookie[i].getName());
        out.println("value" + cookie[i].getValue());
    	out.println("max age" + cookie.getMaxage());
    }
}else{
    out.println("No cookie.");
}
//服务器向客户端写Cookie
//调用HttpServletResponse中的addCookie()方法,把Cookie添加到HTTP相应结果中:
Cookie theCookie = new Cookie("username","Emanon");
response.addCookie(theCookie);

Cookie有效期为-1代表着这个Cookie仅存于当前浏览器,其他浏览器进程无法访问这个Cookie。 

3.11 javax.servlet.RequestDispatcher接口

  1. void forward(ServletRequest request, ServletResponse response)
    转法一个request从一个servlet到server上的另一个地方(比如servlet,JSP文件或者html文件)
  2. void include(ServletRequest request, ServletResponse response)
    在response里包含了某种资源(比如servlet,JSP页面,HTML文件)的内容

使用:
Servlet可以通过两种方式得到Request Dispatcher对象:
* (1)调用ServletContext的getReuqestDispatcher(String path)
* (2)调用ServletRequest的getRequestDispatcher(String path)
两者path的意义都是指定目标组件的路径。但是从ServletContext调用的RequestDispatcher的路径必须是绝对路径但是从RequestDispatcher得到的RequestDispatcherc的参数就既可以是绝对路径y又可以是相对路径。

@WebServlet("/ASerlet")
public class MyServlet extends HttpServelt
{
	void doGet(HttpServletRequest request, HttpServletResponse)
		throws ServletException, HttpException
	{
		//...
		request.getRequestDispatcher("login.html").forward(requestm,response);
		//转发一个相对路径
	}
	void doPost(HttpServletRequest reuqest, HttpServletResponse response)
	{
		request.getRequestDispatcher("AServlet").forward(request,response);
		//转发一个相对路径~
	}		
}

4. WebServlet Annotation

  • name属性可以指定也可以不指定,通过getServletName()取得。如果不指定,则为Servlet的完整类名(带着包名的那种)
  • urlpattern可以设置多个值,也可以用正则表达式。常用
    • /* 或者/ : 拦截所有
    • *.do 拦截后缀;拦截后缀必须使用相对路径。
    • /user/test 拦截绝对路径
    • 不可以有/*.do
    • 只有value属性的时候可以不写value=
    • value属性和urlpattern属性是等价的
声明Filter:
@WebFilter(dispatcherTypes = {DispatcherType.REQUEST }, 
			urlPatterns= {"/user/test", "/user/example"})

声明Servlet
@WebServlet(urlPatterns= {"/user/test", "/user/example"})

声明监听器
@WebListener@WebListener标注的类必须实现以下至少一个监听接口:
    javax.servlet.ServletContextListener
    javax.servlet.ServletContextAttributeListener
    javax.servlet.ServletRequestListener
    javax.servlet.ServletRequestAttributeListener
    javax.servlet.http.HttpSessionListener
    javax.servlet.http.HttpSessionAttributeListener
    

@WebInitParam@WebFilter@WebServlet一起使用,充当<init-param>子元素
@ClientEndpoint

5. Listener&Event

5.1 ServletContextListener

ServletContextListener接口可以监听ServletContext对象的生命周期。ServletContext就是那个Servlet总管家,也实际上是监听Web应用的生命周期。

当Servlet容器启动或终止Web应用时,会触发SevrletConetxtEvent时间。该事件由ServletContextListener来处理:

package javax.servlet;
public interface ServletContextListener{
	default void contextInitialized(ServletContextEvent sce){
        //当Servlet容器qidongWeb应用的时候调用该方法。调用完后,容器再对Filter进行初始化,并且对那些在Web应用启动时就需要被初始化的Servlet进行初始化。
    }
    default void contextDestroyed(ServletContextEvent sce){
        //dangServlet种植Web应用的时候第哦啊用,调用之前,会先销毁所有Servlet和Filter。
    }
}

我们自己可以定义自己的MyServletContextListener:

package mypack;
public class MyServletContextListener implements ServletContextListener{
	public void contextInitialized(ServletContext sce){
        ServletContext = sce.getServletContext();
        String jndi = sc.getInitParameter("jndi");
        Context ctx = null;
        try{
            ctx = new Initialcontext();
            DataSource ds =  (DataSource)ctx.lookup(jndi);
            sc.setAttribute("datasource",ds);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public void contextDestroyed(ServletContextEvent sce){
        ServletContext context = sce.getServletContext();
        Counter counter = (Counter)context.getAttribute("datasource");
        if(counter != null)
        {
            System.out.println("曾经来过");
        }
    }
}	

用户自定义的MyServletContextListener监听器只有现象servlet容器注册,servlet容器启动或终止的时候才会调用该监听器的相关方法。在web.xml中,元素用于向容器注册监听器:

<web-app>
    <listener>
        <listener-class>mypack.MyServletContextListener</listener-classlistener-context>
    </listener>
</web-app>

5.2 HttpSessionBindingListener

如果一个对象实现了这个接口,当他被绑定到Session/被Session删除的时候,Servlet容器会通知这个对象。而这个对象在接收到通知后,可以做一些初始化或者清除状态的操作。

5.3 ServletContextEvent

package javax.servlet;
public class ServletContextEvent extends java.util.EventObject
	implements Serializable{
	ServletContext	getServletContext(){
        //Return the ServletContext that changed.
    }
}

6.Filter组件

6.1 javax.servlet.Filter 接口

  • filter可以对一部分客户请求进行预处理操作,然后再把请求转发给相应的Web组件。等到Web组件生成了相应结果后,过滤器还能对相应结果进行检查和修改,然后再把修改后的相应结果发给客户。各web组件中的相同操作可以放到一个过滤器里面完成,这样减少了重复编码。
  • 责任链设计模式

一些Filter的应用:加密,压缩,图像转换,身份验证,登陆,etc

一个例子

//MyFilter.java
public class MyFilter implements Filter
{
	private FilterConfig config;
	public void init(FilterConfig config){
		this.config = config;
        //在web应用启动的时候,Servlet容器先创建了包含过滤器配置信息的FilterConfig对象,然后创建了Filter对象。接着调用Filter对象的init方法。在init里面可以通过config这个大管家来读取web.xml文件中为过滤器配置的初始化参数。
	}
	public void doFilter(ServletReqest request,ServletResponse response)
		throws ServletException,IOExcpetion
	{
		//pre-filter code
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		HttpSession session = request.getSession();
		String username = session.getParameter("username");
		if(usernmae == null || username.lenght() == 0)
		{
			request.getDispatcher("login.html").forward(request,response);
		}
        //这个方法完成实际的过滤操作。当客户请求访问的URL和过滤器的URL匹配的时候,Servlet容器将先调用过滤器的doFilter方法。FilterChain用于访问后续过滤器或者web组件。
		chain.doFilter(request,response);
		//post-filter code	
	}
	public void destroy()
	{
		config = null;
	}	
}

6.2 配置文件书写

发布过滤器的时候,必须在web.xml文件中加入元素和元素,或者Annotation一下。元素用来定义一些过滤器,如下所示:

例1:

<filter>
	<filter-name>f1</filter-name>
	<filter-class>f1.MyFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>f1</filter-name>
	<url-pattern>/*</url-pattern>
	<dispacther>REQUEST</dispatcher>
</filter-mapping>

这里url-pattern表示所有的url地址都要经过这个filter过滤。dispatcher的子元素不写的话默认发布方式是REQUEST。

例2:
如果有一个这样的Servlet,如何写一个针对他的Filter呢?

<servlet>
	<servlet-name>AServlet</servlet-name>
	<servlet-class>a.Servlet</servlet-class>
</servlet>
<servelt-mapping>
	<servlet-name>AServlet</servlet-name>
	<url-pattern>/a</url-pattern>
</servlet-mapping>

答案:

<filter>
	<filter-name>myFilter</filter-name>
	<filter-class>b.MyFilter</filter-class>
<filter>
<filter-mapping>
	<filter-name>myFilter</filter-name>
	<servelt-name>AServelt</servlet-name>
	<dispatcher>REQUEST</diapatcher>
</filter-mapping>

另外,用Annotationd写的话

@WebFilter(dispactherTypes={DispatcherType.REQUEST},urlPatterns={"/a"})

这样写注解就很简洁。还可以:

@WebFilter(dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE}, 
  urlPatterns= {"/a"})

访问资源经过多个过滤器的过滤器执行顺序
若使用web.xml声明,优先匹配<url-pattern>,然后是<servlet-name>.若有多个,按照声明顺序。

Enum DispatcherType
servelt3.0规范中,<filter-mapping>中的子标签<dispatcher>里面的元素会被转化为枚举类型DispatcherType。DispatcherType由五个可能值,并且可以在一个<filter-mapping>中加入任意数目的<dispatcher>,使得filteri将会作用于:

  • 1)直接从客户端过来的request(REQUEST)
  • 2)forward来的request(FORWARD)
  • 3)include来的request(INCLUDE)
  • 4)通过类的request(ERROR):
<error-page>
	<error-code>400</error-code>
	<location>/filter/error.jsp</location>
</error-page>

<error-page>
	<error-code>404</error-code>
	<location>/filter/error.jsp</location>
</error-page>

<error-page>
	<error-code>500</error-code>
	<location>/filter/error.jsp</location>
</error-page>

上面的意思是,HTTP请求相应的状态码只要是400,404,500直以,容器就会请求转发到error.jsp之下,这就出发了一次error,走进了DispatcherFilter。但是要注意,虽然把请求转发到error.jsp是一次forward过程,但是配置成<dispatcher>FORWARD</dispatcher>的话并不会走Dispatcher过滤器。

  • 5)还有ASYNC异步而来的请求。有这个的Filter可以拦截异步servlet。

这五种dispatcher方法可以单独使用也可以组合使用。配置多个<dispatcher></dispatcher>即可。

参考文献

孙鑫 深入详解Servlet/JSP
孙卫琴 Tomcat与Java Wev开发技术详解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值