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

在使用Spring MVC进行开发时,总是要对系统异常和用户的异常行为进行处理,以提供给用户友好的提示,也可以提高系统的安全性。

拦截系统响应错误

首先是拦截系统响应错误,这个可以在web.xml中配置,根据错误代码跳转到相应的提示页面。这里要注意一个问题,错误处理页面所用到的静态资源最好是直接写在页面中,或者同一个文件夹下,因为如果用户访问了一个系统不存在的路径,例如:**/ss/kk/ll/tt.jsp这样就会有404错误就会跳转到相应的处理页面,但是这个处理页面中的静态资源的路径就会变成**/ss/kk/ll/*.js这种,就会造成静态资源不可以使用。

<!-- 404错误拦截 --> <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> <!-- 500错误拦截 --> <error-page> <error-code>500</error-code> <location>/error500.jsp</location> </error-page>

使用拦截器进行权限校检

在配置web.xml时,可以配置DispatcherServlet的处理解析路径。

<!-- 配置前端控制器 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- ContextconfigLocation配置springmvc加载的配置文件
          适配器、处理映射器等 --> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/classes/spring/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <!-- 1、.action访问以.action结尾的  由DispatcherServlet进行解析
           2、/,所有访问都由DispatcherServlet进行解析 --> <url-pattern>/</url-pattern> </servlet-mapping>

这里需要特别注意的是如果只拦截像以.action结尾URL,可以通过Spring MVC的拦截器来拦截并对不同权限的用户做出不同的响应,但是对静态页面.html,.jsp这种权限的校检就没有太好的办法了。可以在每个JSP页面中都检测一次session,这样一来在写JSP页面的时候就会很麻烦,还有可能用户的权限不够某些值为null,JSP的编译都要报错。但这种做法有一个优点就是不用操心静态资源的访问。还有一种就是想上面的配置一样拦截所有的URL,这样的话所有的RUL都会交给DispatcherServlet来分发,上面提到的JSP、html页面的权限校检的问题就可以解决了,完全可以通过拦截器来处理,但是也带来了新的问题。如果不对js,css和图片这种静态资源进行映射的话,DispatcherServlet就找不到,造成所有的静态资源都访问不了。这个问题有两种解决办法:

1.在web.xml中配置servlet来映射静态资源。

<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/js/*</url-pattern> <url-pattern>/css/*</url-pattern> <url-pattern>/images/*</url-pattern> </servlet-mapping>

这个配置最好放在DispatcherServlet之前,在DispatcherServlet处理之前映射。这里使用的是Tomcat提供的default Servlet,其他应用服务器可能有所不同。

还需要在springmvc.xml配置文件中配置默认的静态资源文件处理器

<mvc:default-servlet-handler />

2.在springmvc.xml中配置静态资源文件映射

springmvc.xml是在配置DispatcherServlet时配置的映射文件。也就是默认的[name]-servlet.xml文件。

<mvc:resources mapping="/images/**" location="/images/" /> <mvc:resources mapping="/css/**" location="/css/" /> <mvc:resources mapping="/js/**" location="/js/" /> <mvc:resources mapping="/imgdata/**" location="/imgdata/" />

这样一来DispatcherServlet在分发请求时就可以找到对应的静态资源文件了。这里还需要注意一个问题,在配置拦截器的时候务必要把这些文件过滤掉,不然还是无法使用。

通过以上的配置,静态资源的访问、系统异常的响应都没有问题了。可以使用拦截器进行权限的校检与管理了。

在springmvc.xml文件中配置拦截器:

拦截器直接定义就可以拦截所有的请求,但是这样还会造成静态资源被拦截。除非在实现拦截器的时候手动排除。

<!-- 定义拦截器 --> <mvc:interceptors> <!-- 直接定义拦截所有请求 --> <bean class="com.wxisme.ssm.interceptor.IdentityInterceptor"></bean> </mvc:interceptors>

也可以自定义拦截路径

<!-- 定义拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*.action" /> <mvc:mapping path="/*.jsp" /> <mvc:mapping path="/*.html" /> <mvc:mapping path="/*.htm" /> <mvc:exclude-mapping path="/login.jsp"/> <mvc:exclude-mapping path="/register.jsp"/> <mvc:exclude-mapping path="/about.jsp"/> <bean class="com.course.interceptor.IdentityInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>

这样就可以过滤掉静态资源。

拦截器的编写:

自定义拦截器要实现HandlerInterceptor接口。HandlerInterceptor接口定义了三个方法:preHandle、postHandle、afterCompletion。

preHandle在请求被处理器处理之前调用,postHandle在请求被处理之后,视图生成之间调用,afterCompletion在请求完全处理后调用。如果有多个拦截器,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法。

看一个简单的用户校检的例子:

package com.course.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** *身份认证拦截器
 *@author 王旭
 *@time 2015-9-6 上午9:51:27 */ public class IdentityInterceptor implements HandlerInterceptor { /** * 进行身份认证,在handler执行之前执行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object obj) throws Exception {

        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username"); //判断是否为公开地址 String url = request.getRequestURL().toString(); if(url.contains("login.")) { return true;//是公开地址则放行  } //判断用户是否登录 else if(username != null) { return true;
        } else { //不是公开地址则重定向到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); return false;
        }

    }

    @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {

    }

    @Override public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {

    }

}

注意如果前面配置的时候没有过滤掉静态资源可以在代码里手动过滤。

定义全局异常处理器

在srpingmvc.xml中配置全局异常处理器

<!-- 只有一个全局异常处理器起作用 --> <bean id="exceptionResolver" class="com.wxisme.ssm.exception.OverallExceptionResolver"></bean>

编写全局异常处理器:

先编写一个自定义异常CustomException

package com.course.exception; /** *自定义异常类型
 *@author 王旭
 *@time 2015-10-4 下午3:51:10 */ public class CustomException extends Exception { private String message; public CustomException(){} public CustomException(String message) { super(message); this.message = message;
    } public String getMessage() { return message;
    } public void setMessage(String message) { this.message = message;
    }

}

编写全局异常处理器,要实现HandlerExceptionResolver接口,并重写resolveException方法。

package com.course.exception; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; /** *系统全局异常处理器
 *@author 王旭
 *@time 2015-10-4 下午3:38:41 */ @Controller public class OverallExceptionResolver implements HandlerExceptionResolver { /** * 进行全局异常的过滤和处理 */ @Override public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) { //handler为当前处理器适配器执行的对象 String message = null; //判断是否为系统自定义异常。 if(ex instanceof CustomException) {
            message = ((CustomException) ex).getMessage();
        } else {
            message = "系统出错啦,稍后再试试!";
        }

        ModelAndView modelAndView = new ModelAndView();
        //跳转到相应的处理页面
        modelAndView.addObject("errorMsg", message);
        modelAndView.setViewName("error"); return modelAndView;
    }

}

