Spring MVC 异常处理实例讲解

时间:2018-11-07
本文章向大家介绍Spring MVC 异常处理实例讲解,需要的朋友可以参考一下

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 请求总控器 -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
View Code

配置dispatcher-servlet.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="edu.nf.ch09"/>

    <mvc:annotation-driven/>

    <mvc:default-servlet-handler/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
View Code

Controller (UserController)

package edu.nf.ch09.controller;

import edu.nf.ch09.controller.vo.ResponseVO;
import edu.nf.ch09.entity.Users;
import edu.nf.ch09.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

/**
 * @author wangl
 * @date 2018/11/5
 */
@Controller
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 局部异常处理方法
     *
     * @ExceptionHandler标注的方法用于专门处理请求方法抛出的异常
     * value属性指定异常的Class对象(是一个数组,可以指定多个class),
     * 表示捕获什么样的异常对象,最后在标注的方法中传入一个异常参数,就可以得到相应的异常对象
     * 注意:@ExceptionHandler标注的方法只在当前的Controller类中有效,
     * 在其他类中必须重新编写相关的Handler异常处理方法,
     * 如果希望让所有的Controller都共享一个Handler异常处理,那么可以配置为全局异常处理
     *
     * @return
     */
    /*@ExceptionHandler(UserException.class)
    public ResponseVO handlerException(RuntimeException e){
        ResponseVO vo = new ResponseVO();
        vo.setCode(401);
        vo.setMessage(e.getMessage());
        return vo;
    }*/

    /**
     * 用户登陆
     * @param user
     * @param session
     * @return
     */
    @PostMapping("/userLogin")
    @ResponseBody
    public ResponseVO login(Users user, HttpSession session){
        ResponseVO vo = new ResponseVO();
        //如果login方法引发了异常,则会执行上面的handlerLoginException异常处理方法
        user = userService.login(user);
        session.setAttribute("user", user);
        vo.setValue("index.html");
        return vo;
    }

    @PostMapping("/addUser")
    @ResponseBody
    public ResponseVO addUser(Users user){
        userService.addUser(user);
        return new ResponseVO();
    }
}

ExceptionAdvice(全局的异常处理类)

package edu.nf.ch09.controller.advice;

import edu.nf.ch09.controller.vo.ResponseVO;
import edu.nf.ch09.service.exception.DataAccessException;
import edu.nf.ch09.service.exception.UserException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author wangl
 * @date 2018/11/5
 * 定义一个全局的异常处理类(类似一个切面)
 * 这个类中定义的所有方法都是异常处理方法,
 * 也可以理解为是全局的异常通知
 * value属性指定对哪些控制器进行切入拦截
 */
@ControllerAdvice("edu.nf.ch09.controller")
public class ExceptionAdvice {

    /**
     * 全局异常处理方法
     * 用于处理用户登陆异常
     * @param e
     * @return
     */
    @ExceptionHandler(UserException.class)
    @ResponseBody
    public ResponseVO handlerLoginException(RuntimeException e){
        ResponseVO vo = new ResponseVO();
        vo.setCode(401);
        vo.setMessage(e.getMessage());
        return vo;
    }

    /**
     * 全局异常处理方法
     * 用于处理crud操作
     * @param e
     * @return
     */
    @ExceptionHandler(DataAccessException.class)
    @ResponseBody
    public ResponseVO handlerDataAccessException(RuntimeException e){
        ResponseVO vo = new ResponseVO();
        vo.setCode(500);
        vo.setMessage(e.getMessage());
        return vo;
    }
}

持久层引发的异常

package edu.nf.ch09.dao.impl;

import edu.nf.ch09.dao.UserDao;
import edu.nf.ch09.entity.Users;
import edu.nf.ch09.service.exception.DataAccessException;
import org.springframework.stereotype.Repository;

/**
 * @author wangl
 * @date 2018/11/5
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Override
    public Users getUserByName(String userName) {
        Users user = null;
        if("user1".equals(userName)){
            user = new Users();
            user.setUserName("user1");
            user.setPassword("123456");
        }
        return user;
    }

    @Override
    public void saveUser(Users user) {
        System.out.println("insert into user_info values ...");
        throw new DataAccessException("添加失败");
    }
}
View Code

业务逻辑层引发的异常

package edu.nf.ch09.service.impl;

import edu.nf.ch09.dao.UserDao;
import edu.nf.ch09.entity.Users;
import edu.nf.ch09.service.UserService;
import edu.nf.ch09.service.exception.UserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author wangl
 * @date 2018/11/5
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public Users login(Users user) {
        Users newUser = userDao.getUserByName(user.getUserName());
        if(newUser == null){
            throw new UserException("用户不存在");
        }
        if(!user.getPassword().equals(newUser.getPassword())){
            throw new UserException("密码错误");
        }
        return newUser;
    }

    @Override
    public void addUser(Users user) {
        userDao.saveUser(user);
    }
}
View Code