接上一篇:FastJson
1. 异常解析器
1.1 现有方案,分散处理
Controller中的每个Handler自己处理异常
public User2 test3(){
User2 user2 = null;
try {
user2 = new User2(1,null,null,new Date(),22222.38);
System.out.println(user2);
} catch (Exception1 e) {
e.printStackTrace();
return "redirect:/xx/error1";
} catch (Exception2 e){
e.printStackTrace();
return "redirect:/xx/error2";
}
return user2;
}
public User2 test4(){
User2 user2 = null;
try {
user2 = new User2(2,null,null,new Date(),2333.18);
System.out.println(user2);
} catch (Exception1 e) {
e.printStackTrace();
return "redirect:/xx/error1";
} catch (Exception2 e){
e.printStackTrace();
return "redirect:/xx/error2";
}
return user2;
}
此种处理方案,异常处理逻辑,分散在各个handler中,不利于集中管理
1.2 异常解析器,统一处理
Controller中的每一个Handler不再自己处理异常,而是直接throws所有异常,定义在一个”异常解析器“集中捕获处理所有异常
- 把所有异常处理放在ex包下
2. resolver包下定义异常解析器:MyExceptionResolver 3. 其他新建如下:
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView();
if (ex instanceof MyException1) {
modelAndView.setViewName("redirect:/error1.jsp");
} else if (ex instanceof MyException2) {
modelAndView.setViewName("redirect:/error2.jsp");
} else if (ex instanceof MyException3) {
modelAndView.setViewName("redirect:/error3.jsp");
}
return modelAndView;
}
}
- mvc.xml配置
<bean class="com.lyx.resolver.MyExceptionResolver"></bean>
- controller
@RequestMapping("/ex")
@Controller
public class ExController {
@RequestMapping("/test")
public String test(Integer id) throws Exception {
if(id==1){
throw new MyException1("testex1");
}
return "success";
}
}
- Tomcat运行,访问http://localhost:8080/ex/test?id=1
2. 拦截器
2.1 现存问题
- 当用户登录成功后在session作用域中添加一个key:value保存一下用户登录状态,代码如下
@Controller
@RequestMapping("/login")
@SessionAttributes("state")
public class LoginController {
@RequestMapping("/save")
public String save(Model model){
model.addAttribute("state","ok");
return "index";
}
}
- 其他方法,要先去判断static是否等于ok,来判断用户是否登录,如果登录了再执行对应的业务,但是如果没有登录,就会跳到登录页面,所以这两个判断和跳转,每一个方法都要判断/跳转一遍,且代码是一样的,这就是Handler中存在的冗余问题
2.2 拦截器
- 针对上述问题,我们可以把上面冗余的代码,写在一个方法里,然后其他方法复用该方法,实现这个效果的就是拦截器
- 拦截器的实现原理就是,当一个方法被调用时,先不执行里面的方法,会先经过拦截器,拦截器里面会执行相关的逻辑,只有拦截器里面的逻辑顺利执行了,拦截器才会放行方法
- 来写一个拦截器
- 新建一个interceptor包,包下新建一个MyInterceptor.java
- 该类implements 了HandlerInterceptor
- 重写了HandlerInterceptor里面的三个方法,preHandle():在handler之前执行,postHandle():在handler之后执行,响应之前执行,afterCompletion():在视图渲染完毕后执行
- 由此可见后面两个方法没有太大的作用
- 代码如下:
代码:
public class MyInterceptor1 implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
package com.lyx.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MyInterceptor1 implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if(session.getAttribute("state")!=null){
return true;
}
response.sendRedirect("/login.jsp");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.3 mvc.xml配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login/test2"/>
<mvc:mapping path="/login/test3"/>
<bean class="com.lyx.interceptor.MyInterceptor1">
</bean>
</mvc:interceptor>
</mvc:interceptors>
2.4 Tomcat运行
- 访问http://localhost:8080/login/test1,未登录,拦截器拦截,跳转到登录页面
- 访问http://localhost:8080/login/test2,未登录,拦截器拦截,跳转到登录页面
- 访问http://localhost:8080/login/save,登录,跳转到index
- 再次访问http://localhost:8080/login/test1,已经登录,拦截器不拦截,执行当前test1中的方法
2.5 mvc.xml配置拦截/不拦截路径
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login/*"/>
<mvc:mapping path="/login/**"/>
<mvc:mapping path="/login/test*"/>
<mvc:exclude-mapping path="/login/save"/>
<bean class="com.lyx.interceptor.MyInterceptor1">
</bean>
</mvc:interceptor>
</mvc:interceptors>
- 对应拦截路径配置: <mvc:mapping path=“/login/*”/>,Tomcat运行,访问路径:http://localhost:8080/login/b/test1,就不会被拦截
|