在Java Spring引导中将请求主体数据解析为对象



我正在尝试将请求体解析为对象(我使用的是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
}
}

好吧,我假设

  1. 您有一个User实体和一个Lock实体,您需要根据用户实体标记Lock实体
  2. 用户和锁定实体都有JpaRepository接口
  3. 你的项目中有lombok依赖项

如果这是正确的,下面是我将实现的解决方案。这有助于API设计并分离控制器和服务类之间的责任。

  1. 定义UserLockRequest请求主体类
@Getter
@Setter
public class UserLockRequest{

@NotNull
@NotBlank
private int userId;
@NotNull 
@NotBlank
private long lockerId;
}
  1. 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
}
}
}
  1. UserController
public class UserController {
@PutMapping("/lock")
public Optional<User> lockUser(@Validated @RequestBody UserLockRequest userLockRequest) {
return userService.lockUser(userLockRequest);
}
}
  1. 下面是http调用的样子
curl --location --request PUT 'http://localhost:8081/user/lock/ 
--header 'Content-Type: application/json' 
--data-raw '{
"user_id": 8,
"locker_id":"1"
}'

最新更新