这次调试发现两个问题:
主要如下:
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错误,那么返回登录页。 调试如下:
按下提交按钮后,给出提示。成功了。
时间: 2024-10-12 18:45:09