资讯专栏INFORMATION COLUMN

SSM全局异常处理——两种实用实现方案

int64 / 2450人阅读

摘要:本人也处于学习的阶段,发表此文章也是希望能够得到更多的技术交流和帮助,文中的不足还有劳大家指出全局异常处理两种实用实现方案

## SSM全局异常处理——两种实用实现方案 ##

先前做项目时自己不是很门清这块,在网上查阅资料后发现资料也不是很全面,因此自己摸索出来后就想着赶紧给大家分享一下,尽管此技术点很基础,但是希望能够帮到大家。

为什么实现:

在我们的项目运行过程中,无法完全避免出现一些位置的运行时异常(比如NullPointerException ),而恰恰我们并没有对该异常进行处理,那么就会将此异常抛向用户。

当用户浏览页面时突然眼前蹦出一堆看不懂的“外星文”,可想而知用户的体验度是非常差的。

而如果简单的配置一下异常处理的话可以在web.xml中进行配置异常后跳转的页面,例如404

  
       404
       /404err.jsp
   

            这种方法现在已经low到爆哦,如果我们是json请求呢?因此我们需要自己实现一套完美的异常处理,保证我们系统是健壮的!

 

 
springmvc HandlerExceptionResolver异常处理器:
今天我们就在springmvc的这个接口上进行一番操作(异常处理器啥是?)

