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;
    }
}

 

posted @ 2019-08-14 16:55  送外卖的小菜鸟  阅读(292)  评论(0编辑  收藏  举报