博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springMVC Spring MVC 异常处理
阅读量:4036 次
发布时间:2019-05-24

本文共 6778 字,大约阅读时间需要 22 分钟。

 Spring MVC处理异常有3种方式:

 (1)使用@ExceptionHandler注解实现异常处理;

(2)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver; 

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

一、使用@ExceptionHandler进行处理

1.创建异常基类,使用@ExceptionHandler声明异常处理

    BusinessException和SystemException为自定义异常类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package 
com.twosnail.exception;
 
import 
javax.servlet.http.HttpServletRequest;
import 
org.springframework.stereotype.Controller;
import 
org.springframework.web.bind.annotation.ExceptionHandler;
 
@Controller
public 
class 
BasicExController {
    
/**
     
* 基于@ExceptionHandler异常处理基类
     
* @return
     
*/
    
@ExceptionHandler
    
public 
String exception( HttpServletRequest request , Exception ex ) {
         
    
// 根据不同错误转向不同页面  
        
if
( ex 
instanceof 
BusinessException ) {
            
return 
"business-error"
;  
        
}
else 
if
( ex 
instanceof 
SystemException ) { 
            
return 
"system-error"
;
        
else 
{
            
return 
"error"
;  
        
}
    
}
}

2、使所有需要异常处理的Controller都继承该类,如下所示:

1
public 
class 
DemoController 
extends 
BasicExController {}

    然而,Dao层、Service层、Controller层抛出的异常(BusinessException、SystemException和其它异常)都能准确显示定义的异常处理页面,达到了统一异常处理的目标。

    总结:使用@ExceptionHandler注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的Controller类继承于BasicExController即可)、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性(需要修改已有代码,使继承于BasicExController),在异常处理时不能获取除异常以外的数据。

二、SimpleMappingExceptionResolver简单异常处理器

    SimpleMappingExceptionResolver有两种配置方式,可以按自己需求而定,配置代码如下:

1、第一种,在Spring的配置文件中,增加以下内容:

    在这里,可以设置跳转相应页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<
bean 
class
=
"org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
>
    
<!-- 定义默认的异常处理页面,当该异常类型的注册时使用 -->
    
<
property 
name
=
"defaultErrorView" 
value
=
"error"
></
property
>
    
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
    
<
property 
name
=
"exceptionAttribute" 
value
=
"ex"
></
property
>
    
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
    
<
property 
name
=
"exceptionMappings"
>
        
<
props
>
            
<
prop 
key
=
"com.twosnail.exception.BusinessException"
>business-error</
prop
>
            
<
prop 
key
=
"com.twosnail.exception.SystemException"
>system-error</
prop
>
        
</
props
>
    
</
property
>
 
    
<!-- 相关状态码对应的错误页面 -->
    
<
property 
name
=
"statusCodes"
>
        
<
props
>
            
<
prop 
key
=
"errors/500"
>500</
prop
>
            
<
prop 
key
=
"errors/404"
>404</
prop
>
        
</
props
>
    
</
property
>
    
<!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
    
<
property 
name
=
"warnLogCategory" 
value
=
"WARN" 
/>
    
<!-- 默认HTTP状态码 -->
    
<
property 
name
=
"defaultStatusCode" 
value
=
"500" 
/>
</
bean
>

2、第二种,通过自定义java类,继承SimpleMappingExceptionResolver

    然后在Spring的配置。代码如下:

1
2
3
4
5
6
7
8
9
<
bean 
id
=
"exceptionResolver" 
class
=
"com.twosnail.exception.MyselfSimpleMappingExceptionResolver"
>
    
<
property 
name
=
"exceptionMappings"
>
        
<
props
>
            
<
prop 
key
=
"com.twosnail.exception.SystemException"
>error/500</
prop
>
            
<
prop 
key
=
"com.twosnail.exception.BusinessException"
>error/errorpage</
prop
>
            
<
prop 
key
=
"java.lang.exception"
>error/500</
prop
>
        
</
props
>
    
</
property
>
</
bean
>

    java类代码如下,在这里可以处理相应逻辑,如下,分别处理了jsp页面和json数据:

1
2
3
4
5
6
7
8
9
10
11
1
3
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package 
com.twosnail.exception;
 
import 
java.io.IOException;
import 
java.io.PrintWriter;
import 
javax.servlet.http.HttpServletRequest;
import 
javax.servlet.http.HttpServletResponse;
import 
org.springframework.web.servlet.ModelAndView;
import 
org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
 
