异常统一处理:HttpRequestMethodNotSupportedException(Http请求方法不支持异常)

一、引言

本篇内容是“异常统一处理”系列文章的重要组成部分,主要聚焦于对 HttpRequestMethodNotSupportedException 的原理解析与异常处理机制,并给出测试案例。

  • 关于 全局异常统一处理 的原理和完整实现逻辑,请参考文章:
    《SpringBoot 全局异常统一处理(AOP):@RestControllerAdvice + @ExceptionHandler + @ResponseStatus》
  • 本文仅详细解析 HttpRequestMethodNotSupportedException 的异常处理;其他类型异常的原理和处理方法,请参阅本文所在专栏内的其他文章。

二、异常原理

在Spring Boot应用中,HttpRequestMethodNotSupportedException异常是由Spring MVC框架抛出的,当客户端通过HTTP协议发送请求到服务器端时,所使用的HTTP方法(如GET、POST、PUT、DELETE等)与控制器方法所期望的方法不匹配时,就会触发这个异常。

例如,如果你有一个只支持POST请求的RESTful API接口:

@PostMapping("/some-resource")
public ResponseEntity<String> handlePostRequest(...) {// ...
}

但客户端尝试以GET方法访问该资源:

GET /some-resource

此时,由于服务器端没有为GET方法配置对应的处理方法,Spring MVC在解析请求并试图找到合适的方法进行处理时,无法找到对应HTTP GET方法的处理器,因此会抛出HttpRequestMethodNotSupportedException异常,并附带信息说明请求的方法不受支持。

解决这个问题的方式是确保客户端使用与服务器端定义的控制器方法相匹配的HTTP方法进行通信。如果需要支持多种HTTP方法,可以使用@RequestMapping注解配合method属性指定多个支持的方法,或者分别使用@GetMapping@PostMapping等注解来明确指定每个HTTP方法的处理器方法。

三、异常处理代码

在Spring Boot应用中,我们可以通过使用@ExceptionHandler注解来捕获并处理HttpRequestMethodNotSupportedException异常。

3.1 异常处理示意图

在这里插入图片描述

3.2 异常处理核心代码

异常处理策略的核心代码如下:

package com.example.core.advice;import com.example.core.advice.util.ApiUtil;
import com.example.core.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.servlet.http.HttpServletRequest;/*** 全局异常处理器*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {private final HttpServletRequest request;public GlobalExceptionHandler(HttpServletRequest request) {this.request = request;}/*** Http请求方法不支持异常。* <p>* 一个接口,是由【请求方法】(GET、POST、PUT、DELETE等)和【接口路径】两个部分来唯一确定的。* 当一个请求,能找到对应的【接口路径】,但是没有找到对应的【请求方法】时,会报异常 HttpRequestMethodNotSupportedException ,进入此异常处理。* 当一个请求,找不到对应的【接口路径】时,会直接报错 404 ,不会进入此异常处理。* <p>* 测试:一个接口,应该用Post请求,却用了GET请求。* <p>* 报错示例:* DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]* <p>* 注意:此方法不能包含 HandlerMethod 入参,否则会报错;因为进入此异常处理方法,意味着收到的请求是没有对应的控制器方法的。*/@ExceptionHandler@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)public Result<String> handle(HttpRequestMethodNotSupportedException e) {String api = ApiUtil.getApi(request);String userMessage = "Http请求方法不支持异常!请稍后重试,或联系业务人员处理。";String errorMessage = String.format("HttpRequestMethodNotSupportedException(Http请求方法不支持异常);当前请求接口:[%s];报错信息:%s", api, e.getMessage());return Result.fail(userMessage, String.valueOf(HttpStatus.METHOD_NOT_ALLOWED.value()), errorMessage);}}

上述代码中,当出现HttpRequestMethodNotSupportedException异常时,系统将返回一个状态码为405(Method Not Allowed)的结果,并附带具体的错误信息。

3.3 获取当前请求的API

package com.example.core.advice.util;import javax.servlet.http.HttpServletRequest;/*** API工具类** @author songguanxun* @since 2024-2-18*/
public class ApiUtil {/*** 获取当前请求的API*/public static String getApi(HttpServletRequest request) {String method = request.getMethod();String uri = request.getRequestURI();return String.format("%s %s", method, uri);}}

四、测试案例

4.1 测试代码

package com.example.web.exception.controller;import com.example.web.model.param.UserAddParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;@Slf4j
@RestController
@RequestMapping("exception")
@Tag(name = "异常统一处理")
public class ExceptionController {@PostMapping("HttpRequestMethodNotSupportedException")@Operation(summary = "异常:HttpRequestMethodNotSupportedException")public void testHttpRequestMethodNotSupportedException(@Valid @RequestBody UserAddParam param) {log.info("测试:HttpRequestMethodNotSupportedException");}}

4.2 正确请求示例

在这里插入图片描述

4.3 未处理异常时的报错

请求响应

在这里插入图片描述

控制台的错误日志

在这里插入图片描述

4.4 已处理异常时的响应

在这里插入图片描述

五、触发异常的情景

