ONE:异常处理
一、自定义一个异常类
继承Exception类,通过get和set来设置异常信息
public class SysException extends Exception {
private String message;
public SysException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
二、自定义异常处理
通过实现HandlerExceptionResolver接口,并编写实现方法
//这里通过Component向spring的IOC容器添加这个自定义异常处理类对象
@Component
public class exceptionResolver implements HandlerExceptionResolver {
//这里的参数,前两个就不多说了,后面是
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
//在控制台打印异常信息
e.printStackTrace();
//创建一个自定义异常对象
SysException sysException = null;
//如果要抛出的异常是属于我们定义的异常
//向下转型成我们定义的异常
if (e instanceof SysException){
sysException = (SysException)e;
}else{
//否则,生成新的异常对象,并设置message为“请联系管理员”
sysException = new SysException("请联系管理员!");
}
ModelAndView mv = new ModelAndView();
//返回一个自定义的异常信息,存入exceptionMsg这个key中
mv.addObject("exceptionMsg",sysException.getMessage());
//设置转到特定的error页面
mv.setViewName("/WEB-INF/pages/error.jsp");
return mv;
}
}
三、controller层方法
@Controller
@RequestMapping("exception")
public class exceptionController {
@RequestMapping("testException")
public String testException() throws Exception {
try{
//产生异常,进入catch
int a = 10/0;
}catch (Exception e){
//先在控制台打印异常信息
e.printStackTrace();
//跑出自定义类SysException类的对象,并指定message为哈哈哈
throw new SysException("哈哈哈");
}
//若无异常,跳转成功页面(显然不会执行)
return "success";
}
}
四、jsp页面
index.jsp:
通过点击标签执行controller里对应的方法
<a href="exception/testException">testException</a>
error.jsp:
运行结果:
梳理:
通过抛出自定义的异常,来执行自定义的异常处理器,通过这个异常处理器处理异常(或者转向指定的异常页面),避免执行错误时在浏览器中打印一堆错误信息。
TWO:拦截器
拦截器的概述
- SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
- 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
- 拦截器和过滤器的功能比较类似,有区别
- 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
- 拦截器是SpringMVC框架独有的。
- 过滤器配置了/*,可以拦截任何资源。
- 拦截器只会对控制器中的方法进行拦截。
- 拦截器也是AOP思想的一种实现方式
- 想要自定义拦截器,需要实现HandlerInterceptor接口。
拦截器和过滤器的区别:
过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。
拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。
拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的
总之,拦截器拦截的东西只会拦截控制器中的方法,并且只有springMVC框架里才能用
一、编写controller里的方法
@Controller
@RequestMapping("interceptor")
public class interceptorController {
@RequestMapping("testInterceptor")
//执行时打印方法执行
public String testInterceptor(){
System.out.println("testInterceptor执行了...");
//执行成功则跳转success页面
return "success";
}
}
二、编写拦截器
第一层拦截器和第二层拦截器
第一层拦截器:
public class LeverOneInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("第一层拦截器(执行前)");
//这里加了一个转发的路径来测试,暂时设置成error.jsp的页面好了,虽然不是真的发生了异常
request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
//true表示允许通过,转向下一层拦截器或者controller的执行方法
//false表示不给予通过,被拦截,无法转向下一层
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("第一层拦截器(执行后)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("第一层拦截器(执行完成)");
}
}
第二层拦截器:
public class LeverTwoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("第二层拦截器(执行前)");
//此处也给予通过
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("第二层拦截器(执行后)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("第二层拦截器(执行完成)");
}
}
三、配置拦截器
在springmvc.xml中添加如下配置:
<mvc:interceptors>
<!--第一层拦截器-->
<mvc:interceptor>
<!--表示方法的路径,此处表示interceptor下面的所有方法都拦截-->
<mvc:mapping path="/interceptor/*"/>
<!--第一层拦截器的全限定类名-->
<bean class="com.ssn.interceptor.LeverOneInterceptor"></bean>
</mvc:interceptor>
<!--第二层拦截器-->
<mvc:interceptor>
<!--表示方法的路径,此处表示interceptor下面的所有方法都拦截-->
<mvc:mapping path="/interceptor/*"/>
<!--第二层拦截器的全限定类名-->
<bean class="com.ssn.interceptor.LeverTwoInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
三、jsp页面
index.jsp
<a href="interceptor/testInterceptor">测试拦截器</a>
success.jsp
<h3>成功</h3>
<% System.out.println("成功页面执行了");%>
error.jsp
<h3>异常页面</h3>
<% System.out.println("异常页面执行了");%>
运行结果
这里有一个小问题,就是,在异常页面之后,还执行了成功页面,但是为什么最终显示的是异常页面呢?
虽然这个做法很迷惑,因为基本不会在允许通过(return true)的情况下去请求另外一个页面
我也不知道…日后知道了再补充