Spring MVC 碰到的实际异常处理

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class OrderAspact {
    
    @Before("execution(* ocj.com.cn.order.service.impl.TestServiceImpl.*(..))")
    public void processBefore(JoinPoint jp){
        //获取方法名
        System.out.println(jp.getSignature().getName());
        //获取参数
        Object[] args = jp.getArgs();
        for(Object a : args){
            System.out.println(a.toString());
        }
        System.out.println("In Aspact");
    }
    
}
 
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Service;


@Aspect 
@Service
public class WrongUrlAdvise{
        @Before("execution(* org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler.handleRequest(..)) and args(request,..)")  
        private void addTag(HttpServletRequest request){
                request.setAttribute(Constants.INVALID_URL, 1);
        }
}
  

第一个是参考,

第二个 使用场景:

1,web框架:spring mvc

2,缓存:ehcache 并且使用的是web page cache, dispatch包含了forward

3,没有使用mvc:resource 给所有静态资源加前缀

4,缓存拦截到request后发现能命中缓存,于是打上visitLog标记并进行build,但是当前无对应的element,于是FilterChain继续走下去直到Controller,然而spring mvc 找不到映射request请求的url或者发生RunTimeException时Spring MVC会forward给容器的Default Servlet去处理, 根据web.xml 会跳转到相应404页面,然而404也符合缓存的pattern于是也被

ehcache的filter捕获, 至此发生重入异常

处理方法

1, 使用aop在DefaultServletHttpRequestHandler forward 之后直接跳转到处理404的controller,可以解决重入但是所有本地静态资源的请求也会被拒绝

2,加参,在发生重入的地方进行判断,直接跳过ehcache的dofilter, 但是之后所有forward到404页面的都会走controller

3,catch到FilterNonReentrantException这个异常,然后redirect到404.

String uri = request.getServletPath();
try {
  // Only cache pages matching specific pattern.
   if (!pattern.matcher(uri).matches() || request.getAttribute(Constants.INVALID_URL) != null) {
     chain.doFilter(request, response);
      return;
   }
。。。。。
  。。。。
  super
.doFilter(request, response, chain); } catch(FilterNonReentrantException ree){   log.error(this .cacheName + " occured reenter error, request is " + request.getAttribute(Constants.SERVLET_FORWARD_REQUEST_URI));   response.sendRedirect(Constants.ERRORPAGE404); } catch (IOException ioe) {   suppressNetworkException(ioe, uri); } catch (Exception ex) {   log.error(ex);   throw ex; }
。。。

参考: DefaultServletHttpRequestHandler.java

posted @ 2013-12-10 16:34  yiyi_2  阅读(542)  评论(0编辑  收藏  举报