Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 304|回复: 0

Shiro异常处理总结

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-13 12:16:11 | 显示全部楼层 |阅读模式

    出自:https://blog.csdn.net/goodyuedandan/article/details/62420120

    一、Spring MVC处理异常有3种方式: 
    (1)使用Spring-MVC提供的SimpleMappingExceptionResolver;
    (2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;

    (3)使用@ExceptionHandler注解实现异常处理;

     

    Spring HandlerExceptionResolver implementations deal with unexpected exceptions that occur during controller execution. A HandlerExceptionResolver somewhat resembles the exception mappings you can define in the web application descriptor web.xml. However, they provide a more flexible way to do so. For example they provide information about which handler was http://blog.csdn.net/frankcheng5143/article/details/50890118executing when the exception was thrown. Furthermore, a programmatic way of handling exceptions gives you more options for responding appropriately before the request is forwarded to another URL (the same end result as when you use the Servlet specific exception mappings).

    Besides implementing the HandlerExceptionResolver interface, which is only a matter of implementing the resolveException(Exception, Handler) method and returning a ModelAndView, you may also use the provided SimpleMappingExceptionResolver or create @ExceptionHandler methods. The SimpleMappingExceptionResolver enables you to take the class name of any exception that might be thrown and map it to a view name. This is functionally equivalent to the exception mapping feature from the Servlet API, but it is also possible to implement more finely grained mappings of exceptions from different handlers. The @ExceptionHandler annotation on the other hand can be used on methods that should be invoked to handle an exception. Such methods may be defined locally within an @Controller or may apply to many @Controller classes when defined within an @ControllerAdvice class. The following sections explain this in more detail.

    在Controller执行过程中发生的异常可以通过Spring的HandlerExceptionResolver实现类来处理异常,它有点像web.xml中你所能定义的那种错误页面。然而,它提供的方式比web.xml更加灵活性。比如它能提供发生异常所在handler的信息,而且通过编程处理异常在转发请求的时候给开发者更多的选择。除了通过实现HandlerExceptionRresolver接口来处理异常之外(它通常是实现resolveException(Exception, Handler)方法并返回一个ModelAndView)开发人员还可以使用SimpleMappingExceptionResolver 或者@ExceptionHandler来处理异常。开发者可以通过SimpleMappingExceptionResolver将异常的类名和一个视图名映射起来,这等同于通过Servlet API的映射, 但是它可以实现更加细粒度的将异常映射到不同的handler上。 在Controller中,可以通过@ExceptionHandler注解来处理异常@ExceptionHandler注解在方法之上,将或者通过@ControllerAdvice定义在许多的Controller上。

    (1)使用SimpleMappingExceptionResolver实现异常处理,能够轻松的将异常映射到对应的错误视图上,在处理请求的时候Spring MVC可能抛出很多异常,给客户端返回信息的时候需要和相关的错误码匹配,根据错误给客户的返回相关的错误代号;

     在springMvc-content.xml配置文件如下:

        <!-- shiro异常处理 -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
           <property name="exceptionMappings">
              <props>
                 <prop key="org.apache.shiro.authz.AuthorizationException">/unauthor</prop> 
                  <prop key="java.lang.Throwable">error/500</prop> 
              </props>
           </property>
        </bean>

     

     

    DefaultHandlerExceptionResolver将SpringMVC的异常分发到不同的错误代码上,下面是错误代码和异常的对应关系:

     

     

    (2) 实现HandlerExceptionResolver 接口自定义异常处理器,HandlerExceptionResolver是一个接口,只有一个方法,我们只需要实现这个接口;

    在springMvc-content.xml配置文件如下:

    <!--然后通过 Spring的HandlerExceptionResolver去进行全局捕获,不论你在系统哪里去throw,只要实现了 HandlerExceptionResovler这个接口,Spring都会拦截下异常进行处理  -->
    <bean id="exceptionResolver" class="com.lf.resolver.MyExceptionResolver"></bean>

     

    我的实现如下:

    public class MyExceptionResolver implements HandlerExceptionResolver {
    
       public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
          System.out.println("==============异常开始=============");
             ex.printStackTrace();
          System.out.println("==============异常结束=============");
          ModelAndView mv = new ModelAndView("error");
          mv.addObject("exception", ex.toString().replaceAll("\n", "<br/>"));
          return mv;
       }
    
    }

     

    (3)@ExceptionHandler注解实现异常处理

    将@ExceptionHandler标注在Controller的方法上,该方法将处理由@RequestMapping方法抛出的异常。

    首先要增加BaseController类,并在类中使用@ExceptionHandler注解声明异常处理,代码如下:

    public class BaseController {
       /** 基于@ExceptionHandler异常处理 */
      @ExceptionHandler
       public String exp(HttpServletRequest request, Exception ex) {
          request.setAttribute("ex", ex);
          // 根据不同错误转向不同页面  
          if(ex instanceof BusinessException) {
             return "business_error";
          }else if(ex instanceof ParameterException) {
             return "parameter_error";
          } else {
             return "error";
          }
       }
    }

    然后需要修改现有代码,使所有需要异常处理的Controller都继承该类,如下所示:

    public class TestController extends BaseController

     

    三、未捕获异常的处理 :

            对于Unchecked Exception而言,由于代码不强制捕获,往往被忽略,如果运行期产生了UncheckedException,而代码中又没有进行相应的捕获和处理,则我们可能不得不面对尴尬的404、500……等服务器内部错误提示页面。 
            我们需要一个全面而有效的异常处理机制。目前大多数服务器也都支持在Web.xml中通过<error-page>(Websphere/Weblogic)或者<error-code>(Tomcat)节点配置特定异常情况的显示页面。

    实现方式如下:

     

    修改web.xml文件,增加以下内容:

    <!-- 出错页面定义 -->
    <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/500.jsp</location>
    </error-page>
    <error-page>
    <error-code>500</error-code>
    <location>/500.jsp</location>
    </error-page>
    <error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
    </error-page>

     

    三、比较异常处理方式的优缺点:

            Spring MVC集成异常处理3种方式都可以达到统一异常处理的目标。从3种方式的优缺点比较:

      若只需要简单的集成异常处理,推荐使用SimpleMappingExceptionResolver即可;

      若需要集成的异常处理能够更具个性化,提供给用户更详细的异常信息,推荐自定义实现HandlerExceptionResolver接口的方式;

      若不喜欢Spring配置文件或要实现“零配置”,且能接受对原有代码的适当入侵,则建议使用@ExceptionHandler注解方式。 

     

    在此补充个Ajax实现异常信息无跳转的处理方式:

       Java代码(Controller类)

    @RequestMapping(value = "/ajaxAlert", method = RequestMethod.POST)
    public void ajax(HttpServletResponse response, User user) throws Exception {
    
       if(user.getId()==null) {
          if(user.getUserName()==null || "".equals(user.getUserName())) {
             AjaxUtils.rendJson(response, false, "用户名为空创建失败");
          } else {
             AjaxUtils.rendJson(response, true, "创建用户成功");
          }
       } else {
          AjaxUtils.rendJson(response, true, "修改用户成功");
       }
    }
    
    @RequestMapping(value = "/controllerAjax", method = RequestMethod.POST)
    public void controllerAjax(HttpServletResponse response, Integer id) throws Exception {
       try {
          testService.daoTest();
          AjaxUtils.rendJson(response, true, "操作成功");
       } catch(Exception be) {
          AjaxUtils.rendJson(response, false, "Dao层异常");
       }
    }

    Java代码(AjaxUtils类)

     

    import java.io.IOException;
    import javax.servlet.http.HttpServletResponse;
    import net.sf.json.JSONObject;
    
    public class AjaxUtils {
    
       public static void rendText(HttpServletResponse response, String content)
             throws IOException {
          response.setCharacterEncoding("UTF-8");
          response.getWriter().write(content);
       }
    
       public static void rendJson(HttpServletResponse response, boolean success,
                            String message) throws IOException{
          JSONObject json = new JSONObject();
          json.put("isSuccess", success);
          json.put("message", message);
          rendText(response, json.toString());
       }
    }

    页面代码

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Exception</title>
    <script type="text/javascript" src="./jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
          $(function(){
          init();
          });
    
          function init(){
          $("#ajaxCreate").click(function(){
          doAjax({userName: "Candy", realName: "Carol"});
          })
          $("#ajaxUpdate").click(function(){
          doAjax({id: 1, userName: "Candy", realName: "Carol"});
          })
          $("#ajaxFail").click(function(){
          doAjax({realName: "Carol"});
          })
          }
          function doAjax(data) {
          $.post("./ajax.do",data,function(t){
          if(!t.isSuccess){
          alert("操作失败, 原因:" + t.message);
          }else{
          alert("操作成功, 描述:" + t.message);
          }
          },"json").error(function(){
          alert("未知错误");
          });
          }
    </script>
    </head>
    <body>
    <br />
    <a id="ajaxCreate" href="#">创建用户成功</a>
    <br />
    <a id="ajaxUpdate" href="#">修改用户成功</a>
    <br />
    <a id="ajaxFail" href="#">用户名为空创建失败</a>
    </body>
    </html>

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 07:51 , Processed in 0.076522 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表