PUT 和 POST 在未知属性上失败 Spring 不同的行为

spring

1个回答

写回答

lele8720

2025-06-19 21:35

+ 关注

Spring
Spring

PUT 和 POST 是 HTTP 请求方法中的两种常见方式。它们在 Spring 框架中的行为略有不同,特别是当请求中包含未知属性时。本文将讨论 PUT 和 POST 在未知属性上失败时 Spring 的不同行为,并通过案例代码进行说明。

PUT 方法的行为

PUT 方法用于向服务器发送数据,用于创建或更新资源。当使用 PUT 方法时,客户端通常会提供完整的资源表示,包括所有属性。如果请求中包含未知属性,Spring 会根据默认配置将其忽略,并只更新已知属性。

下面是一个使用 PUT 方法的示例代码:

Java

@RestController

@RequestMapping("/users")

public class UserController {

@PutMapping("/{id}")

public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {

// 根据 id 查找要更新的用户

User user = userService.findById(id);

if (user == null) {

return ResponseEntity.notFound().build();

}

// 更新用户属性

user.setName(updatedUser.getName());

user.setEmAIl(updatedUser.getEmAIl());

// 保存更新后的用户

userService.save(user);

return ResponseEntity.ok(user);

}

}

在上面的代码中,PUT 请求被映射到 updateUser 方法。该方法接收一个 id 参数和一个 updatedUser 对象作为请求体,其中 id 用于标识要更新的用户,updatedUser 包含要更新的属性。

如果请求中包含未知属性,例如:

JSon

{

"id": 1,

"name": "John Doe",

"emAIl": "johndoe@example.com",

"age": 25

}

Spring 会忽略 age 属性,并只更新 nameemAIl 属性。这是因为在默认情况下,Spring 的数据绑定机制会忽略未知属性。

POST 方法的行为

POST 方法用于向服务器提交数据,用于创建资源。与 PUT 方法不同,POST 方法通常不要求提供完整的资源表示,可以只包含部分属性。当使用 POST 方法时,如果请求中包含未知属性,Spring 会根据默认配置将其忽略,并保存已知属性。

下面是一个使用 POST 方法的示例代码:

Java

@RestController

@RequestMapping("/users")

public class UserController {

@PostMapping

public ResponseEntity<User> createUser(@RequestBody User newUser) {

// 保存新用户

userService.save(newUser);

return ResponseEntity.ok(newUser);

}

}

在上面的代码中,POST 请求被映射到 createUser 方法。该方法接收一个 newUser 对象作为请求体,其中包含要创建的用户的属性。

如果请求中包含未知属性,例如:

JSon

{

"name": "John Doe",

"emAIl": "johndoe@example.com",

"age": 25

}

Spring 会忽略 age 属性,并保存 nameemAIl 属性。这是因为在默认情况下,Spring 的数据绑定机制会忽略未知属性。

自定义处理未知属性

有时,我们可能希望在请求中包含未知属性时,Spring 可以进行处理而不是忽略它们。为了实现这一点,我们可以自定义数据绑定规则。

Spring 中,我们可以通过实现 HandlerMethodArgumentResolver 接口来自定义数据绑定规则。下面是一个示例代码:

Java

public class UnknownPropertyHandlerResolver implements HandlerMethodArgumentResolver {

@Override

public boolean supportsParameter(MethodParameter parameter) {

return parameter.getParameterType().equals(User.class);

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContAIner mavContAIner, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);

User user = objectMapper.readValue(request.getInputStream(), User.class);

return user;

}

}

在上面的代码中,UnknownPropertyHandlerResolver 类实现了 HandlerMethodArgumentResolver 接口,并重写了两个方法:supportsParameterresolveArgumentsupportsParameter 方法用于判断该解析器是否支持给定的参数类型,这里我们只支持 User 类型。resolveArgument 方法用于解析请求参数,并将其转换为 User 对象。

在自定义解析器后,我们需要将其注册到 Spring 的配置中。可以通过创建一个配置类来实现:

Java

@Configuration

public class WebConfig implements WebMvcConfigurer {

@Override

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

resolvers.add(new UnknownPropertyHandlerResolver());

}

}

在上面的代码中,WebConfig 类实现了 WebMvcConfigurer 接口,并重写了 addArgumentResolvers 方法,将自定义解析器添加到解析器列表中。

PUT 和 POST 是常见的 HTTP 请求方法,在 Spring 中的行为略有不同。当请求中包含未知属性时,PUT 方法会忽略这些属性,只更新已知属性;而 POST 方法会忽略这些属性,只保存已知属性。如果需要处理未知属性,可以通过自定义数据绑定规则来实现。以上是关于 PUT 和 POST 在未知属性上失败 Spring 不同行为的讨论,并提供了相应的案例代码。

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号