springMVC @ResponseBody HandlerInterceptor ModelAndView null

来源:互联网 发布:博客源码下载 编辑:程序博客网 时间:2024/05/22 05:03

今天springMVC开发遇到一个问题就是:

用了@RestController或者@ResponseBody注解之后,再用 拦截器拦截( HandlerInterceptor)的时候, 里面的 postHandle 的方法的参数ModelAndView 不管怎么弄都是null,很纠结,看了官网文档才知道加了这2个注解其实就不走视图转换而是走的这个类RequestResponseBodyMethodProcessor。



解决办法是加一个切面,然后在切面里面设置返回的参数到request(也可以设置到ThreadLocal)里面 然后拦截器里面在从request或者ThreadLocal里拿即可


切面类如下

@Aspect@Componentpublic class GateWayAOP {    private  ThreadLocal entityThreadLocal=new ThreadLocal();    //Controller层切点路径    @Pointcut("execution(* com.yihu.wlyy.web..*.*(..))")    public void controllerAspect() {    }    public GateWayAOP() {        //System.out.println("Observer---------------------------------------");    }    @Around("controllerAspect()")    public Object checkToken(ProceedingJoinPoint point) throws Throwable {        Object obj = null;        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        try {            obj = point.proceed();        }catch (Exception e){            e.printStackTrace();        }        request.setAttribute("returnObj",obj);//先把结果放进        return obj;    }}

拦截器里面拿

@Componentpublic class GateWayInterceptor implements HandlerInterceptor {    private Logger logger = LoggerFactory.getLogger(GateWayInterceptor.class);    @Autowired    private GcHttpLogDao httpLogDao;    @Autowired    private GcTokenDao gcTokenDaoDao;    /**     * preHandle:预处理回调方法     *     * @param request     * @param response     * @param handler     * @return     * @throws Exception     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        return true;    }    /**     * 后处理回调方法     *     * @param request     * @param response     * @param handler     * @param modelAndView     * @throws Exception     */    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        String output = "";        if (modelAndView != null) {            output = JSONObject.fromObject(modelAndView.getModelMap()).toString();        } else {            Object returnObj = request.getAttribute("returnObj"); //再把结果放进            if (returnObj != null) {                output = JSONObject.fromObject(returnObj).toString();              }        }        HandlerMethod handlerMethod = (HandlerMethod) handler;//        response.getOutputStream()        String token = request.getHeader("accesstoken");        String ip = NetworkUtil.getIpAddress(request);        saveHttpLog(ip,                JSONObject.fromObject(request.getParameterMap()).toString(),                output,                token,                request.getRequestURI(),                GcHttpLog.flagEm.success.getCode(),                null);    }    /**     * 整个请求处理完毕回调方法     *     * @param request     * @param response     * @param handler     * @param ex     * @throws Exception     */    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {    }}


这边要注意的是

因为每次请求都是新的request,所以是线程安全的

用ThreadLocal也是线程安全的


原创粉丝点击