这里我把需要重写的URL统一放在一个容器里(map)
代码如下:
package com.jym.filter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @author 作者 :Jym
* @version 创建时间:2019年10月8日 上午9:39:39
* HttpServletRequest的装饰类
* 用来改变HttpServletRequest的状态, 对请求内容的过滤
*
*/
public class JymUrlRewriteServletRequestWrapper extends HttpServletRequestWrapper{
private Map<String,String> resourceMap; // 资源映射表
public JymUrlRewriteServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getRequestURI(){
String s1 = super.getRequestURI();
int i = super.getContextPath().length();
String oldUri = s1.substring(i);
return transcode(oldUri);
}
@Override
public StringBuffer getRequestURL(){
String oldUri = super.getRequestURI().substring(super.getContextPath().length());
StringBuffer sb = new StringBuffer();
String url = super.getRequestURL().toString().replaceAll(oldUri,transcode(oldUri));
return sb.append(url);
}
@Override
public String getServletPath(){
String s1 = super.getRequestURI();
int i = super.getContextPath().length();
String oldUri = s1.substring(i);
return super.getServletPath().replaceAll(oldUri,transcode(oldUri));
}
//初始化url资源
public void initMapping(Map<String, String> resourceMap) {
this.resourceMap = resourceMap;
}
/**
*
* @Title: transcode
* @Description: 获取css等静态资源重写的url
* @param @param key 原来的请求路径
* @param @return
* @return String
* @throws
*/
private String transcode(String key){
//如果map中有对应的value,则采用value的请求路径 否则采用原来的
String value = resourceMap.get(key);
if(null != value){
return value;
} else {
return key;
}
}
}
这里我简单的把资源容器添加了几条数据,正常可以维护进数据库
package com.jym.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* @author 作者 :Jym
* @version 创建时间:2019年10月8日 上午9:39:03
*
*/
public class JymUrlRewriteFilter extends OncePerRequestFilter{
//不参加重写的请求后缀 如果web.xml没配置则默认用该变量
private static final String DEFAULT_EXECUDE_EXTENTIONS = "jsp,jspx,do";
//默认统一静态资源路径到static文件夹下(如果SpringMVC配置文件已经对静态资源处理 则不需要此变量) 如果web.xml没配置则默认用该变量
private static final String DEFAULT_PREFIX = "/static";
private final Logger logger = LoggerFactory.getLogger(JymUrlRewriteFilter.class);
//统一静态资源路径 web.xml配置
private String prefix;
//不参加重写的请求后缀 web.xml配置
private Set<String> excludeExtentions = new HashSet<String>();
//资源映射map 可维护到数据库
private Map<String, String> resourcemap = new HashMap<String, String>();
/**
* 初始化时装置静态资源
*/
@Override
protected void initFilterBean() throws ServletException {
//这里简单写死,正常应该从数据库读取,初始化map
resourcemap.put("/test","/model/test");
super.initFilterBean();
try {
//初始化参数prefix excludeExtentions
initParameter(getFilterConfig());
} catch (IOException e) {
throw new ServletException("init paramerter error",e);
}
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 防止缓存
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
// 在请求消息中发送将使得请求和响应消息都不使用缓存
response.setHeader("Cache-Control", "no-store");
// 设置过期的时间期限 0s 不进行缓存
response.setDateHeader("Expires", 0);
String from = request.getRequestURI().substring(request.getContextPath().length());
if(rewriteURL(from)) {
//css,js等静态资源 统一放入static文件夹下 否则404
final String to = prefix + transcode(from);
logger.debug("UrlRewriteFilter: forward request from "+from+" to "+to);
//重定向到该路径
request.getRequestDispatcher(to).forward(request, response);
}else {
//重写url
JymUrlRewriteServletRequestWrapper newRequest = new JymUrlRewriteServletRequestWrapper((HttpServletRequest) request);
//初始化url重写容器
newRequest.initMapping(resourcemap);
logger.debug("UrlRewriteFilter: rewrite newuri:"+newRequest.getRequestURI());
filterChain.doFilter(newRequest, response);
}
}
/**
*
* @Title: transcode
* @Description: 获取css等静态资源重写的url
* @param @param key 原来的请求路径
* @param @return
* @return String
* @throws
*/
private String transcode(String key){
//如果map中有对应的value,则采用value的请求路径 否则采用原来的
String value = resourcemap.get(key);
if(null != value){
return value;
} else {
return key;
}
}
/**
*
* @Title: initParameter
* @Description: 从web.xml中读取 初始化参数
* @param @param filterConfig
* @param @throws IOException
* @return void
* @throws
*/
private void initParameter(FilterConfig filterConfig) throws IOException {
//如果xml中该拦截器参数没有配置prefix,则启用默认DEFAULT_PREFIX,如果配置了 采用xml中配置的参数
prefix = getStringParameter(filterConfig,"prefix",DEFAULT_PREFIX);
String excludeExtentionsString = getStringParameter(filterConfig,"excludeExtentions",DEFAULT_EXECUDE_EXTENTIONS);
excludeExtentions = new HashSet<String>((Arrays.asList(excludeExtentionsString.split(","))));
logger.debug("RestUrlRewriteFilter.prefix="+prefix+" will rewrite url from /demo.html => ${prefix}/demo.html by forward");
logger.debug("RestUrlRewriteFilter.excludeExtentions=["+excludeExtentionsString+"] will not rewrite url");
}
/**
*
* @Title: rewriteURL
* @Description: 判断是否需要重写url
* @param 请求url
* @param @return
* @return boolean
* @throws
*/
private boolean rewriteURL(String from) {
//获取url请求的后缀
String extension = StringUtils.getFilenameExtension(from);
//正常后台请求
if(extension == null || "".equals(extension)) {
return false;
}
//json,xml等
if(excludeExtentions.contains(extension)) {
return false;
}
//css,js,jpg等静态文件返回true
return true;
}
/**
*
* @Title: getStringParameter
* @Description: 如果web.xml中该拦截器参数没有配置name参数,则启用默认defaultValue,如果配置了 采用xml中配置的参数
* @param @param filterConfig
* @param @param name
* @param @param defaultValue
* @param @return
* @return String
* @throws
*/
private String getStringParameter(FilterConfig filterConfig,String name,String defaultValue) {
String value = filterConfig.getInitParameter(name);
if(value == null || "".equals(value.trim())) {
return defaultValue;
}
return value;
}
}
JymUrlRewriteFilter
com.jym.filter.JymUrlRewriteFilter
prefix
/static
excludeExtentions
jsp,jspx,do,json,xml,swf,zip
JymUrlRewriteFilter
/*
@Controller
@RequestMapping("/model")
public class ModelDataController {
@RequestMapping("/test")
public String test(Student student){
return "index";
}
}
正常应该访问:/model/test
但是我们之前在重写过滤器中的map中添加了resourcemap.put("/test","/model/test")这段代码
所以我们直接访问/test