欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

让OpenSessionInViewFilter更灵活的过滤URL 博客分类: Hibernate ServletJSPWebSpringHibernate 

程序员文章站 2024-03-25 08:57:16
...
OpenSessionInViewFilter能很方便的处置视图显示的时候Hibernate的Lazy load 问题,但受制于filter-mapping的url-pattern,如果要精细控制过滤的url,则会导致web.xml文件filter-mapping元素大增,而且url-pattern匹配模式仅限于路径匹配模式、扩展匹配模式及详细匹配模式(参考http://foxty.iteye.com/blog/39332)。

如何更灵活的控制OpenSessionInViewFilter需要过滤的URL?
这里给出一种代价较小,但更灵活的方式:
package com.your.servlet.filter;

import java.io.IOException;

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

import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
import org.springframework.util.AntPathMatcher;

/**
 * 
 * @author llade
 * @version 1.0
 * Creation date: Oct 9, 2008 10:31:32 AM
 */
public class OpenSessionInViewFilterDelegate extends OpenSessionInViewFilter {
	
	protected String[] mappings = new String[]{};
	private AntPathMatcher antPathMatcher = new AntPathMatcher();
	
	private boolean filterURI(String uriWithoutContextPath){
		for (int i = 0; i < mappings.length; i++) {
			if(antPathMatcher.match(mappings[i],uriWithoutContextPath)){
				if(logger.isDebugEnabled()){
					logger.debug("matched,pattern:"+mappings[i]+",uri:"+uriWithoutContextPath);
				}
				return true;
			}
		}
		if(logger.isDebugEnabled()){
			logger.debug("not matched,uri:"+uriWithoutContextPath);
		}
		return false;
	}
	
	
	public String[] getMappings() {
		return mappings;
	}


	public void setMappings(String[] mappings) {
		this.mappings = mappings;
	}


	@Override
	protected void doFilterInternal(HttpServletRequest request,
			HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		String uri = request.getRequestURI();
		String contextPath = request.getContextPath();
		String uriWithoutContextPath = uri.substring(contextPath.length());
		if(this.filterURI(uriWithoutContextPath)){//符合过滤规则.则应用OpenSessionInViewFilter
			super.doFilterInternal(request, response, filterChain);
		}else{//不符合,则不应用
			filterChain.doFilter(request, response);
		}
	}


	@Override
	public void afterPropertiesSet() throws ServletException {
		for (int i = 0; i < mappings.length; i++) {
			mappings[i] = mappings[i].trim();
		}
		super.afterPropertiesSet();
	}

	
}



web.xml配置:
 <filter>
		<filter-name>openSessionInViewFilterDelegate</filter-name>
		<filter-class>	org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>openSessionInViewFilterDelegate</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

这里解释一下,org.springframework.web.filter.DelegatingFilterProxy会找到和<filter-name>名字相同的<bean>来处理符合filter-mapping的url,真正的url过滤放在了OpenSessionInViewFilterDelegate ,所以此处使用匹配所有路径。

spring配置:

<bean id="openSessionInViewFilterDelegate" class="com.your.servlet.filter.OpenSessionInViewFilterDelegate"> 
    <property name="mappings"> 
      <list> 
        <value>/viewlist/**.jsp</value> 
        <value>/do/**.jsp</value> 
        <value>/another/*/*.jsp</value> 
      </list> 
    </property> 
  </bean>


这里使用了ant路径方式,*匹配单层路径,**匹配任何多层路径。而且配置也没那么复杂了。