所以我想实现保存用户的功能
首先我检查用户是否存在
如果存在则抛出异常
否则保存用户
但是当我从服务层抛出异常 .flatMap(user -> Mono.error(new IllegalArgumentException("User Exists with email "+ user.getEmail())))
@Service
@RequiredArgsConstructor
public class AppUserService {
private final AppUserRepository appUserRepository;
public Flux<AppUser> getAllUsers() {
return appUserRepository.findAll();
}
public Mono<AppUser> saveUser(AppUser appUser) {
return getUser(appUser.getEmail())
.flatMap(user -> Mono.error(new IllegalArgumentException("User Exists with email " + user.getEmail())))
.switchIfEmpty(Mono.defer(() -> appUserRepository.save(appUser))).cast(AppUser.class).log();
}
public Mono<AppUser> getUser(String email) {
return appUserRepository.findFirstByEmail(email);
}
}
在 Controller 层,如果我像 .onErrorResume(error -> ServerResponse.badRequest().bodyValue(error)) 那样处理它
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class AppUserController {
private final AppUserService appUserService;
private final PasswordEncoder encoder;
@GetMapping
public Flux<AppUser> getAllUsers(@RequestHeader("email") String email) {
return appUserService.getAllUsers();
}
@PostMapping
@CrossOrigin
public Mono<ResponseEntity<Object>> saveUser(@RequestBody Mono<AppUser> appUserMono) {
return appUserMono
.doOnSuccess(appUser -> appUser.setPassword(encoder.encode(appUser.getPassword())))
.subscribeOn(Schedulers.parallel())
.flatMap(appUserService::saveUser)
.flatMap(savedAppUser -> ResponseEntity.created(URI.create("/user/" + savedAppUser.getId())).build())
.onErrorResume(error -> Response entity.badRequest().bodyValue(error))
.log();
}
}
它在控制台上抛出错误
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.springframework.web.reactive.function.server.DefaultEntityResponseBuilder$DefaultEntityResponse and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
并向客户端返回 200
我做错了什么
阅读错误后,它似乎得到一个空值
但如果我在 onErrorResume(error -> ..)
处调试流程,则错误变量会出现错误
不明白为什么它仍然抛出 jackson 错误
是因为 Jackson 无法订阅 ServerResponse 或相关内容吗
最佳答案
您的代码中存在一些问题。
以下是如何让它运行(没有存储库):
package test;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class AppUser {
private String id;
private String username;
private String firstName;
private String password;
private String email;
}
@Service
@RequiredArgsConstructor
public class AppUserService {
public Mono<AppUser> saveUser(AppUser appUser) {
return getUser(appUser.getEmail())
.flatMap(user -> Mono.<AppUser>error(
new IllegalArgumentException("User Exists with email " + user.getEmail())))
.switchIfEmpty(Mono.defer(() -> Mono.just(AppUser.builder().username("mustafa").build())));
}
public Mono<AppUser> getUser(String email) {
// return Mono.defer(() -> Mono.just(AppUser.builder().email(email).build()));
return Mono.defer(Mono::empty);
}
}
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class AppUserController {
private final AppUserService appUserService;
@PostMapping
@CrossOrigin
public Mono<ResponseEntity<AppUser>> saveUser(@RequestBody Mono<AppUser> appUserMono,
@RequestHeader("email") String email) {
return appUserMono
.subscribeOn(Schedulers.parallel())
.flatMap(appUserService::saveUser)
.flatMap(savedAppUser -> Mono.just(
ResponseEntity.created(URI.create("/user/" + savedAppUser.getId())).body(savedAppUser)))
.onErrorResume(error -> Mono.just(ResponseEntity.badRequest().build()))
.log();
}
}
您的 Controller 的返回类型是 Mono<ResponseEntity<AppUser>>
但你正在返回ServerResponse
。我修复了这个问题并从您的服务代码中删除了强制转换。
您可以通过注释/取消注释 getUser
来尝试生成 400 或有效结果。 body 。
也许编写电子邮件检查逻辑的更清晰方法是使用旧的 if/else 语句:
public Mono<AppUser> saveUser(AppUser appUser) {
if (emailExists(appUser.getEmail())) {
return Mono.error(new IllegalArgumentException("User Exists with email "
+ appUser.getEmail()));
} else {
return Mono.just(AppUser.builder().username("mustafa").build());
}
}
关于java - spring webflux中Controller层错误处理错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69031496/