首页 > 其他分享 >SpringMVC中的异常处理机制

SpringMVC中的异常处理机制

时间:2024-05-17 14:55:19浏览次数:17  
标签:exception 请求 SpringMVC request import 机制 异常 response

1. 概述

SpringMVC提供了基于xml和基于注解的异常处理机制,一般情况下两者都要进行配置,xml异常处理机制主要用于处理xml方式产生的异常,注解异常处理机制主要用于处理基于注解方式产生的异常。

2. 基于xml方式的异常处理机制

<!--配置基于xml的异常映射-->
    <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!--key属性指定具体的出错类型,标签体中为对应的出错页面(这个值会拼上前后缀以得到全路径)-->
                <prop key="java.lang.Exception">system-error</prop>
            </props>
        </property>
    </bean>

3. 基于注解方式的异常处理

步骤:

  1. 使用@ControllerAdvice注解表名此类为异常处理类
  2. 方法上使用@ExceptionHandler注解表示此方法处理何种异常,如
    @ExceptionHandler(value = ArithmeticException.class)

4. 实际应用

一般若是普通请求产生的异常,则应该返回错误页面,若是Ajax请求返回的是相应的JSON字符串。

  1. 判断一个请求是否是Ajax请求

    请求依据:(两者含其一则为Ajax请求)

    • 请求头中Accept中包含application/json
    • 请求头中X-Requested-With字段为XMLHttpRequest的为Ajax请求
     /**
         * 判断此次请求是否是Ajax请求
         * @param request 此次请求对应的request对象
         * @return true表示是Ajax请求,false表示是普通请求
         */
        public static boolean isAjax(HttpServletRequest request) {
            
            String accept = request.getHeader("Accept");
            String xRequestHeader = request.getHeader("X-Requested-With");
    
            return accept != null && accept.contains("application/json")
                    ||
                    xRequestHeader != null && xRequestHeader.equals("XMLHttpRequest");
        }
    
  2. 配置基于xml方式的异常处理机制

  3. 配置基于注解方式的异常处理

    package com.wuw.crowd.mvc.config;
    
    import com.google.gson.Gson;
    import com.wuw.crowd.exception.LoginFailedException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    import com.wuw.crowd.util.CrowdUtil;
    import com.wuw.crowd.constant.CrowdConstant;
    import com.wuw.crowd.util.ResultEntity;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @description: 基于注解的异常处理机制
     * @author: WuW
     * @create: 2022/5/2 18:36
     */
    @ControllerAdvice
    public class MyExceptionResolver {
    
        @ExceptionHandler(value = ArithmeticException.class)
        public ModelAndView resolveArithmeticException(HttpServletRequest request, HttpServletResponse response, NullPointerException exception) throws IOException {
            String viewName = "system-error";
            return commonResolve(viewName, exception, request, response);
        }
    
        @ExceptionHandler(value = NullPointerException.class)
        public ModelAndView resolveNullPointerException(HttpServletRequest request, HttpServletResponse response, NullPointerException exception) throws IOException {
            String viewName = "system-error";
            return commonResolve(viewName, exception, request, response);
        }
    
        @ExceptionHandler(value = LoginFailedException.class)
        public ModelAndView resolveLoginFailedException(HttpServletRequest request, HttpServletResponse response, LoginFailedException exception) throws IOException {
            String viewName = "admin-login";
            return commonResolve(viewName, exception, request, response);
        }
    
        /**
         * 抽取异常处理机制的公共部分
         * @param viewName 将要返回到哪个页面
         * @param exception 捕获到的异常信息
         * @param request 请求对象
         * @param response 响应对象
         * @return 返回ModelAndView
         * @throws IOException 响应对象获取输出流时抛出异常
         */
        private ModelAndView commonResolve(String viewName, Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
    
            boolean ajax = CrowdUtil.isAjax(request);
    
            // 如果是Ajax请求
            if (ajax) {
                // 创建ResultEntity对象
                ResultEntity<Object> failed = ResultEntity.failed(exception.getMessage());
                Gson gson = new Gson();
                // 将ResultEntity对象转换为JSON字符串
                String s = gson.toJson(failed);
                // 将JSON字符串作为响应体返回给浏览器
                response.getWriter().write(s);
                return null;
            }
    
            // 如果是普通请求
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
            // 设置对应的视图名称
            modelAndView.setViewName(viewName);
            return modelAndView;
        }
    
    }
    
    

    注:ResultEntity对象为统一响应对象,其中的failed方法实际上是将传入的exception对象封装成一个ResultEntity对象并返回给调用者。CrowdConstant类为自定义的常量类,主要用于存储各种常用的字符串,可有效预防写错单词导致的程序错误,在实际开发中十分有用。

    解释:若为Ajax请求,则应该向浏览器返回一个JSON字符串格式的ResultEntity对象,此时异常处理机制返回null即可;若为普通请求,则抛出异常,并返回异常页面(此时是页面名称,因为前后缀在mvc文件中已配置)。

