初见Requestbody 与 Requestparam 与 415

668 阅读3分钟

415 Unsupported Media Type 错误记录🌐

在模仿前后端分离的项目时,突然遇到 415 Unsupported Media Type 错误,这个错误究竟是怎么回事呢?🌟

首先,什么是 415 Unsupported Media Type 错误?😱

当客户端发送的 Content-Type 设置不符合服务器的预期时,就可能出现 415 Unsupported Media Type 错误。简单来说,就是客户端传递的数据格式服务器期望的数据格式不匹配。

开发中,IDEA 有时会提示不同的参数传递方式:

  • 如果接口方法使用了@RequestBody 注解,通常意味着后端希望接收到 JSON 格式的数据。因此前端需要将数据序列化为 JSON,并将 Content-Type 设置为 application/json。否则,后端无法正确解析数据内容,可能会导致 415 Unsupported Media Type 错误。

  • 如果接口方法使用了 @RequestParam 注解,通常意味着后端期望接收 表单格式的数据,即 application/x-www-form-urlencoded。在这种情况下,前端可以直接发送键值对格式的数据(如 key1=value1&key2=value2),不需要 JSON 序列化,且可以省略 Content-Type 的设置(浏览器会自动添加)。

事故发生的示例代码

@PostMapping("/user/account/token/")
public ResponseEntity<?> getToken(@RequestBody LoginRequest loginRequest) {
    // 处理请求
    return ResponseEntity.ok("假设Token生成了");
}
<template>
    <div>
        <input v-model="username" placeholder="请输入用户名" />
        <input v-model="password" type="password" placeholder="请输入密码" />
        <button @click="getToken">获取 Token</button>
        <p>响应内容:{{ responseMessage }}</p>
    </div>
</template>
<script setup>

import { ref } from 'vue';
import $ from 'jquery';

// 定义响应式变量
const username = ref('');
const password = ref('');
const responseMessage = ref('');

const getToken = () => {
    $.ajax({
        url: 'http://localhost:8080/user/account/token/',
        type: 'POST',

        data:{ // 未将数据转换为 JSON 字符串
        username: username.value,
        password: password.value
        },
        success: (response) => {
            responseMessage.value = response;
        },
        error: (xhr, status, error) => {
            console.error("请求失败:", error);
            responseMessage.value = "请求失败";
        }
    });
};
</script>

在这个例子里,@RequestBody 告诉 Spring Boot 将请求体中的 JSON 数据 解析到 LoginRequest 对象中。因此,如果我的请求头中的 Content-Type 不是 application/json,也就是没有转成JSON,就会触发 415 错误。

415 错误的常见原因 🎯

  1. 缺少 Content-Type 设置

在前端请求中,我没有显式设置 Content-Type,导致默认值可能是 text/plain,而后端期望 application/json 格式的数据。

例如:如果你在前端请求中使用了 JSON.stringify(),但是没有显式设置 Content-Type 为 application/json,可能会导致请求头的 Content-Type 默认是 text/plain。而如果后端期望接收的是 application/json 格式的数据,它可能会无法正确解析请求体,因为它会认为请求体是 text/plain 类型

  1. 注解和请求方式不匹配

使用了 @RequestBody注解,但我传递的却是表单数据(例如application/username=tom&password=123456),导致数据格式不符合要求。

解决 415 Unsupported Media Type 错误的技巧 🔧

  1. 显式设置 Content-Type

确保我的 Ajax 请求中明确设置了 contentType: "application/json",确保请求符合 JSON 格式:

$.ajax({
    url: "/user/account/token",
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify({
        username: "user",
        password: "pass"
    }),
    success: (response) => {
        console.log("Token received:", response)
    }
});
  1. 检查后端注解

确保在后端代码中正确使用了 @RequestBody 注解。调试请求日志:通过前端控制台和后端日志检查请求的 Content-Type 和数据格式是否匹配。


我自己的错误原因分析:IDEA 补全选错了 😅😅😅

这是我第一次使用 IDEA 补全 Ajax 请求代码,还不知道这两者区别的我直接补全了@RequestBody,而我实际模拟的项目的代码是没有转化成JSON,导致错误的 Content-Type 设置。这种情况下,我没有显式设置 contentType: "application/json",而 IDEA 自动填充的默认类型可能是 text/plain,这与后端需要的 JSON 格式不符。