我正在尝试将请求体解析为对象(我使用的是Java Spring引导(。
我的控制器是这样的:
public class UserController {
@PutMapping("/lock/{id}")
public Optional<User> lockUser(@PathVariable Long id, @Validated @RequestBody UserLockRequest user) {
return userService.lockUser(id, user);
}
}
我的UserService
看起来像这样:
public Optional<User> lockUser(Long userId, UserLockRequest userLockRequest) {
Optional<User> user = userRepository.findById(userId);
user.get().setLocker(userLockRequest.getLocker());
userRepository.save(user.get());
return user;
}
我的请求类UserLockRequest
看起来像这样:
public class UserLockRequest {
@NotBlank
@NotNull
private Locker locker;
public Locker getLocker() {
return locker;
}
public void setLocker(Locker locker) {
this.locker = locker;
}
}
我的请求是这样的:
curl --location --request PUT 'http://localhost:8081/user/lock/8'
--header 'Content-Type: application/json'
--data-raw '{
"locker_id": "1"
}'
我的User
实体包含locker
字段:
@OneToOne
@JoinColumn(name = "locker_id")
private Locker locker;
我可以看到UserService
中的userLockRequest.getLocker()
总是空的。
我正在尝试将Locker
分配给User
对象并将其保存在数据库中。
我不知道如何将PUT请求中的locker_id
映射到用于接受请求的UserLockRequest
。
非常感谢您的帮助:(
您需要从数据库中获取Locker
并将其分配给User
。为了实现这一点,您需要进行以下几项更改:
public class UserLockRequest {
private long locker_id; // so that it matches your JSON, but it should really be "lockerId" and you should update your JSON
// getter / setter
}
然后,您还需要调整UserService
代码,以便从数据库中获得Locker
:
public Optional<User> lockUser(Long userId, UserLockRequest userLockRequest) {
Optional<User> user = userRepository.findById(userId);
Locker locker = lockerService.getById(userLockRequest.getLockerId());
user.get().setLocker(locker);
userRepository.save(user.get());
return user;
}
我假设你有一个LockerService
,方法返回一个给定ID的Locker
。
最后,避免在不检查Optional
是否为空的情况下使用Optional.get()
,否则,您可能会得到NoSuchElementException
。你可以按照以下路线做一些事情:
public User lockUser(Long userId, UserLockRequest userLockRequest) {
Optional<User> optionalUser = userRepository.findById(userId);
Locker locker = lockerService.getById(userLockRequest.getLockerId());
if (optionalUser.isPresent()) {
User user = optionalUser.get();
user.setLocker(locker);
userRepository.save(user.);
return user;
} else {
// throw some custom exception or just return null, it is your decision
}
}
好吧,我假设
- 您有一个User实体和一个Lock实体,您需要根据用户实体标记Lock实体
- 用户和锁定实体都有JpaRepository接口
- 你的项目中有lombok依赖项
如果这是正确的,下面是我将实现的解决方案。这有助于API设计并分离控制器和服务类之间的责任。
- 定义
UserLockRequest
请求主体类
@Getter
@Setter
public class UserLockRequest{
@NotNull
@NotBlank
private int userId;
@NotNull
@NotBlank
private long lockerId;
}
UserService
类。我使用spring推荐的基于构造函数的注入
@Service
public class UserService {
private final UserRepository userRepository;
private final LockerRepository lockerRepository;
public UserService(UserRepository userRepository, LockerRepository lockerRepository) {
this.userRepository = userRepository;
this.lockerRepository = lockerRepository;
}
public User lockUser(UserLockRequest userLockRequest) {
Optional<User> optionalUser =
userRepository.findById(userLockRequest.getUserId());
Optional<Locker> locker = lockerRepository.findById(userLockRequest.getLockerId());
if (optionalUser.isPresent() && locker.isPresent()) {
User user = optionalUser.get();
user.setLocker(locker.get());
userRepository.save(user);
return user;
} else {
// Error handling is upto you based on what requirement you have
}
}
}
UserController
类
public class UserController {
@PutMapping("/lock")
public Optional<User> lockUser(@Validated @RequestBody UserLockRequest userLockRequest) {
return userService.lockUser(userLockRequest);
}
}
- 下面是http调用的样子
curl --location --request PUT 'http://localhost:8081/user/lock/
--header 'Content-Type: application/json'
--data-raw '{
"user_id": 8,
"locker_id":"1"
}'