宁波网站推广制作公司,招聘页面模板,做导航网站有发展吗,wordpress配置百度云cdn加速异常处理
异常处理思路#xff1a;Controller 调用 service#xff0c;service 调用 dao#xff0c;异常都是向上抛出的#xff0c;此时 DispatcherServlet 会暂停正常的请求处理流程#xff0c;转而进入异常处理流程#xff0c;并将异常交给异常解析器处理。
controll…异常处理异常处理思路Controller 调用 serviceservice 调用 dao异常都是向上抛出的此时 DispatcherServlet 会暂停正常的请求处理流程转而进入异常处理流程并将异常交给异常解析器处理。controller代码Controller RequestMapping(/exception) public class ExController { /** * try-catch 处理异常 */ RequestMapping(/findAll.do) public String findAll1(){ try { System.out.println(执行了...); // 模拟异常 int a 10 / 0; } catch (Exception e) { e.printStackTrace(); //跳转到友好提示页面 } return suc; } /** * 使用异常处理器方式 */ RequestMapping(/findAl2.do) public String findAll2(){ System.out.println(执行了...); // 模拟异常 int a 10/0; return suc; } }自定义异常类与业务相关的异常需要遵循JDK异常规范继承 Exceptionpublic class SysException extends Exception { private String message; Override public String getMessage() { return message; } public void setMessage(String message) { this.message message; } public SysException(String message) { this.message message; } }message 是一个用于存储异常信息的成员变量作用是描述当前异常发生的具体原因或详细信息。当创建 SysException 实例时会将具体的异常描述字符串传入并赋值给 message之后可以通过 getMessage() 方法获取这个信息用于调试或向用户展示错误原因。自定义异常处理器SpringMVC 提供了 HandlerExceptionResolver 异常处理的核心接口定义了处理异常的规范public class SysExceptionResolver implements HandlerExceptionResolver { Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { // 在控制台打印异常的信息 e.printStackTrace(); // 声明变量 SysException exception null; // 如果是自定义的SysException直接强转使用 if(e instanceof SysException){ exception (SysException)e; }else { // 如果是其他异常则包装成一个新的SysException并设置默认提示信息 exception new SysException(系统正在维护请联系管理员); } // 存入异常提示信息 ModelAndView mv new ModelAndView(); //Throwable定义了getMessage()方法用于返回异常/错误的详细描述信息 mv.addObject(errorMsg,e.getMessage()); // 设置跳转的页面 mv.setViewName(error); return mv; } }如果捕获的异常 e 是 SysException 类型直接强转使用如果是其他异常则包装成一个新的SysException并设置默认提示信息 “系统正在维护请联系管理员”目的是将所有异常统一转为SysException类型便于后续统一处理避免对不同异常类型写重复代码。通过 e.getMessage() 获取异常的消息文本将其存入模型中指定异常发生时要跳转的视图名称为error最终返回ModelAndViewSpring 会根据该对象渲染对应的错误页面并响应给客户端。SpringMVC 基于组件式开发在 springmvc.xml 配置文件中配置异常处理器!--配置异常处理器-- bean idsysExceptionResolver classcom.qcby.util.SysExceptionResolver /jsp页面代码% page contentTypetext/html;charsetUTF-8 languagejava isELIgnoredfalse % html head title错误提示页面/title /head body h3错误的友好提示页面/h3 ${errorMsg} /body /html效果展示拦截器在 SpringMVC 中拦截器是一种基于 AOP 思想的组件主要用于对处理器进行预处理和后处理技术拦截器Filter和过滤器Interceptor的功能比较类似但有区别技术归属与依赖 过滤器属于Servlet 规范的一部分定义在javax.servlet包中不依赖任何框架只要是 Servlet 容器如Tomcat就能运行可以通过web.xml或WebFilter注解配置过滤器 拦截器是Spring 框架提供的组件定义在org.springframework.web.servlet包中依赖于 Spring 容器仅在 Spring 环境中生效其运行需要 Spring 的 DispatcherServlet 调度本质是 Spring 对请求处理流程的增强。作用范围与处理对象 过滤器处理的是ServletRequest 和 ServletResponse 对象关注的是请求数据响应数据本身作用于整个请求、响应周期可以处理所有进入 Servlet 容器的请求覆盖范围更广 拦截器只拦截通过 DispatcherServlet 分发的请求即处理的是 HandlerMethodSpringMVC 的 Controller 方法关注的是业务方法调用范围更窄。执行时机与生命周期 过滤器的生命周期由Servlet 容器管理随容器启动而初始化随容器关闭而销毁 拦截器的生命周期由Spring 容器管理随 Spring 上下文初始化而创建随上下文销毁而销毁。自定义拦截器步骤首先需要定义一个controller层的方法用于测试Controller RequestMapping(/dept) public class DeptController { /** * 测试方法 * return */ RequestMapping(/findAll.do) public String findAll() { System.out.println(controller方法执行了...); return suc; } }创建一个自定义拦截器类需要实现HandlerInterceptor接口重写接口内需要的方法public class MyInterceptor implements HandlerInterceptor { /** * 拦截controller中方法 */ Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(MyInterceptor的preHandle方法执行了...); // 手动跳转页面 // request.getRequestDispatcher(/WEB-INF/pages/suc.jsp).forward(request,response); // 拦截不放行 //return false; // 放行,执行controller中方法 return true; } }需要在 springmvc.xml 配置文件中配置拦截器并指定拦截 / 排除的路径!--配置拦截器-- mvc:interceptors mvc:interceptor !--该拦截器拦截哪些资源-- mvc:mapping path/dept/**/ !--哪些资源不拦截 mvc:exclude-mapping path / -- !--拦截器对象-- bean classcom.qcby.util.MyInterceptor1 / /mvc:interceptor /mvc:interceptors请求路径http://localhost:8080/dept/findAll.do打印结果如图即 MyInterceptor 拦截器生效了请求处理的大致流程为客户端请求 → 过滤器 → Servlet容器 → DispatcherServlet → 拦截器 → Controller → 拦截器 → DispatcherServlet → 过滤器 → 客户端响应拦截器围绕 Controller 方法的调用在 HandlerInterceptor 接口中的有三个核心方法preHandle是在 Controller 方法执行前拦截的方法可以使用request或者response跳转到指定的页面 return true 放行执行下一个拦截器如果没有拦截器则执行controller中的方法return false 不放行会终止后续流程包括controller中的方法与后续拦截器postHandle是在 Controller 方法执行之后、视图渲染之前拦截的方法可以使用request、response的方式或者通过 return xxx指定了要跳转的视图若指定了跳转的页面那么跳转操作会覆盖 Controller 原本指定的页面Controller 方法所要跳转的页面将不会显示afterCompletion是在整个请求处理完成视图渲染后拦截的方法request或者response不能再跳转页面了。public class MyInterceptor1 implements HandlerInterceptor { /** * 拦截controller中的方法 */ //controller方法执行前拦截的方法 Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{ System.out.println(MyInterceptor1的preHandler方法执行了); // 手动跳转页面 // request.getRequestDispatcher(/WEB-INF/pages/suc.jsp).forward(request,response); // 拦截不放行 //return false; // 放行,执行方法 return true; } //controller方法执行后拦截的方法 Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception{ System.out.println(MyInterceptor1的postHandle方法执行了...); // 也是可以进行页面的跳转 request.getRequestDispatcher(/WEB-INF/pages/suc.jsp).forward(request,response); return; } //controller跳转的jsp页面都执行完成了最后执行该方法 Override public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex)throws Exception{ System.out.println(MyInterceptor1的afterCompletion方法执行了...); } }配置多个拦截器可以定义拦截器链拦截器链就是将拦截器按着一定的顺序结成一条链在访问被拦截的方法时拦截器链中的拦截器会按着定义的顺序执行我们再定义一个拦截器public class MyInterceptor2 implements HandlerInterceptor { /** * 拦截controller中方法 */ Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(MyInterceptor2的preHandle方法执行了...); // 放行,执行controller中方法 return true; } /** * controller方法执行后要拦截的方法 */ Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(MyInterceptor2的postHandle方法执行了...); } /** * controller跳转的jsp页面都执行完成了最后执行该方法 */ Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(MyInterceptor2的afterCompletion方法执行了...); } }配置两个拦截器mvc:interceptors !--配置拦截器-- mvc:interceptor !--该拦截器拦截哪些资源-- mvc:mapping path/dept/**/ !--哪些资源不想拦截 mvc:exclude-mapping path / -- !--拦截器对象-- bean classcom.qcby.util.MyInterceptor1 / /mvc:interceptor !--配置拦截器-- mvc:interceptor mvc:mapping path/**/ bean classcom.qcby.util.MyInterceptor2 / /mvc:interceptor /mvc:interceptors总结执行顺序请求前阶段preHandle按拦截器注册顺序执行MyInterceptor1→MyInterceptor2目标业务Controller仅在所有拦截器的 preHandle 都返回 true 后才执行响应后阶段postHandle、afterCompletion按注册逆序执行MyInterceptor2→MyInterceptor1。