全局异常拦截以及拦截器转发异常 + 前端vue接收异常信息抛出异常

本文介绍了如何在Spring MVC中实现全局异常处理,通过@ControllerAdvice注解创建全局异常拦截类,捕获Controller层的异常。同时,针对拦截器中捕获的异常,通过转发到特定Controller进行处理,确保异常信息能正确传递到前端。并展示了前端如何利用axios拦截响应,处理返回的错误信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、创建全局异常拦截类

package com.zx.framework.handler;

import com.zx.cargo.pojo.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice(
        basePackages = {
                "com.zx.cargo.stock.controller",
                "com.zx.cargo.code.controller"
        }
)
public class GlobalExceptionHandler {
    @ExceptionHandler({Throwable.class})
    public ResponseWrapper handleException(Throwable cause) {
        log.error("---start---全局异常-@see com.zx.framework.handler.HandlerException");
        System.out.println("cause--->"+cause.getMessage());
        cause.printStackTrace();
        log.error("---end---全局异常-@see com.zx.framework.handler.HandlerException");

        // 异常信息
        String message = cause.getMessage();
        if (StringUtils.isEmpty(message)) {
            message = "服务器内部错误!";
        }

        return new ResponseWrapper<Boolean, String>().failure().setMessage(message);
    }
}

了解 @ControllerAdvice

@ControllerAdvice是组件注解,他使得其实现类能够被classpath扫描自动发现,如果应用是通过MVC命令空间或MVC Java编程方式配置,那么该特性默认是自动开启的。

注解@ControllerAdvice的类可以拥有@ExceptionHandler, @InitBinder或 @ModelAttribute注解的方法,并且这些方法会被应用到控制器类层次的所有@RequestMapping方法上。

@ControllerAdvice会获取从Controller抛出的异常,只能获取从Controller抛出异常

二、拦截器转发异常信息

首先拦截器与过滤器 是在进入Controller层之前加载的,他们抛出的异常全局异常类拦截不到我们需要做一个异常信息的转发 获取到异常信息 将他抛出到Controller层

1.创建抛出异常的Controller

package com.zx.cargo.error.web;

import com.zx.cargo.pojo.GlobalException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局过滤器 抛出异常 Controller
 */
@RequestMapping("/error")
@RestController
public class ErrorController {
    @RequestMapping("/exception")
    public void handleException(HttpServletRequest request) {
        throw new GlobalException(request.getAttribute("error").toString());
    }
}

2.在拦截器获取异常并重定向到异常Controller

try {
                     verify = JwtUtil.isVerify(token, user);
                } catch (ExpiredJwtException jwtExp) {
                    // 异常捕获,发送到error controller
                    request.setAttribute("error", "登录超时,请重新登录");
                    //将异常分发到/error/exthrow控制器
                    request.getRequestDispatcher("/error/exception").forward(request, response);
                }

前端vue进行配置

import {Loading, Message, MessageBox} from 'element-ui'

//响应回来token是否过期
Axios.interceptors.response.use(response => {
    if (response.data && response.data.status === false) {

      // 处理结果-未成功(skip为true跳过此处错误提示,在具体方法做处理)
      if (response.data.skip === false) {
        if (response.data.message) {
          Message.error(response.data.message)
        }
        return Promise.reject(response.data.message)
      }
    }
    return response

  },
  error => {
    return Promise.reject(error)
  })
### 解决 Vue 中 Axios 请求失败状态码为 400 的问题 当遇到 HTTP 状态码 400 错误时,通常意味着服务器无法处理客户端发送的请求,因为请求中有语法错误或缺少必要的参数。为了更好地管理和响应这种类型的错误,在 Vue 应用程序中可以采取以下措施: #### 1. 设置全局拦截器捕获错误 通过设置 Axios 的全局请求和响应拦截器来统一管理 API 调用中的异常情况。 ```javascript import axios from 'axios'; // 创建一个新的 Axios 实例 const instance = axios.create({ baseURL: process.env.VUE_APP_API_URL, }); // 添加响应拦截器 instance.interceptors.response.use( response => { // 对于成功的响应不做特殊处理 return response; }, error => { const { response } = error; if (response && response.status === 400) { console.error('Bad Request:', response.data); throw new Error(`Server responded with status ${response.status}: Bad Request`); } // 将其他类型的错误继续抛出以便上层捕捉 return Promise.reject(error); } ); export default instance; ``` 此代码片段定义了一个自定义的 Axios 实例,并为其配置了响应拦截器以检测并处理特定的状态码 400 响应[^1]。 #### 2. 使用 try-catch 结构调用服务方法 在实际发起网络请求的地方采用 `try...catch` 或者 `.then().catch()` 来包裹异步操作,从而能够优雅地处理可能出现的各种错误状况。 ```javascript async function fetchData() { try { const result = await axios.get('/api/data'); return result.data; } catch (error) { if (!error.response) { // 如果没有收到有效的响应,则可能是连接超时等问题 alert('Network error occurred.'); } else if (error.response.status === 400) { // 特定情况下显示更详细的提示信息给用户 alert('Invalid data was sent to server, please check your input and retry.'); } throw error; // 继续传播未被捕获的错误 } } ``` 这段 JavaScript 函数展示了如何利用 `try...catch` 构造去执行可能引发拒绝承诺的操作,并针对不同场景提供相应的反馈机制[^2]。 #### 3. 提供友好的用户体验界面 对于前端应用而言,重要的是要让用户知道发生了什么以及他们应该怎么做才能解决问题。可以通过模态框、通知条或其他形式向用户提供清晰而简洁的信息说明。 例如,可以在页面顶部添加一个消息栏用于展示来自后端API返回的消息内容;也可以设计专门的错误页用来引导访客回到正常浏览路径上去。 综上所述,面对 Vue 中 Axios 发生 400 状态码的情况,除了技术层面的有效应对之外,还应当注重提升整体应用程序的质量和服务水平,确保即使出现问题也能给予良好的交互体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国家级著名CV工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值