`
jiangshaolin
  • 浏览: 55905 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

关于url映射

    博客分类:
  • java
阅读更多
最近在新项目中想使用一个映射规则,如下:
URL映射过程(严格遵守,如果method为空,则默认执行类特定名字的方法)
http://host:port/model/method?paramName=paramValue...
实现思想:
1,用一个过滤器去获得请求uri,再把uri转化为model.do?method=method的请求,然后调用RequestDispatcher.forward(request, response)方法转发。
2,再在web.xml中配置过滤.do的ActionServlet过滤器。

在测试一个<jsp:include page="/model/method">的时候发现存在如下问题:
The requested resource (/model/method) is not available
于是把过滤器设为
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
结果出现死无限制执行,堆栈溢出。

晚上下载urlrewriter开源项目,读了一下源代码,并没有发现解决方案,并测试了一下也出现同样的问题。(就是当<jsp:include>的时候就出问题了),不过他可以配置请求是哪种类型,比如redirect,forward,include等,但还是无法完全避免一种场景:
/a映射到a.jsp
/b映射到b.jsp
然后a.jsp里面有<jsp:include page="/b">的情形
如果是这样,一旦请求/a,则urlrewriter必出问题。

我的过滤器代码如下:
import java.io.IOException;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 所有请求必经此类,处理url映射规则
 * @author jsl
 * @date 2010/3/2
 *
 */
public class RequestFilter implements Filter{

	private static Log log = LogFactory.getLog(RequestFilter.class);
	public void destroy() {
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		String uri = req.getRequestURI();
		
		log.debug("req.getRequestURI():"+uri);
		log.debug("req.getContextPath():"+req.getContextPath());
		// not forward uri
		if(uri.indexOf(".")!=-1){
			log.debug("not forward uri");
			chain.doFilter(request, response);
			return ;
		}
		
		//calc forward uri
		
		String target = "";
		if("".equals(req.getContextPath())){
			target = calcForwardUri(uri);
		}else{
			target = calcForwardUri(uri.replaceFirst(req.getContextPath(), ""));
		}
		log.debug("forward uri:"+target);
		
		
		//forward uri
		if (resp.isCommitted()) {
            log.error("response is comitted cannot forward to " + target +
                    " (check you haven't done anything to the response (ie, written to it) before here)");
        }else{
    		RequestDispatcher dispatcher = getRequestDispatcher(req, target);
    		dispatcher.forward(request, response);
        }
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		
	}
	
	/**
	 * calculate forward uri   example: /aa/bb   /aa
	 */
	private String calcForwardUri(String uri){
		//web root
		if("/".equals(uri)){
			return "/";
		}
		
		StringBuffer sb = new StringBuffer("/");
		String[] temp = uri.split("/");
		sb.append(temp[1]);
		sb.append(".do");
		if(temp.length>=3){
			sb.append("?method=").append(temp[2]);
		}
		return sb.toString();
	}
	private RequestDispatcher getRequestDispatcher(final HttpServletRequest hsRequest, String toUrl) throws ServletException {
        final RequestDispatcher rq = hsRequest.getRequestDispatcher(toUrl);
        if (rq == null) {
            // this might be a 404 possibly something else, could re-throw a 404 but is best to throw servlet exception
            throw new ServletException("unable to get request dispatcher for " + toUrl);
        }
        return rq;
    }
	public static void main(String[] args) {
		String s ="/abc/d";
		System.out.println(s.replaceFirst("/abc", ""));
		System.out.println(s.indexOf("/",1));
		
		System.out.println(s.split("/")[1]);
	}
}


不知道大家有没有碰到此类问题或已经有相应的解决方案?
分享到:
评论
2 楼 jiangshaolin 2010-03-07  
刚测试了Struts也存在同样的问题

.do-->jsp(包含<jsp:include page="XX.do">语句)
因为ActionForward也是用forward实现,所以错误信息如下:
java.io.IOException: Stream closed
1 楼 jiangshaolin 2010-03-06  
参考了大量资料,包括tomcat源码,jsp/servlet规范,做了不少测试.
<jsp:include>is not a request?

Filter不再起作用?

相关推荐

Global site tag (gtag.js) - Google Analytics