首页 > 代码库 > 019医疗项目-模块一:用户身份校验拦截器的调试

019医疗项目-模块一:用户身份校验拦截器的调试

这次调试发现两个问题:

主要如下:

1.在嵌入的页面中,如果session过期了,跳转到登陆页面

现象:

登陆页面是嵌入在页面中。

技术分享

 

 解决办法:

找到登录的jsp页面:login.jsp。然后修改里面的登陆提交的回调方法,

技术分享

问题解决:

解决后如下:

技术分享

 

 

 

还有问题:

问题2:

3、当执行一个提交操作时,session过期,应该跳转登陆页面,本系统提交返回是json(SubmitResultInfo) ,由于LoginInterceptor拦截器作用,拦截了,返回了登陆页面。

无法解析登陆页面内容。

问题演示:

我们先登录一个账号:

技术分享

 

 

然后,再开一个窗口,输入http://127.0.0.1:8080/yycgproject/first.action

技术分享

 

 

 然后点击退出系统,这样的话我们就相当于把这个session给关掉了。接着我们再去看第一个页面,点击“提交”按钮。

结果如下:

技术分享

 

不管怎么点击都没有。

原因如下:

我们按下提交,本来应该提交的是@ResponseBody SubmitResultInfo 这种json格式。然后前台页面解析这种json格式给我们结果,但是我们之前配了一个拦截器,这个提交被拦截器拦截了,结果拦截器返回的是request.getRequestDispatcher("/WEB-INF/jsp/base/login.jsp").forward(request, response);这个东西又不是JSON.一:前台页面不能解析啊。二:也不能跳转到"/WEB-INF/jsp/base/login.jsp"。所以就停止不动了。

解决办法:

在拦截器里面抛异常,然后在全局异常处理器里面去解析这个异常做相应的处理。

LoginInterceptor拦截器代码如下:

public class LoginInterceptor implements HandlerInterceptor {
/**
 * 
 * 执行时间:进入到action方法之前,
 * 使用场景:用于用户的认证,用户的授权拦截。
 * 
 */
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
        HttpSession session=request.getSession();
        ActiveUser activeUser=(ActiveUser)session.getAttribute(Config.ACTIVEUSER_KEY);
        if(activeUser!=null)//说明从Session中取出来用户对象,那么就放行
        {
            return true;
            
        }
//如果activeUser是空的,那就是说明用户没有登录。那么我们就要检测用户的要浏览的是不是公共的界面,如果是的话,也可以放行。
        List<String> open_urls=ResourcesUtil.gekeyList(Config.ANONYMOUS_ACTIONS);
        //Config.ANONYMOUS_ACTIONS就是资源的名字就是anonymousActions。说明要从这里去取值,
        
        
        //得到用户的url
        String url=request.getRequestURI();
        
        //遍历资源文件里面是不是包含了我们要访问的那个url.如果包含了,放行。
        for(String open_url:open_urls)
        {
            
            if(url.indexOf(open_url)>=0)//>=0说明找到位置了
            {
                return true;
            }
            
            
            
            
        }
        
        //如果上面的都没哟满足,那么我们就要拦截下来,跳转到用户的登录界面
        //request.getRequestDispatcher("/WEB-INF/jsp/base/login.jsp").forward(request, response);
        ResultUtil.throwExcepion(ResultUtil.createWarning(Config.MESSAGE, 106,null));//106代表的是“此操作需要登陆后进行”
  
        
        return false;
    }
/**
 * 执行的时机:进入到Action方法,在返回modelAndView之前执行。
 * 使用场景:在这里统一对返回的数据进行处理,比如统一添加菜单,导航等

 */
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        
    }
/**
 * 执行时间:action方法执行完成,已经返回modelAndview,执行
 * 使用的场景:统一处理系统异常,在这里统一记录系统日志,监控action的执行的时间,在preHandle记录开始的时间,在afterCompletion记录结束的时间
 * 
 * 
 * 
 * 
 */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        
        
        
        
        
    }

}
  ResultUtil.throwExcepion(ResultUtil.createWarning(Config.MESSAGE, 106,null));这句话是关键。