public 
class 
MyselfSimpleMappingExceptionResolver 
extends 
SimpleMappingExceptionResolver {
 
    
@Override
    
protected 
ModelAndView doResolveException(HttpServletRequest request,
            
HttpServletResponse response, Object handler, Exception ex) {
        
// Expose ModelAndView for chosen error view.
        
String viewName = determineViewName(ex, request);
        
if 
(viewName != 
null
) {
// JSP格式返回
            
if 
(!(request.getHeader(
"accept"
).indexOf(
"application/json"
) > -
1 
|| (request
                    
.getHeader(
"X-Requested-With"
) != 
null 
&& request
                    
.getHeader(
"X-Requested-With"
).indexOf(
"XMLHttpRequest"
) > -
1
))) {
                
// 如果不是异步请求
                
// Apply HTTP status code for error views, if specified.
                
// Only apply it if we're processing a top-level request.
                
Integer statusCode = determineStatusCode(request, viewName);
                
if 
(statusCode != 
null
) {
                    
applyStatusCodeIfPossible(request, response, statusCode);
                
}
                
return 
getModelAndView(viewName, ex, request);
            
else 
{
// JSON格式返回
                
try 
{
                    
PrintWriter writer = response.getWriter();
                    
writer.write(ex.getMessage());
                    
writer.flush();
                
catch 
(IOException e) {
                    
e.printStackTrace();
                
}
                
return 
null
;
 
            
}
        
else 
{
            
return 
null
;
        
}
    
}
}

    总结使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但方法1仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。

三、HandlerExceptionResolver自定义异常

1.在Spring的配置文件中,增加以下内容:

1
<
bean 
id
=
"exceptionHandler" 
class
=
"com.twosnail.exception.MyExceptionHandler"
/>

2.添加自定义的MyExceptionHandler类,代码如下:

    在这里,单独打印出了异常路径,便于在日志中查看,在对SystemException异常进行了特殊处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
5
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package 
com.twosnail.exception;
 
import 
java.util.Map;
 
import 
javax.servlet.http.HttpServletRequest;
import 
javax.servlet.http.HttpServletResponse;
import 
org.springframework.web.servlet.HandlerExceptionResolver;
import 
org.springframework.web.servlet.ModelAndView;
import 
org.springframework.web.servlet.View;
import 
org.springframework.web.servlet.view.RedirectView;
 
public 
class 
MyExceptionHandler 
implements 
HandlerExceptionResolver {
 
    
public 
ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, 
            
Object handler, Exception exception ) {
         
        
System.out.println( 
"【抛出异常】--异常路径为:" 
            
request.getServletPath() + 
"\n【异常信息】--" 
+  exception.getMessage() ) ;
        
//如果不是抛出的action业务异常则不处理
        
if
( !( exception 
instanceof 
SystemException ) ) {
            
return 
null
;
        
}
         
        
final 
SystemException actionE = (SystemException) exception;      
        
ModelAndView model = 
null
;
        
if
( actionE.getForwardType() == SystemException.FORWARD ) {
                
//进入页面渲染
                
model = 
new 
ModelAndView( actionE.getModelPath(), actionE.getAttributes());
        
else 
if
( actionE.getForwardType() == SystemException.REDIRECT ) {
                
model = 
new 
ModelAndView( 
new 
RedirectView( actionE.getModelPath(), 
true
));
        
else 
{
            
//直接返回页面内容
            
model = 
new 
ModelAndView( 
new 
View() {
                
@Override
                
public 
void 
render(Map<String, ?> arg0, HttpServletRequest arg1,
                        
HttpServletResponse arg2) 
throws 
Exception {
                     
                    
arg2.setContentType( 
"text/html" 
);
                    
arg2.setCharacterEncoding( actionE.getEncode() );
                    
if
( actionE.getResponseBody() != 
null 
) {
                        
arg2.getWriter().print( actionE.getResponseBody() );
                    
}
                
}
                 
                
@Override
                
public 
String getContentType() {
                    
return 
"text/html; charset=utf-8"
;
                
}
            
} );
        
}
         
        
return 
model;
    
}
}

    总结从上面的集成过程可知,使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点。在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。而SimpleMappingExceptionResolver就是HandlerExceptionResolver的默认实现类

 

转载地址:http://jdjdi.baihongyu.com/

你可能感兴趣的文章
ipconfig,ifconfig,iwconfig
查看>>
opensuse12.2 PL2303 minicom
查看>>
电平触发方式和边沿触发的区别
查看>>
网络视频服务器移植
查看>>
Encoding Schemes
查看>>
移植QT
查看>>
如此调用
查看>>
计算机的发展史
查看>>
带WiringPi库的交叉编译如何处理一
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Spring事务的七种传播行为
查看>>
ES写入找不到主节点问题排查
查看>>
Java8 HashMap集合解析
查看>>
ArrayList集合解析
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
Android计算器实现源码分析
查看>>
Android系统构架
查看>>
Android 跨应用程序访问窗口知识点总结
查看>>
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>