标签:exception,请求,SpringMVC,request,import,机制,异常,response
From: https://www.cnblogs.com/wuw-calliope/p/16229474.html

相关文章

  • spring security 使用过滤器认证登录时,抛出自定义异常
    前情提要最近在做项目的改造,涉及到新增用户的离职冻结状态,当被离职/冻结后,尝试登录系统,则抛出不同的异常代码给前端,前端依据不同的异常代码提示不同的文本。所以需要对项目的认证逻辑简单调整,增加按照不同的登录用户的状态(离职/冻结)判断,如果满足指定状态,则抛出对应的异常代码。......
  • 多线程下使用List中的subList和remove方法产生的 java.util.ConcurrentModificationEx
    在说多线程操作List之前,我们先看下单线程下产生的问题:单线程List<Integer>listA=newArrayList<>();listA.add(1);listA.add(2);listA.add(3);listA.add(4);listA.add(5);listA.add(6);for(Integera:listA){......
  • 谈谈垃圾回收机制方式及内存管理。
    回收机制方式1、定义和用法:垃圾回收机制(GC:GarbageCollection),执行环境负责管理代码执行过程中使用的内存。2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执......
  • 鸿蒙HarmonyOS实战-Stage模型(服务卡片介绍和运行机制)
    ......
  • NODEJS通过发送json数据查询目标服务,实现服务器状态监控,发现异常发送到微信群提醒
    root@aea87fa6e6a2:/home/node#catlogin2.jsconstrequest=require('request-promise');constmoment=require('moment');constcron=require('node-cron');process.env.TZ='Asia/Shanghai';//设置时区为上海时区constrp......
  • 论文阅读:基于多通道自注意力机制的电子病历实体关系抽取
    宁尚明,滕飞,李天瑞.基于多通道自注意力机制的电子病历实体关系抽取[J].计算机学报,2020,43(5):916-929.本文的主要贡献一种更为高效的神经网络架构:recurrent+transformer。"recurrent+CNN"是当前医学文本领域实体关系抽取任务的主流建模方法,为进一步建模表征更全面......
  • tkinter打包执行异常
    一、背景tkinter界面中通常会用到日历控件,常用的是tkcalendar,这个包在编译器中使用时一般没什么问题,但是在打包时会出现问题,无论是Pyinstaller还是Nuitka,网上能查到的都是Pyinstaller解决方案,这里写一下Nuitka的解决方案。二、tkcalendar问题1——Calendar与python自带的calenda......
  • 2.2.3 加入objection机制
    先分析前面的:上一节中虽然输出了"main_phaseiscalled",但是"dataisdrived"并没有输出。但是既然进入了main_phase,应该会把这一整个任务执行完成才对,但是这里好像在执行的过程中被外力kill掉了?UVM中通过objection来控制验证平台的关闭在上一节中并没有调用finish语句,但是在......
  • 2.2.2加入factory机制
    driver代码:这里的factory机制被集成在了一个宏中:uvm_comphonent_utils。这个宏所做的事情非常多,其中之一就是将my_driver登记在UVM内部的一张表中,这张表是factory功能实现的基础。只要在定义一个新的类时使用这个宏,就相当于把这个类注册到了这个表中。在给driver加入这个机制后......
  • C++:自定义异常
    #include<iostream>#include<stdexcept>//自定义异常类classMyException:publicstd::exception{public://重写what()函数以提供异常的描述,const表示函数不会改变类的成员变量,noexcept表示不会抛出异常constchar*what()constnoexceptoverride{......