java - spring webflux中Controller层错误处理错误

标签 java spring-webflux reactor webflux

所以我想实现保存用户的功能 首先我检查用户是否存在 如果存在则抛出异常 否则保存用户 但是当我从服务层抛出异常 .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/

相关文章:

python - 扭曲 - 交互地对函数进行排队

java - 使用 Android 增加 sqlite 数据库中列的值

java - Spring Webflux "works"中的实现,但我试图理解 "why?"

java - WebClient 请求级别超时抛出称为默认 onErrorDropped 的运算符

java - 如何指定 MongoDB 中多个表之间的 @CollectionTable 关系?

扭曲 - 通过 KeyboardInterrupt 中断回调

java - 从字符串中解析有符号数

java - 无法更新 NaturalId 字段值 : An immutable natural identifier of entity {Model} was altered from ABC to XYZ

Java AWT 重量级 Canvas

java - 使用 mongo 响应式(Reactive) Spring 检查 Webflux 数据