如下示例中,当请求 删除用户 接口时,前端漏传id参数,导致接口路径变为 [/users];只有新增用户和查询用户列表的接口为 [/users],且请求方法都不是DELETE。最后,就抛出了 HttpRequestMethodNotSupportedException 异常,因为 接口路径[/users]不支持DELETE方法

当出现此种情况时,说明前端调用接口出现了错误,应检查前端请求代码,将id参数补全。

接口示例

在这里插入图片描述

请求示例

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/479198.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 USART详细解读(理论知识)

文章目录 前言一、同步传输和异步传输二、UART协议三、UART硬件结构1.波特率&#xff0c;数据位&#xff0c;校验位&#xff0c;停止位设置2.数据发送流程3.数据接收流程4.中断控制 总结 前言 本篇文章来给大家讲解一下STM32中的USART&#xff0c;USART是STM32中非常重要的一个…

Vscode vim 插件使用Ctrl+C和V进行复制粘贴到剪切板

Vscode vim 插件使用CtrlC和V进行复制粘贴到剪切板 使用这一个插件的时候复制粘贴和其他软件互动的时候体验不好, 并且不可以用Ctrl c, Ctrl v很不爽 "vim.commandLineModeKeyBindings": [{"before" : ["Ctrl", "c"],"after&q…

索引失效的10中场景

目录 前言 1. 准备工作 1.1 创建user表 1.2 插入数据 1.3 查看数据库版本 1.4 查看执行计划 2. 不满足最左匹配原则 2.1 哪些情况索引有效&#xff1f; 2.2 哪些情况索引失效&#xff1f; 3. 使用了select * 4. 索引列上有计算 5. 索引列用了函数 6. 字段类型不同 …

Vue25 过滤器

实例 dayjs.min.js需要去bootcdn下载 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>过滤器</title><script type"text/javascript" src"../js/vue.js"></script><script t…

第三讲 数据存储

面向磁盘的架构 DBMS 假定数据库的主要存储位置位于非易失性磁盘【non-volatile disk】上。 DBMS 的组件【components】负责管理非易失性【non-volatile】和易失性【volatile】存储之间的数据移动。 为了理解来回移动数据的影响&#xff0c;我们首先要先理解存储层次结构是什么…

C#分部类、分割类的用法,及用分割类设计一个计算器

目录 一、涉及到的知识点 1.分部类 2.分部类主要应用在以下两个方面 3.合理使用分部类分割类 4.事件处理程序 5.Math.Ceiling方法 6.Text.Contains() 7.pictureBox.Tag属性 二、实例 1.源码 2.生成效果 在开发一些大型项目或者特殊部署时&#xff0c;可能需要…

Appium Python自动化测试之环境搭建

Appium简介 Appium是一个自动化测试开源工具&#xff0c;支持IOS和Android平台上的移动原生应用、移动Web应用和混合应用。所谓的“移动原生应用”是指那些用IOS或者Android SDK写的应用&#xff1b;所谓的“移动Web应用”是指使用移动浏览器方位的应用&#xff08;Appium支持…

SQL注入工具之SQLmap入门操作

了解SQLmap 基础操作 SQLmap是一款自动化的SQL注入工具&#xff0c;可以用于检测和利用SQL注入漏洞。 以下是SQLmap的入门操作步骤&#xff1a; 1.下载SQLmap&#xff1a;可以从官方网站&#xff08;https://sqlmap.org/&#xff09;下载最新版本的SQLmap。 2.打开终端&#…

Maxwell - 增量数据同步工具

前言 今天来学习一个新的大数据小工具 Maxwell &#xff0c;它和 Sqoop 很像。Sqoop主要用于在 Hadoop &#xff08;比如 HDFS、Hive、HBase 等&#xff09;和关系型数据库之间进行数据的批量导入和导出&#xff0c;而 Maxwell 则主要用于监控数据库的变化&#xff08;通过监控…

D258——可单电源或双电源 工作,应用范围包括变频放大器、DC增益部件和所有常规运算放大电路。

D258是由两个独立的高增益运算放大器组成。可以是单电源工作&#xff0c;也可以是双电源工作,电源的电流消耗与电源电压大小无关。应用范围包括变频放大器、DC增益部件和所有常规运算放大电路。 主要特点&#xff1a; ● 可单电源或双电源 工作 ● 在一个封装内的两个经内部补…

《软件方法(下)》8.2.5.2 属性是否直接描述类(202402更新)(1)

8.2.5.2 属性是否直接描述类 类和属性连在一起说"类的属性"&#xff0c;应该能直接说得通&#xff0c;否则类和属性的搭配是不合适的。这个时候应该找到或建立合适的类&#xff0c;把该属性移进去。 例如图8-57&#xff0c;“人员的组织名称”是“人员的组织的名称…

如何使用Docker搭建YesPlayMusic网易云音乐播放器并发布至公网访问

文章目录 1. 安装Docker2. 本地安装部署YesPlayMusic3. 安装cpolar内网穿透4. 固定YesPlayMusic公网地址 本篇文章讲解如何使用Docker搭建YesPlayMusic网易云音乐播放器&#xff0c;并且结合cpolar内网穿透实现公网访问音乐播放器。 YesPlayMusic是一款优秀的个人音乐播放器&am…