Spring MVC整合异常解析器和拦截器

使用Spring MVC让我们的开发变的更加方便,今天的内容介绍有关异常解析器和拦截器的相关内容

异常解析器:Controller中的Handler中可能会有要处理的异常,而且有时是重复的异常,我们定义异常解析器之后就可以在每个Handler只需抛出异常,然后异常解析器会帮我们执行,并重定向到要提示的错误页面

拦截器:Controller中的Handler中可能会有冗余的功能(代码),比如:有多个Handler中都要判断登录的状态,只有登录之后才能进行下一步的操作,使用拦截器中将冗余的功能分离出来,即可以减少代码量,也可以让维护变的简单

异常解析器

现有方案,分散处理

controller中的每个Handler自己处理异常

此种处理方案,异常处理逻辑,分散在各个handler中,不利于集中管理,而且可能多个handler中处理的异常时相同的处理逻辑,导致代码冗余

public String xxx(){
    try{
        ...
    }catch(Exception1 e){
        e.printStackTrace();
        return "redirect:xxx/error1.jsp";
    }atch(Exception2 e){
        e.printStackTrace();
        return "redirect:xxx/error2.jsp";
    }
    return "success";
}

异常解析器,统一处理

Controller中每个Handler不再自己处理异常,而是直接throws所有异常

定义一个"异常解析器"集中捕获处理所有的异常

此种方案,在集中管理异常方面,更有优势

  • 执行时机:任何一个handler抛出异常时

定义了一个异常解析器

扫描二维码关注公众号,回复: 11503752 查看本文章
/**
 * 异常解析器
 * 执行时机:任何一个handler抛出异常时
 */
public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        if (e instanceof MyException1){
            modelAndView.setViewName("redirect:/error1.jsp");
        }else if (e instanceof MyException2){
            modelAndView.setViewName("redirect:/error2.jsp");
        }else if (e instanceof MyException3){
            modelAndView.setViewName("redirect:/error3.jsp");
        }
        return modelAndView;
    }
}

在Spring中对该异常解析器进行注册就可以使用

这样我们之后在handler中发生异常时,只需要将异常抛出

模拟在handler中异常的抛出

@RequestMapping("test1")
public String xxx(Integer id){
	if(id==1){
        throws new MyExcetion1("test ex1");
    }
    return "success";
}

在定义了异常解析器时,我们的handler如果发生我们抛出的异常,那么就会由异常解析器将其转到我们定义要转跳的错误页面.

总结:

以后在我们的项目中只需要定义一个异常解析器,那么所有handler都不需要自己直接处理异常,只需要抛出由异常解析器处理即可.

拦截器

作用:抽取handler冗余功能

定义拦截器

执行顺序是:

perHandler-postHandler-afterHandler

举例:

比如在一个Controller中有登录,查询所有用户,删除一个用户三个Handler,er查询所有用户和删除一个用户都是需要判断在登录的条件下才能操作

那么在这两个Handler中就有大量的重复的功能(代码)

package per.leiyu.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @author 雷雨
 * @date 2020/6/27 16:34
 */
public class MyInterceptor  implements HandlerInterceptor {
    /**
     * 在Handler在前执行
     * 在其中定义Handler中冗余的功能
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //我们可以在这做关于登录状态
        HttpSession session=  httpServletRequest.getSession();
        if (session!=null){
            return true;
        }else{
            //中断请求之前,响应请求,把它重定向到登录页面
            httpServletResponse.sendRedirect("login.jsp");
            return false;
        }

    }

    /**
     * 在Handler之后执行,但是在响应之前执行
     * 可以改动请求中的数据
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 在视图渲染完毕之后执行,也就是在响应之后执行
     * 一般用来做资源的回收
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

配置拦截器

定义了拦截器,要配置拦截器,告诉Spring工厂,也要告诉我们拦截器要拦截的路径是什么

<!-- 拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="要拦截的handler的路径"/>
        <!-- 支持的写法 -->
        <!--<mvc:mapping path="/inter/test1"/> -->
        <!--<mvc:mapping path="/inter/test2"/> -->
        <!--<mvc:mapping path="/inter/*"/> -->
        <!--<mvc:mapping path="/inter/test*"/> -->
        <!--<mvc:mapping path="/inter/**"/> 包含inter中的所有子路径的handler  -->
        <!--<mvc:exclude-mapping path="/inter/test1"/>  表示不包含(不拦截)的handler的路径 -->
        <bean class="拦截器的路径"/>
    </mvc:interceptor>
</mvc:interceptors>
    

我是雷雨,一个普本科的学生,主要专注于Java后端和大数据开发

如果这篇文章有帮助到你,希望你给我一个大大的赞
如果有什么问题,希望你能留言和我一起研究,学习靠自觉,分享靠自愿

转载注明出处
https://blog.csdn.net/qq_40742223

猜你喜欢

转载自blog.csdn.net/qq_40742223/article/details/106987641