public class SpringExceptionResolver implements HandlerExceptionResolver {
 
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
 HttpServletResponse response, Object handler, Exception ex) {

参数:

      request:当前请求

      response:当前响应对象

      ex: 当本次方法执行异常,这个参数就是当前异常对象

 

 
实现方式A——根据请求类型,选择不同的异常处理方式(不要忽略代码注释哦)
我们项目中的请求在一种角度可上分页面请求、json请求。因此根据请求类型,选择不同的异常处理方式就可以理解为:如果是页面请求异常了,我们就选择页面请求异常处理来返回错误信息。如果是json请求异常,那么就以json的形式返回。

 

开始前准备两个异常类型,为我们手动抛异常能区分开请求类型
CustomException:使用场景是前台发送json请求,那么我们在该请求的service层抛出CustomException,前台就会收到异常信息。

/**
 * 如果抛出此异常,系统会以json格式向前台返回异常信息
 * 使用方式: throw new CustomException("这里填入异常信息,会发送到前台");
 */
public class CustomException extends Exception{
    private static final long serialVersionUID = -1668707977736987938L;
    //异常信息
    public String message;
    public CustomException (String message) {
        super(message);
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

 

/**
* @ClassName: ReturnViewException 
* @Description: 此异常类型用来向前台返回页面
 */
public class ReturnViewException extends Exception{
 
    private static final long serialVersionUID = -1668707977736987938L;
 
    //异常信息
    public String message;
 
    public ReturnViewException (String message) {
        super(message);
        this.message = message;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

 

public class IntegrateException implements HandlerExceptionResolver {
 
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) {
        //判断是否为ajax请求,默认不是
        boolean isAjaxRequest = false;  
        //这段代码能够得知是否为ajax请求,也就是我们说的json请求
        if(!StringUtils.isBlank(request.getHeader("x-requested-with")) && request.getHeader("x-requested-with").equals("XMLHttpRequest")){  
            isAjaxRequest = true; 
        }
        //如果是ajax请求
        if(isAjaxRequest) {
            CustomException  customException = null;
            if(ex instanceof CustomException) {
                customException = (CustomException) ex;
            }else {
                //如果抛出的不是系统自定义的异常则重新构造一个未知错误异常
                //这里我就也有CustomException省事了,实际中应该要再定义一个新的异常
                customException = new CustomException ("系统未知错误,请联系管理员");
            }
             String message = customException.getMessage();
             //向前台返回错误信息
             ModelAndView model = new ModelAndView();
             FastJsonJsonView view = new FastJsonJsonView();
             Map map = new HashMap();
             map.put("code", 5000);
             map.put("message", message);
             view.setAttributesMap(map);
             model.setView(view);
             return model;
        }else {
            //如果不是ajax请求 那么异常后需要返回页面
            ReturnViewException returnViewException = null;
            //如果抛出的异常类型是我们预想的,会想前台返回我们指定在参数里的页面
            if(ex instanceof ReturnViewException) {
                returnViewException = (ReturnViewException) ex;
            }else {
                //这里的500是我资源下的500.jsp,使用了mvc的映射省去了前缀后缀
                //系统默认跳转到500页面
                returnViewException = new ReturnViewException("500"); 
            }
             ModelAndView model = new ModelAndView();
             model.setViewName(returnViewException.getMessage());
             return model;
        }
    }
}

在此同时我们需要在springmvc.xml中配置我们的全局异常处理类,bean id别随意更改..

现在就可以开始使用了~~~~

手动使用:

throw new CustemException("错误了"); //向前台返回 "错误了" 异常信息
throw new ReturnViewException("500err") //前台重定向到500err.jsp

当然出现未知异常后,回自动向前台返回我们默认的异常信息

 
实现方式B——自定义项目接口规则,判断特定的异常处理方式
实现的主要原理更简单明亮:

方才A方案是判断请求类型,这里我们更加暴力,假如我规定项目的json请求全部以 .json结尾,页面请求全部以 .page结尾,那么我们就可以在异常处理器拦截到异常时,判断请求的后缀来决定怎么处理了。不同点就在这里,但是虽然A复杂点,我还是推荐使用A

好,抛代码,这是springmvc.xml

   
    
    
    
    

 

创建异常类(这个东西,根据需要判多少种异常类型,我们可以创很多的,不仅限于一两个)

public class ParamException extends RuntimeException {
    public ParamException() {
        super();
    }
 
    public ParamException(String message) {
        super(message);
    }
 
    public ParamException(String message, Throwable cause) {
        super(message, cause);
    }
 
    public ParamException(Throwable cause) {
        super(cause);
    }
 
    protected ParamException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
public class PermissionException extends RuntimeException {
 
    public PermissionException() {
        super();
    }
 
    public PermissionException(String message) {
        super(message);
    }
 
    public PermissionException(String message, Throwable cause) {
        super(message, cause);
    }
 
    public PermissionException(Throwable cause) {
        super(cause);
    }
 
    protected PermissionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

然后我们上最关键的异常处理器

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        String url = request.getRequestURL().toString();
        ModelAndView mv;
        String defaultMsg = "System error";
 
        // 这里我们要求项目中所有请求json数据,都使用.json结尾
        if (url.endsWith(".json")) {
            if (ex instanceof PermissionException || ex instanceof ParamException) {
                JsonData result = JsonData.fail(ex.getMessage());
                mv = new ModelAndView("jsonView", result.toMap());
            } else {
                log.error("unknown json exception, url:" + url, ex);
                JsonData result = JsonData.fail(defaultMsg);
                mv = new ModelAndView("jsonView", result.toMap());
            }
        } else if (url.endsWith(".page")){ // 这里我们要求项目中所有请求page页面,都使用.page结尾
            log.error("unknown page exception, url:" + url, ex);
            JsonData result = JsonData.fail(defaultMsg);
            mv = new ModelAndView("exception", result.toMap());
        } else {
            log.error("unknow exception, url:" + url, ex);
            JsonData result = JsonData.fail(defaultMsg);
            mv = new ModelAndView("jsonView", result.toMap());
        }
 
        return mv;
    }

结束语:

这就是我整理出来的两种ssm全局异常处理方式了,希望能够帮助到大家。本人也处于学习的阶段,发表此文章也是希望能够得到更多的技术交流和帮助,文中的不足还有劳大家指出!

SSM全局异常处理——两种实用实现方案

csdn:https://blog.csdn.net/qq_4182...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73513.html

相关文章

  • Java后端

    摘要:,面向切面编程,中最主要的是用于事务方面的使用。目标达成后还会有去构建微服务,希望大家多多支持。原文地址手把手教程优雅的应用四手把手实现后端搭建第四期 SpringMVC 干货系列:从零搭建 SpringMVC+mybatis(四):Spring 两大核心之 AOP 学习 | 掘金技术征文 原本地址:SpringMVC 干货系列:从零搭建 SpringMVC+mybatis(四):Sp...

    joyvw 评论0 收藏0
  • spring中的统一异常处理

    摘要:首先,定义一个存放异常处理函数的类,并使用修饰。修饰的方法的写法和内的异常处理函数写法是一样的。控制生效的范围注意到,我是这样编写注解的它用来限定这些异常处理函数起作用的的范围。使用的机制,做统一异常处理。 在具体的SSM项目开发中,由于Controller层为处于请求处理的最顶层,再往上就是框架代码的。因此,肯定需要在Controller捕获所有异常,并且做适当处理,返回给前端一个友...

    paraller 评论0 收藏0
  • 移动商城项目【总结】

    摘要:有必要建一个资源服务器存放静态资源。一些用户级别的数据轻量可以考虑存储在中。存储的是值,可以通过来对和对象之间的转换如果我们的数据是在后台传过去或者转换而成的,在前台上并没有做什么改变的话。 移动商城项目总结 移动商城项目是我第二个做得比较大的项目,该项目系统来源于传智Java168期,十天的视频课程(想要视频的同学关注我的公众号就可以直接获取了) 通过这次的项目又再次开阔了我的视野,...

    BlackHole1 评论0 收藏0
  • SpringBoot搭建一个SSM开发框架(二)

    摘要:接着上一篇,我们在测试可以允许后,我们接着来写一个查询功能,一连接数据库的查询例子我来看看项目的结构顶级父项目公司默认有的父项目数据层 接着上一篇,我们在测试web可以允许后,我们接着来写一个查询功能, 一、 连接数据库的查询例子 我来看看项目的结构: tx-parent 顶级父项目(公司默认有的) |- tx-manager ------------------------...

    Nosee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<