JavaWeb静态资源映射ResourceMappingFilter

概要:

对网站中的目录进行映射,让资源引用更加简单,例如/assets/a/b/c/js/libs/jquery.js可以简化为/res/jquery.js

| |目录

对网站中的目录进行映射,让资源引用更加简单,


源码

package com.itshidu.ssh.commons.filter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 静态资源映射
 * @author 夏增明
 * @date 2011-03-25
 * 
 */
public class ResourceMappingFilter implements Filter {
	
	private List<String> dirs=new ArrayList<String>();//资源文件夹
	private String mapping;
	private ServletContext application;
	private String debug="true";
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0;
		HttpServletResponse response = (HttpServletResponse) arg1;
		
		String uri = request.getRequestURI();
		
		if(uri.indexOf(request.getContextPath()+mapping)!=0){
			chain.doFilter(arg0, arg1);
			return;
		}

		int start = uri.lastIndexOf(mapping)+mapping.length();
		int end = uri.length();
		String name = uri.substring(start, end);

		for(String patt : dirs){
			String resPath = patt+name;
			String realPath = application.getRealPath(resPath);
			if(new File(realPath).exists()){
				RequestDispatcher disp = request.getRequestDispatcher(resPath);
				disp.forward(arg0, arg1);
				return;
			}
		}
		chain.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		String[] arr = config.getInitParameter("location").split(",");
		this.mapping = config.getInitParameter("mapping");
		this.debug = config.getInitParameter("debug");
		
		application = config.getServletContext();
		
		for(String str : arr){
			if(str.endsWith("/*")){
				String res = str.substring(0, str.length()-2);
				String real = application.getRealPath(res);
				File file = new File(real);
				readDirectory(res,file, file);
			}else if(str.endsWith("/")){
				dirs.add(str.substring(0, str.length()-1));
			}else{
				dirs.add(str);
			}
		}
		
		for(String dr : dirs){
			log("ResourceMapping: "+mapping+" --> "+ dr);
		}
	}
	
	private void readDirectory(String dir,File src,File file){
		
		if(file.isDirectory()){
			String res = dir+file.getAbsolutePath().substring(src.getAbsolutePath().length());
			
			dirs.add(res);
			for(File fo : file.listFiles()){
				readDirectory(dir,src,fo);
			}
		}
		
	}
	
	private void log(String info){
		if(debug.equals("true")){
			System.out.println(info);
		}
	}
	
}


配置web.xml

<filter>
  	<filter-name>resourceMapping</filter-name>
  	<filter-class>com.itshidu.ssh.commons.filter.ResourceMappingFilter</filter-class>
  	<init-param>
  		<param-name>location</param-name>
  		<param-value>/WEB-INF/static/*,/assets/*,/resource</param-value>
  	</init-param>
  	<init-param>
  		<param-name>mapping</param-name>
  		<param-value>/res</param-value>
  	</init-param>
  	<init-param>
  		<param-name>debug</param-name>
  		<param-value>true</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>resourceMapping</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>


解释说明

location:本地资源目录,多个目录用英文逗号分隔,xxx/*代表xxx目录和所有后代目录

mapping:虚拟目录,location中设置的目录都将映射到这里

debug:启动是否打印映射信息


通过以上配置,访问资源时会方便很多:

资源路径映射之后的快捷路径
/WEB-INF/static/js/lib/jquery/1.10.js
/res/1.10.js
/assets/a/b/c/d/e/f/g/h/hello.js/res/hello.js
/resource/js/cityloader/index.js
/res/index.js


/assets/a/b/c/d/e/f/g/h/hello.js 

除了/res/hello.js外,也可以写得更详细:

/res/h/hello.js

/res/g/h/hello.js

/res/f/g/h/hello.js

通常,当两个目录中文件名冲突时,我们会使用这种方式进行区分处理。

评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
  • 全部评论(1)
  • 饮冰室主人 如果指定在计算机的任意一个资源目录(也就是不在服务器所在目录),有没有什么好的方式。
资料加载中...
已关注 , 取消