通过一个简单的Spring Boot应用程序,我试图理解Spring Boot注释@RequestParam和@RequestBody之间的区别及其各自的用法。Spring文档将@RequestParam定义为“表示方法参数应绑定到web请求参数的注释”,将@RequestBody定义为“表示方法参数应绑定到web请求主体的注释”因此,可以公平地假设注释和相关方法都可以用作等最终备选方案(类似结果的不同方法),以将参数传递给后端应用程序,例如插入值“email”,用户数据库中的“用户名”和“密码”(为了简单起见,忘记了密码的必要加密)。
因此,可以预期代码会在下面被截断
@PostMapping
public User save(@RequestBody User user) {
return userService.createUser(user);
}
相当于
@PostMapping(value = "/users")
public ResponseEntity<User> createUser(
@RequestParam String email,
@RequestParam String username,
@RequestParam String password
) {
try {
User user = new User();
user.setEmail(email);
user.setUsername(username);
user.setPassword(password);
userService.createUser(user);
return ResponseEntity.noContent().build();
} catch (Exception exception) {
return new ResponseEntity<>(HttpStatus.I_AM_A_TEAPOT);
}
}
使用Postman尝试@RequestBody替代方案会得到200 OK响应:
但尝试@RequestParam替代方案会导致400“错误请求”错误:
为什么这个@RequestParam方法会触发一个错误,而显然等效的方法@RequestBody会按预期工作?
为了完整起见,下面给出了用户模型:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
存储库如下所示:
public interface UserRepository extends JpaRepository<User, Long> {}
用户服务界面如下所示:
public interface UserService {
List<User> getAllUsers();
User getUserById(Long id);
User createUser(User user);
void deleteUser(Long id);
}
用户服务如下:
@Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Override
public User createUser(User user) {
return userRepository.save(user);
}
@Override
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
@Override
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
你在url中传递请求参数值的方式是不正确的。对于多个参数,u可以传递如下值:
http://<url>:<port>/user/101?param1=10¶m2=20
并参考以下答案:
如何将RequestParam值设置为URL
将多个参数传递给RestAPI-Spring
首先,感谢您的支持和花在测试代码上的时间!@requestParam和@requestBody实际上都可以用作将值传递到后端的两个备选方案,正如前面的回答中所断言的(谢谢!)。仍然需要解释为什么不使用我问题中提供的代码,因为在postman中修改请求(如图所示)没有帮助,而使用cUrl发布请求会导致完全相同的405错误。因此,必须在代码中找到解决方案。找到它花了一段时间,但在我的控制器类上有一个@RequestMapping(value=“/users”)注释,必须禁用它。请注意,@RequestMapping的不正确使用显然只会干扰@RequestParam,而不会干扰@RequestBody。下面的代码现在可以工作了(@GetMapping和@deleteMapping在此省略),并给出与问题中给出的@RequestBody完全相同的结果。
@RestController
//@RequestMapping(value="/users")
@CrossOrigin
public class UserController {
@Autowired
private UserServiceImpl userService;
@PostMapping(value = "/users")
public ResponseEntity<Object> createUser(
@RequestParam(name = "email") String email,
@RequestParam(name = "username") String username,
@RequestParam(name = "password") String password
) {
try {
User user = new User();
user.setEmail(email);
user.setUsername(username);
user.setPassword(password);
userService.createUser(user);
return ResponseEntity.noContent().build();
} catch (Exception exception) {
return new ResponseEntity<>(HttpStatus.I_AM_A_TEAPOT);
}
}
这两种方法在功能上是等效的,如果不是在预期用途中。
您不应该在参数值周围使用引号。如果您删除"
,那么它应该可以工作,至少在我将您的代码复制到最近版本的Postman的新Spring Boot项目上可以工作。
邮递员在“设置”选项卡上还有一个选项,可以自动对url进行编码。如果启用该选项,则引号将被编码,并将成为参数值的一部分。默认情况下,它是启用的,但在您的屏幕截图上有一个绿点,表示您更改了某些内容。我猜是您设置了一个导致错误请求的设置(可能是禁用了url编码)。
当我禁用编码我得到这个错误的日志:
java.lang.IllegalArgumentException:
Invalid character found in the request target
[/users?email=bla&username=hello&password="bla" ].
The valid characters are defined in RFC 7230 and RFC 3986
获取刚体组件 TypeScript的代码示例:const rigidBody = this.getComponent(RigidBody); 刚体类型 刚体一般分为三种类型,static,dynamic,kinematic. static,表示静态刚体,犹如质量巨大无比的石头,具体为质量为0的,或者只有碰撞组件的物理元素。 dynamic,表示动力学刚体,能够受到力的作用,具体为质量大于0并且is
流氓和静态刚体 一般当我们创建一个刚体并将它添加到空间上后,空间就开始对之进行模拟,包括了对刚体位置、速度、受力以及重力影响等的模拟。没被添加到空间(没有被模拟)的刚体我们把它称之为流氓刚体。流氓刚体最重要的用途就是用来当作静态刚体,但是你仍然可以使用它来实现如移动平台这样的直接受控物体。 内存管理函数 cpBody *cpBodyAlloc(void) cpBody *cpBodyInit(cp
刚体是组成物理世界的基本对象,可以让一个节点受到物理影响并产生反应。该组件在使用 Builtin 物理引擎时无效。 点击 属性检查器 下方的 添加组件 -> 物理组件 -> Rigid Body 3D,即可添加刚体组件到节点上。 刚体属性 属性 功能说明 Mass 刚体的质量 Linear Damping 线性阻尼,用于减小刚体的线性速率,值越大物体移动越慢 Angular Damping 角阻尼
刚体是组成物理世界的基本对象,你可以将刚体想象成一个你不能看到(绘制)也不能摸到(碰撞)的带有属性的物体。 刚体属性 质量 刚体的质量是通过碰撞组件的 密度 与 大小 自动计算得到的。 当你需要计算物体应该受到多大的力时可能需要使用到这个属性。 var mass = rigidbody.getMass(); 移动速度 // 获取移动速度 var velocity = rigidbody.line
我目前正在做一个三维刚体模拟程序。我目前已经设法使刚体碰撞地板和弹跳正确地利用冲力。然而,我的问题是,一旦他们反弹,他们不断地加速,尽管使用摩擦矢量试图减缓他们。 谢谢 编辑:这里是集成代码。
我有一个模型类和一个控制器。我在post man的正文中发布json类型的数据。但每次我都会收到一个不受支持的媒体类型415错误。这是我的模型课: 我的控制器是: 我已经用HttpServletRequest代替@RequestBody,它起到了作用。但为什么在我使用@RequestBody时它不工作呢? 这是邮递员的快照。这是邮递员请求的图片 这是请求中使用的标题的屏幕截图