我们在来看一下全局异常处理器怎么处理这个情况:
ExceptionResloverCustom.java:

package yycg.base.process.exception;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import yycg.base.process.result.ExceptionResultInfo;
import yycg.base.process.result.ResultInfo;

//全局异常处理器
public class ExceptionResolverCustom implements HandlerExceptionResolver{
 //json转换器
    private HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter;
    public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {
        return jsonMessageConverter;
    }
    public void setJsonMessageConverter(
            HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter) {
        this.jsonMessageConverter = jsonMessageConverter;
    }
    //前端控制器
    //handler就是最后要执行的Action类,Springmvc是面向方法开发的。handler就包装了一个方法
    //这个方法就对应于URL的那个方法,
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        
        
        //输出异常信息
        ex.printStackTrace();
        //在springmvc中,action是被Handle封装起来的,action的方法也被封装到Handle里面了。
        //转成springmvc底层对象,这个底层对象就是对action方法进行封装的那个对象
        HandlerMethod handlerMethod=(HandlerMethod)handler;//这个对象里面只有一个方法。
        Method method=handlerMethod.getMethod();//把这个方法取出来。
        //查找method这个方法上是否有ResponBody这个注解
        ResponseBody responseBody=AnnotationUtils.findAnnotation(method, ResponseBody.class);
        
        if(responseBody!=null)
        {
            //这里说明Action将异常信息转换成能jsoN输出了
            
            return this.resolveJsonException(request, response, handlerMethod, ex);
        }
        
        
        //异常代码
        
        //这里说明action返回的是jsp页面
        //解析异常
        ExceptionResultInfo exceptionResultInfo=resolveExceptioncustom(ex);
        int messagecode=exceptionResultInfo.getResultInfo().getMessageCode();
        String view="/base/error";
        if(messagecode==106)
        {
            
            view="/base/login";
            
        }
        //将异常信息在异常页面输出。
        request.setAttribute("exceptionResultInfo", exceptionResultInfo.getResultInfo());
        //转向错误页面:用Springmvc的方式去转
    ModelAndView modelAndView=new ModelAndView();
    modelAndView.addObject("exceptionResultInfo", exceptionResultInfo.getResultInfo());
    modelAndView.setViewName(view);
    return modelAndView;
    }
    
    private ModelAndView resolveJsonException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)
    {
        //解析异常
        ExceptionResultInfo exceptionResultInfo=resolveExceptioncustom(ex);
        HttpOutputMessage outputMessage=new ServletServerHttpResponse(response);
        
        try {
            //将exceptionResultInfo转成json然后输出,这里直接通过HttpMessageConverter将exceptionResultInfo转化为
            //JSON,然后直接在HttpOutputMessage这个对象中把转化而成的JSON信息写入。输出到客户端。
            
            jsonMessageConverter.write(exceptionResultInfo,MediaType.APPLICATION_JSON,outputMessage );
        } catch (HttpMessageNotWritableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        
        
        
        return new ModelAndView();
    }
    
    
    
    
    private ExceptionResultInfo resolveExceptioncustom( Exception ex)
    {
        ResultInfo resultInfo=null;
        
        //这样的话就是系统的自定义异常
        if(ex instanceof ExceptionResultInfo)
        {
            //解析系统的自定义的异常,
            resultInfo=((ExceptionResultInfo) ex).getResultInfo();
        
        }else {
            //不属于系统自定义异常的话就是未知错误的异常,就是不可知的异常
            resultInfo=new ResultInfo();
            resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
            resultInfo.setMessage("未知错误异常");
            
            
            
            
        }
        return new ExceptionResultInfo(resultInfo);
        
    }

}

主要是这一段:

 String view="/base/error";
        if(messagecode==106)
        {
            
            view="/base/login";
            
        }
就是说如果不发生之前的那种情况,那就不会抛出106的错误,那么就按以前的方法处理(返回错误页)。如果抛出的是106错误,那么返回登录页。




调试如下:

技术分享技术分享

 

按下提交按钮后,给出提示。成功了。

 

019医疗项目-模块一:用户身份校验拦截器的调试