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

时间:2022-09-20 19:10:36

在使用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了。

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

配置文件如下:

# 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权限管理和异常处理的简单示例,如果要深入使用或者要理解其原理还是参考官方文档以及源码。

转载请指明来源。

如有错误,敬请指正。

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

  1. Spring MVC 全局异常处理&amp&semi;文件上传

    Spring MVC 全局异常处理 使用SimpleMappingExceptionResolver实现异常处理 在welcome-servlet.xml进行如下配置: <bean class= ...

  2. Spring MVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  3. Spring MVC基础知识整理➣拦截器和自定义注解

    概述 Spring MVC中通过注解来对方法或者类进行动态的说明或者标注,类似于配置标识文件的属性信息.当标注的类或者方式被使用时候,通过提取注解信息来达到对类的动态处理.在 MVC中,我们常用的注解 ...

  4. spring mvc 用cookie和拦截器实现自动登录(&sol;免登录)

    Cookie/Session机制详解:http://blog.csdn.net/fangaoxin/article/details/6952954 SpringMVC记住密码功能:http://blo ...

  5. Spring MVC全局异常处理

    继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerE ...

  6. spring mvc 全局异常处理

    package com.tool; public class MyException extends Exception{ public String Msg; public String ErrCo ...

  7. Spring MVC温故而知新 – 参数绑定、转发与重定向、异常处理、拦截器

    请求参数绑定 当用户发送请求时,根据Spring MVC的请求处理流程,前端控制器会请求处理器映射器返回一个处理器,然后请求处理器适配器之心相应的处理器,此时处理器映射器会调用Spring Mvc 提 ...

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

    问题: 当前项目是作为手机APP后台支持,使用spring mvc + mybaits + shiro进行开发.后台服务与手机端交互是发送JSON数据.如果后台发生异常,会直接返回异常页面,显示异常内 ...

  9. SSM框架之SpringMVC(6)异常处理及拦截器

    SpringMVC(6)异常处理及拦截器 1.异常处理 1.1.异常处理的思路 ​ 系统中异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息,后者主 ...

随机推荐

  1. 【转】单例模式(singletion)

    单例模式(Singleton) 原地址:http://www.cnblogs.com/BoyXiao/archive/2010/05/07/1729376.html 首先来明确一个问题,那就是在某些情 ...

  2. &lbrack;Nhibernate&rsqb;SchemaExport工具的使用(一)——通过映射文件修改数据表

    目录 写在前面 文档与系列文章 SchemaExport工具 SchemaUpdate工具 一个例子 总结 写在前面 上篇文章介绍了使用代码生成器的nhibernate模版来生成持久化类,映射文件等内 ...

  3. fmt-重新格式化段落

    fmt供用户切分段落,使文本行数不要超出我们看到的屏幕范围. 如果电脑没有fmt(不是posix),需要安装coreutils包. 常用选项有两个: -s 切割较长的行,但不会将短行结合成较长的行. ...

  4. Unity3D开发赛车Demo遇到的问题

    遇到问题 在3D Max中导出的跑车在Unity中轴向不对,不知有没有朋友遇到过呢? 切换坐标系统 在Unity3D中按X键,切换坐标系统 车轮方向变了 运行游戏之后,赛车的车轮方向变歪了 车依然能跑 ...

  5. 中国IT 未来何在

      许久之前,已对国内IT业的一些问题颇有看法,而今又恰逢360与AV-C的纠缠,实在忍不住要发发牢骚.IT在中国,发展不过二十来年,却以迅雷之速横扫各个领域,令人感叹,此成就是不可否认的:然而,发展 ...

  6. 表视图控制器&lpar;TableViewController&rpar;&lpar;一&rpar;

    1 创建一个UITableViewController并展示简单数据 1.1 问题 有很多移动客户端的应用都是采用表的形式来展示数据,因为表视图能使数据看起来更规整.更有调理,比如微信界面就是使用的表 ...

  7. plsql在64位机器下读取tnsname&period;ora 及oracle&lowbar;home异常的解决办法

    问题是: 我在自己电脑(win7  64bit)上安装了oracle的64位数据库   通过sqlplus能正常连接 主要是安装pl/sql时   我是这样安装的1.在网上下载了个instantcli ...

  8. Hibernate3提供的属性的延迟加载功能

    Hibernate3增强了对实体属性的延迟加载功能,要实现这个功能,分两个步骤 1.在hbm配置文件上对某个property设置lazy=true   <property name=" ...

  9. 团队作业4----第一次项目冲刺(Alpha版本)4&period;28

    a.提供当天站立式会议照片 会议内容 今天我们主要针对统计结果的表现形式进行了一些讨论,我们考虑是直接显示统计数据或者是用一些直观的图形来体现,最后经过讨论我们大部分人认为选择数据与图形更加形象直观. ...

  10. emacs 文本替换

    文本替换方法: M-% (query-replace) 输入 响应 SPC 或者 y 替换当前匹配并前进到下一个匹配处 DEL 或者 n 忽略此次匹配并前进到下一个匹配处 . 替换当前匹配并退出 , ...