这样在系统抛异常的时候就会自动过滤并给用户进行相关友好的提示。

用到了log4j一块说了吧,添加jar包,再加一个配置文件log4j.properties就OK了。

配置文件如下:

# Global logging configuration
#在开发环境中设置成DEBUG,在生产环境中设置成info或者error
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

这样就可以在控制台查看日志信息了。

以上只是关于Spring MVC权限管理和异常处理的简单示例,如果要深入使用或者要理解其原理还是参考官方文档以及源码。

时间: 2024-12-19 15:38:29

Spring MVC全局异常处理与拦截器校检的相关文章

Spring MVC实现的登录拦截器

之前接触过struts拦截器,但是没有使用过Spring MVC拦截器,今天花了一天时间好好研究了一下. 定义拦截器 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的.在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Sp

Spring MVC中使用Interceptor拦截器

SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间. 一.定义Interceptor实现类 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的.在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Intercep

spring mvc 配置 mybatis sql拦截器

直接上代码: mybatis配置中 添加  <property name="plugins"> 如下: <bean id="sqlSessionFactory" class="com.hotent.core.mybatis.SqlSessionFactoryFactoryBean"> <property name="configLocation" value="classpath:/co

Spring MVC全局异常处理

继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception

Spring MVC全局异常后返回JSON异常数据

Spring MVC全局异常后返回JSON异常数据 问题: 当前项目是作为手机APP后台支持,使用spring mvc + mybaits + shiro进行开发.后台服务与手机端交互是发送JSON数据.如果后台发生异常,会直接返回异常页面,显示异常内容,如果是404请求不到资源或者500这类服务器的问题,可能会导致返回404和500异常页面,手机端的处理就非常麻烦,为了解决这个问题,就需要做全局的异常处理. 解决方案: (1)自定义或者使用spring自带的各种异常处理器 例如spring基于

白话Spring(中级篇)---拦截器(下)

[一知半解,就是给自己挖坑] 上文我们介绍了Spring中过滤器的基本用法,本文我们来介绍多个拦截器的执行情况,另外一种拦截器的实现方式,以及拦截器与java过滤器的区别.特别的,在本文中,我们将不在演示具体的拦截的实例,请读者们参照上文的实现以及配置方式自行实现. --------------------------------------------------------------------------------------------------------------------

SpringMVC基础(二)_文件上传、异常处理、拦截器

实现文件上传 实现文件上传,需要借助以下两个第三方 jar 包对上传的二进制文件进行解析: commons-fileupload commons-io form表单的 enctype 取值必须为:multipart/form-data(默认为:application/x-www-form-urlencoded):enctype为表单请求正文的类型:method 属性必须取值为 post 方式:提供一个文件选择域: <input type="file"/> : <for

使用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