• spring 异常处理的方式?


    一、使用SimpleMappingExceptionResolver解析器

    1.1在mvc中进行 配置。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    
        <!--spring mvc的配置文件-->
        <!--开启mvc的注解-->
        <mvc:annotation-driven conversion-service="conversionService" >
            <!--配置转换器   转换日期的格式。-->
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                            <property name="dateFormat">
                                <bean class="java.text.SimpleDateFormat">
                                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
                                </bean>
                            </property>
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
        <!--配置日期转换器-->
        <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <bean class="com.aaa.controller.DateConverter"/>
                </set>
            </property>
        </bean>
    
    
    
        <mvc:default-servlet-handler/>
        <!--扫描器:扫描控制器的注解-->
        <context:component-scan base-package="com.aaa.controller"/>
    
         <!--4.静态资源注解-->
        <mvc:default-servlet-handler/>
        <!--<mvc:resource mapping="/static/**" location="/static/"/>-->
    
        <!--3.视图解析器:进行视图解析
           prefix+ 视图名字+suffix
        -->
        <!--5.文件上传的解析器     可以设置相关的属性。-->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="utf-8"/>
            <!--文件上传的大小:单位:字节-->
            <property name="maxUploadSize" value="#{10*1024*1024}"/>
        </bean>
    
    
    
    
    
        <!-- 异常处理  1.  配置解析器 -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <!--1.1默认的错误视图  发生异常时, 跳转到的页面-->
            <property name="defaultErrorView"  value="error"/>
            <!--1.2 异常的属性   捕获到的错误信息。-->
            <property name="exceptionAttribute" value="ex"/>
    
            <!--1.3exceptionMappings   -->
            <property name="exceptionMappings">
                <props>
                    <prop key="异常类型1">
                        error1
                    </prop>
                    <prop key="异常类型2">
                        error2
                    </prop>
                </props>
            </property>
        </bean>
    
    
    
        <!--6. 配置一个拦截器   -->
        <mvc:interceptors>
            <!--<mvc:interceptor>-->
                <!--&lt;!&ndash; 拦截的路径  &ndash;&gt;-->
                <!--<mvc:mapping path="/**"/>-->
                <!--&lt;!&ndash; 配置拦截器的bean &ndash;&gt;-->
                <!--&lt;!&ndash;  放行路径 &ndash;&gt;-->
                <!--<mvc:exclude-mapping path="/user/login"/>-->
                <!--<bean class="com.aaa.interceptors.MyIntercept"/>-->
            <!--</mvc:interceptor>-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.aaa.interceptors.Demo02"/>
        </mvc:interceptor>
    
        </mvc:interceptors>
    
    
    
        
    
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/"/>   <!--视图前缀-->
            <property name="suffix" value=".jsp"/>  <!--视图后缀-->
        </bean>
    
        <aop:config ></aop:config>
    
    
    </beans>

    1.2、建立一个jsp页面,来接收错误的信息。注意路径 ,我的放在 webapp 下。

    <%--
      Created by IntelliJ IDEA.
      User: Administrator
      Date: 2019/8/14
      Time: 14:57
      To change this template use File | Settings | File Templates.
    --%>                                                                        
                                                                        <%--isErrorPage  是否设置错误的页面 --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java"  isErrorPage="true" %> 
    <html>
    <head>
        <title>错误页面</title>
    </head>
    <body>
        <h1>本页面,接收异常数据:${ex}</h1>
    
    </body>
    </html>

    1.3  后台控制层

    package com.aaa.controller;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.subject.Subject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import javax.servlet.http.HttpSession;
    //        if (!currentUser.isAuthenticated()) {
    //            //用户名密码令牌
    //            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    //            //记住我
    //            token.setRememberMe(true);
    //            try {
    //            //调用Suject.login方法 ---》安全管理器--->认证器 ,授权器
    //            currentUser.login(token);
    //            } catch (UnknownAccountException uae) {//账号不存在
    //                log.info("There is no user with username of " + token.getPrincipal());
    //            } catch (IncorrectCredentialsException ice) {//密码错误
    //                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
    //                throw new IncorrectCredentialsException("密码错误");
    //            } catch (LockedAccountException lae) {//账号锁死
    //                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
    //                        "Please contact your administrator to unlock it.");
    //            }
    //            // ... catch more exceptions here (maybe custom ones specific to your application?
    //            catch (AuthenticationException ae) {
    //                //unexpected condition?  error?
    //            }
    //       }
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        //获取日志对象
       private static final transient Logger log= LoggerFactory.getLogger(UserController.class);
    
        @RequestMapping("/login")
        public  String login(String username,String password, HttpSession session){
    
            //获得封装的对象
            Subject currentUser= SecurityUtils.getSubject();
    
            //获得的令牌中的信息    
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    
            //记住我
            token.setRememberMe(true);
            
            currentUser.login(token);
    
            //密码正确 就让它 跳转到指定的页面
            return  "view/ok";
        }
    
    }

    二、使用@ExceptionHandler  注解,     只能控制当前 控制器的异常。  可以自定义异常的处理方法。

     

    2.1 控制层 BaseController中自定义  异常处理方式

    package com.aaa.controller;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authz.AuthorizationException;
    import org.springframework.beans.propertyeditors.CustomDateEditor;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.InitBinder;
    
    import javax.sound.midi.Soundbank;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    /*
    *1.实体类中添加注解。
    *
    * 2.创建BaseController
    *
    * 3.定义全局的类型转换器
    * */
    public class BaseController {
    
        @InitBinder
        public void init(WebDataBinder binder){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            //严格转换 不会自动进行日期的增减处理
            simpleDateFormat.setLenient(false);
    
            //注册一个类型转换器
            binder.registerCustomEditor(Date.class,new CustomDateEditor(simpleDateFormat,true));
        }
    
    
        //自定的方法。   只能控制当前 控制器的异常
        @ExceptionHandler(RuntimeException.class)
        public String handler(RuntimeException ex, Model model){
    
            //将异常放在model里面    捕获信息
            model.addAttribute("ex",ex);
    
            //模拟根据异常不同的情况   返回不同的视图
            if (ex instanceof AuthenticationException){
                System.out.println("处理方案一");
                model.addAttribute("ex",ex);
                return "error";
            }else if (ex instanceof AuthorizationException){
                System.out.println("处理方案二");
                model.addAttribute("ex",ex);
                return  "error";
            }
    
            //根据不同的异常情况可以,返回不同的界面。
            return "error";
        }
    }

    2.2  UserController  

    package com.aaa.controller;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.subject.Subject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import javax.servlet.http.HttpSession;
    //        if (!currentUser.isAuthenticated()) {
    //            //用户名密码令牌
    //            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    //            //记住我
    //            token.setRememberMe(true);
    //            try {
    //            //调用Suject.login方法 ---》安全管理器--->认证器 ,授权器
    //            currentUser.login(token);
    //            } catch (UnknownAccountException uae) {//账号不存在
    //                log.info("There is no user with username of " + token.getPrincipal());
    //            } catch (IncorrectCredentialsException ice) {//密码错误
    //                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
    //                throw new IncorrectCredentialsException("密码错误");
    //            } catch (LockedAccountException lae) {//账号锁死
    //                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
    //                        "Please contact your administrator to unlock it.");
    //            }
    //            // ... catch more exceptions here (maybe custom ones specific to your application?
    //            catch (AuthenticationException ae) {
    //                //unexpected condition?  error?
    //            }
    //       }
    @Controller
    @RequestMapping("/user")
    public class UserController extends BaseController{
    
        //获取日志对象
       private static final transient Logger log= LoggerFactory.getLogger(UserController.class);
    
        @RequestMapping("/login")
        public  String login(String username,String password, HttpSession session){
    
            //获得封装的对象
            Subject currentUser= SecurityUtils.getSubject();
    
            //获得的令牌中的信息
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    
            //记住我
            token.setRememberMe(true);
    
            currentUser.login(token);
    
            //密码正确 就让它 跳转到指定的页面
            return  "view/ok";
        }
    
    }

    三、 使用   @ControllerAdvice  +    @ExceptionHandler  注解

    3.1 同步方式。       就不需要再继承,直接创建一个exception  controller  。

    package com.aaa.controller;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authz.AuthorizationException;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    /*
    *   建立异常的  处理器。
    *
    *   通知 advice    把这个controller 当做一个切面
    *                  把这个方法当做切面加到 代理到个个 执行的过程中
    * */
    @ControllerAdvice    //切面 aop的思想
    public class ExceptionController {
    
    
        @ExceptionHandler(RuntimeException.class)
        public String handler1(RuntimeException ex, Model model){
            if (ex instanceof AuthenticationException){
                model.addAttribute("ex",ex);
                return "error";
            }else if (ex instanceof AuthorizationException){
                model.addAttribute("ex",ex);
                return "error";
            }
            return "error";
        }
    
    }

    3.2 异步方式。  返回json数据

    1.创建实体类

    2.下载  lombok  jar包 ,自动生成一些set get 方法。

    package com.aaa.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    
    /*
    * 实体类中定义 状态码等属性
    *
    * lombok  自动生成实体类中的属性  加上注解即可
    *
    * */
    @Data
    @AllArgsConstructor     //代餐的构造函数
    @NoArgsConstructor      //空参
    @ToString
    public class Result {
        private  Integer satusCode;
        private  String message;
    }

    3.控制层

    package com.aaa.controller;
    
    import com.aaa.entity.Result;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authz.AuthorizationException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /*
    * 一、  建立异常的  处理器。
    *       通知 advice    把这个controller 当做一个切面
    *                  把这个方法当做切面加到 代理到个个 执行的过程中
    *
    *
    * 二、异步方式
    * 1.自定义实体类   下载lombok  使用注解。
    * 2.控制器中返回 json数据格式。
    * */
    @ControllerAdvice    //切面 aop的思想
    public class ExceptionController {
    
    //    @ExceptionHandler(RuntimeException.class)
    //    public String handler1(RuntimeException ex, Model model){
    //        if (ex instanceof AuthenticationException){
    //            model.addAttribute("ex",ex);
    //            return "error";
    //        }else if (ex instanceof AuthorizationException){
    //            model.addAttribute("ex",ex);
    //            return "error";
    //        }
    //        return "error";
    //    }
    
        @ExceptionHandler(RuntimeException.class)
        @ResponseBody
        //返回定义的实体类 result  就不能用视图  model 就不要了。
        //对象当做json数据返回。
        public Result handler1(RuntimeException ex){
    
            Result result = new Result();
    
            if (ex instanceof AuthenticationException){
                //返回一个状态码  自定义
                result.setSatusCode(501);
                result.setMessage("密码认证异常"+ex.getMessage());
            }else  if (ex instanceof AuthorizationException){
                result.setSatusCode(502);
                result.setMessage("授权异常"+ex.getMessage());
            }
    
            return result;
    
        }
    
    }

    4. 效果

     四,实现异常处理的接口  HandlerExceptionResolver

    package com.aaa.controller;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    //了解一下。
    public class ExceptionDemo implements HandlerExceptionResolver {
        @Override   //返回一个model 视图  还需要 配置xml文件
        public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
            return null;
        }
    }
  • 相关阅读:
    Consul负载均衡策略记录
    ASP NET CORE开发优化相关专用随笔
    .NET CORE 3.1配置文件读取方式
    CentOS 8 安装.NET CORE 3.1 发布以及运行
    CORE EF生成ORACLE数据库模型报错问题记录
    【转载】一名程序员十年技术之路的思考与感悟
    iview-admin部署linux nginx报500错误的问题记录
    [转]浅谈账号系统设计
    C#使用phantomjs,爬取AJAX加载完成之后的页面
    nginx触屏版跟PC的代理设置
  • 原文地址:https://www.cnblogs.com/ZXF6/p/11353109.html
Copyright © 2020-2023  润新知