【Spring】SpringMVC之异常处理

java中的异常分为两类,一种是运行时异常,一种是非运行时异常。在JavaSE中,运行时异常都是通过try{}catch{}捕获的,这种只能捕获显示的异常,通常项目上抛出的异常都是不可预见。那么我们能够有什么方法能够解决这种问题吗?当然有,SpringMVC中的异常处理机制就很好的做到了这一点。

SpringMVC中的异常处理一共有3种方式

  • (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
  • (2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
  • (3)使用@ExceptionHandler注解实现异常处理。

(1)使用Spring MVC提供的SimpleMappingExceptionResolver

直接将SimpleMappingExceptionResolver类配置到SpringMVC配置文件中

        <!--
            只是对全局的Controller有效果
                所有的被RequestMapping注解所添加的方法中的异常才有效果
         -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
            <!--
                    key: 异常的类全称
                    value: ModelAndView中的viewName
                    表示当key指定的异常产生时 , 则请求转发至 value指向的视图    -->
                    <prop key="java.lang.Exception">errorPage</prop>
                </props>
            </property>
        </bean>

从配置文件上可以看出,如果发生了异常就跳转到名为errorPage的视图上。

完整的applicationContext.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:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
        <!--
            开启注解扫描
         -->
         <context:component-scan base-package="cn"></context:component-scan>
         <!--
             开启mvc注解扫描
          -->
        <mvc:annotation-driven/>

        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
        <!--
            只是对全局的Controller有效果
                所有的被RequestMapping注解所添加的方法中的异常才有效果
         -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
            <!--
                    key: 异常的类全称
                    value: ModelAndView中的viewName
                    表示当key指定的异常产生时 , 则请求转发至 value指向的视图    -->
                    <prop key="java.lang.Exception">errorPage</prop>
                </props>
            </property>
        </bean>

</beans>

applicationContext.xml

使用这种方式的异常处理就是简单,但是问题显而易见,就是发生了异常自动就跳转到错误页面,那么这不利于后台对错误日志的收集。

(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

使用方式如下:

@Component
public class MyException implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(参数...) {
                 //操作...
    }
}

在自定义异常处理器中,我们就可以很方便对异常信息进行各种操作操作,下面是一个能收集错误信息的自定义异常处理器:

SpringMVC的配置文件中需要负责打开扫描:

<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
        <!--
            开启注解扫描
         -->
         <context:component-scan base-package="cn"></context:component-scan>
         <!--
             开启mvc注解扫描
          -->
        <mvc:annotation-driven/>

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

</beans>

applicationContext.xml

自定义的异常类:

package cn.shop.exception;

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import cn.shop.util.ExceptionUtil;

/**
 * 用来在全局 处理Controller异常
 */
@Component
public class SpringMVCException implements HandlerExceptionResolver {
    /**
     * 如果这个类的对象, 存在于容器中, 则当前的项目中, 所有的Controller 出现的异常, 都会到这个方法中
     *
     * 参数1.      请求对象
     * 参数2. 响应对象
     * 参数3. 出现异常时的 Method对象
     * 参数4. 出现异常时的异常信息
     *
     * 返回值, 会被ViewResolver解析
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object method,Exception e) {
        System.out.println("出现异常的方法:"+method.toString());
        //request.getQueryString():  获取get请求时的参数列表
        String paras = request.getQueryString();
        System.out.println("出现了异常, 出现异常时的请求参数:"+paras);
        System.out.println("--------------------------------------");
        System.out.println("----------      异常信息如下            ---------");
        System.out.println("--------------------------------------");
        e.printStackTrace();

        //存储到异常日志
        ExceptionUtil.toException(e);
        //跳转
        return new ModelAndView( "error");
    }

}

SpringMVCException.java

存储异常的工具类:

package cn.shop.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 用来收集异常日志
 *
 *    JavaEE  web阶段
 *
 *    当产生异常时, 应把异常收集起来 ,
 *
 *        存储到
 *            本地文件
 *            网络存储
 *            短信发送
 *            邮件
 */
public class ExceptionUtil {

    /**
     *
     * 存储:
     *     在存储的目录下 ,按照每天的日期创建单独文件夹
     *
     *                 每天的文件夹中, 异常日志存储的文件, 一个异常一个文件, 文件名称按照时-分-秒-毫秒的格式存储
     *
     *
     * @param e 要存储的异常信息
     * @param exceptionPath 要存储的位置: 是一个文件夹, 文件夹可以不存在
     * @throws Exception
     */
    public static void toException(Exception e,File exceptionPath) throws Exception{
        if(!exceptionPath.exists()){
            //创建文件夹
            exceptionPath.mkdirs();
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String day = sdf.format(date);
        //创建每天的异常文件夹
        File dayDir = new File(exceptionPath, day);
        if(!dayDir.exists())
            dayDir.mkdirs();
        //创建本次异常存储的文件
        SimpleDateFormat sdf2 = new SimpleDateFormat("HH-mm-ss-sss");

        String fileName = sdf2.format(date);
        File file = new File(dayDir, fileName+".txt");
        //创建一个字符打印流 , 指向创建的这个文件
        PrintWriter pw = new PrintWriter(new FileOutputStream(file));
        //将异常信息输出至这个文件
        e.printStackTrace(pw);
        pw.close();
    }
    /**
     *
     * @param e 要存储的异常信息 , 存储的位置 ,在F://log文件夹中
     */
    public static void toException(Exception e){
        try {
            toException(e,new File("F://log"));
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}

ExceptionUtil.java

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

package cn.xdl.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {

    @RequestMapping("/login.do")
    public String UserrLogin(String name,String password){

        //从数据库进行数据对比...

        //将结果值返回
        return "loginResult";
    }
    /**
     * 当前这个Controller类 ,被RequestMapping所注解的方法 如果出现了异常 ,则自动寻找当前类中是否存在被@ExceptionHandler注解的方法 , 如果存在, 则执行
     *
     * 这个方法的写法, 与使用直接方式的Controller基本一致
     *     它的参数列表中, 可以根据需求选择如下参数:
     *     HttpSession / HttpServletRequest /HttpServletResponse / Exception
     */
    @ExceptionHandler
    public String hahaha(Exception e,HttpServletRequest request){
        System.out.println("请求时的参数:"+request.getQueryString());
        System.out.println("---------------------------------");
        System.out.println("-----------  请看异常信息   -----------");
        System.out.println("---------------------------------");
        e.printStackTrace();

        return "error";

    }
}

上面这三种方式,各不影响,如果使用了多种方式的话,那么以离异常近的处理机制为准(就近原则)。

参考文章:

Java中自定义异常

时间: 2024-12-17 03:02:35

【Spring】SpringMVC之异常处理的相关文章

使用Spring MVC统一异常处理实战

1 描写叙述 在J2EE项目的开发中.无论是对底层的数据库操作过程.还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常须要处理.每一个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一.维护的工作量也非常大. 那么,能不能将全部类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护?答案是肯定的. 以下将介绍使用Spring MVC统一处理异常的解决和实现过程. 2 分析 Spring MVC处理异

Spring MVC 系统异常处理方式及性能对比

大部分公司所用的Spring框架版本是3.1版本以下,所以今天暂时总结3.1版本的Spring-MVC异常处理方式. 一.Spring MVC处理异常有3种方式: (1)使用Spring-MVC提供的SimpleMappingExceptionResolver: (2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器: (3)使用@ExceptionHandler注解实现异常处理: 二.分别介绍这三种异常处理的实现方式: (1)使用Simpl

Spring+SpringMVC+MyBatis深入学习及搭建(十六)——SpringMVC注解开发(高级篇)

转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7085268.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十五)——SpringMVC注解开发(基础篇) 本文主要内容: (1)SpringMVC校验 (2)数据回显 (3)异常处理器 (4)图片上传 (5)Json数据交互 (6)支持RESTful 1.SpringMVC校验 1.1校验理解 项目中,通常使用较多的是前端的校验,比如页面中js校验.对于安全要求较高的

Spring MVC全局异常处理与拦截器校检

在使用Spring MVC进行开发时,总是要对系统异常和用户的异常行为进行处理,以提供给用户友好的提示,也可以提高系统的安全性. 拦截系统响应错误 首先是拦截系统响应错误,这个可以在web.xml中配置,根据错误代码跳转到相应的提示页面.这里要注意一个问题,错误处理页面所用到的静态资源最好是直接写在页面中,或者同一个文件夹下,因为如果用户访问了一个系统不存在的路径,例如:**/ss/kk/ll/tt.jsp这样就会有404错误就会跳转到相应的处理页面,但是这个处理页面中的静态资源的路径就会变成*

【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(三)

Spring+SpringMVC MVC呢,现在似乎越来越流行使用SpringMVC框架,我自己用的感觉,是非常好,确实很舒服,配置一开始是麻烦了一点点,但是后续的开发真的是很清爽! SpringMVC配置文件 目录:resource/config/spring,文件名:spring-mvc.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.sp

SpringMVC 全局异常处理

在 JavaEE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大.SpringMvc 对于异常处理这块提供了支持,通过 SpringMvc 提供的全局异常处理机制,能够将所有类型的异常处从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护. 全局异常实现方式 Spring MVC

【每日3分钟技术干货 | 面试题+答案 | Spring&SpringMVC篇(一)】

1. 什么是spring? Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯. 2. 使用Spring框架的好处是什么? 轻量:Spring 是轻量的,基本的版本大约2MB. 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们. 面向切面的编程(AOP):Sp

基于Spring+SpringMVC+Mybatis的Web系统搭建

主要的后端架构:Spring+SpringMVC+Mybatis+Shiro+Maven  IDE:IntelliJ IDEA 15.0.2 jdk:1.8.0_66 系统完整源码 https://github.com/Wellat/Factor 系统目录结构 跑起来效果 搭建步骤 1.用Idea创建maven项目 2.配置pom.xml文件,添加依赖 1 <?xml version="1.0" encoding="UTF-8"?> 2 <proj

SSM框架 (Spring+SpringMVC+MyBatis)

SSM框架--详细整合教程(Spring+SpringMVC+MyBatis) springspringmvcmybatis整合教程ssm整合 1.基本概念  1.1.Spring          Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来.它是为了解决企业应用开发的复杂性而创建的.Spri

spring(一)--spring/springmvc/spring+hibernate(mybatis)配置文件

这篇文章用来总结一下spring,springmvc,spring+mybatis,spring+hibernate的配置文件 1.web.xml 要使用spring,必须在web.xml中定义分发器等信息,基本的配置信息如下: <?xml version="1.0" encoding= "UTF-8"?> <web-app version= "3.0" xmlns="http://java.sun.com/xml/n