【问题标题】:Micronaut + Thymeleaf Form Validation and Error HandlingMicronaut + Thymeleaf 表单验证和错误处理
【发布时间】:2020-12-09 15:51:24
【问题描述】:

问题:这似乎不起作用。

@Post("/register")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @View("register")
  @Error(exception = ConstraintViolationException.class)
  def register(HttpRequest<?> request, ConstraintViolationException constraintViolationException) {
    Optional<RegisterFormData> registerFormDataOptional = request.getBody(RegisterFormData.class)
    Map<String, Object> map = new HashMap<>()
    if(registerFormDataOptional.isPresent()){
      RegisterRequest registerRequest =  new RegisterRequest(registerFormDataOptional.get().properties)
      registerRequest.returnSecureToken = true
      try {
        def registerResponse = firebaseClient.register(registerRequest, this.firebaseApiKey).blockingSingle()
        SendEmailVerificationRequest sendEmailVerificationRequest = new SendEmailVerificationRequest()
        sendEmailVerificationRequest.requestType = 'VERIFY_EMAIL'
        sendEmailVerificationRequest.idToken = registerResponse.idToken
        firebaseClient.sendEmailVerification(sendEmailVerificationRequest, this.firebaseApiKey)
        HttpResponse.redirect(URI.create('/register-success'))
      }catch(HttpClientResponseException ex){
        map.put('errors', [ex.message])
        return map
      }
    }else{
      map.put('errors', violationMessageSource.violationsMessages(constraintViolationException.constraintViolations))
      return map
    }
  }

给我一​​个

{"message":"Required argument [ConstraintViolationException constraintViolationException] not specified","path":"/constraintViolationException","_links":{"self":{"href":"/auth/register","templated":false}}}

目前正在使用 Micronaut 和 Thymeleaf。有人知道我还缺少什么吗?我正在关注https://guides.micronaut.io/micronaut-error-handling/guide/index.html中的示例

这里的重点是在发生约束冲突时将一些错误消息从控制器传递回 UI。使用注解 @Body 和 @Valid 的默认值不起作用,因为它返回没有任何视图的 json 错误。

【问题讨论】:

    标签: groovy micronaut


    【解决方案1】:
    @Inject
    Validator validator
    
    @Inject
    ViolationMessageSource violationMessageSource
    
    
    @Post("/register")
      @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
      def register(HttpRequest<?> request, @Body RegisterFormData registerFormData) {
        //validate registerformdata object
        Map<String, Object> map = new HashMap<>()
        Set<ConstraintViolation<RegisterFormData>> violations = validator.validate(registerFormData)
        if (violations.size() > 0) {
          map.put('registerFormData', registerFormData)
          map.put('errors', violationMessageSource.violationsMessages(violations))
          HttpResponse.redirect(URI.create('/register')).body(map)
        } else {
          RegisterRequest registerRequest = new RegisterRequest(registerFormData.properties)
          registerRequest.returnSecureToken = true
          try {
            def registerResponse = firebaseClient.register(registerRequest, this.firebaseApiKey).blockingSingle()
            SendEmailVerificationRequest sendEmailVerificationRequest = new SendEmailVerificationRequest()
            sendEmailVerificationRequest.requestType = 'VERIFY_EMAIL'
            sendEmailVerificationRequest.idToken = registerResponse.idToken
            firebaseClient.sendEmailVerification(sendEmailVerificationRequest, this.firebaseApiKey)
            HttpResponse.redirect(URI.create('/register-success'))
          } catch (HttpClientResponseException ex) {
            map.put('errors', [ex.message])
            HttpResponse.redirect(URI.create('/register')).body(map)
          }
        }
      }
    

    我在 Micronaut 中注入了一个验证器 bean,就像这样

    @Factory
    class ValidatorConfig {
    
      Validator validator
    
      @PostConstruct
      void initialize(){
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory()
        validator = factory.getValidator()
      }
    
      @Bean
      Validator getValidator(){
        return validator
      }
    }
    

    我的消息来源也是这样

    @Singleton
    public class ViolationMessageSource {
    
        public List<String> violationsMessages(Set<ConstraintViolation<?>> violations) {
            return violations.stream()
                    .map(ViolationMessageSource::violationMessage)
                    .collect(Collectors.toList());
        }
    
        private static String violationMessage(ConstraintViolation violation) {
            StringBuilder sb = new StringBuilder();
            Path.Node lastNode = lastNode(violation.getPropertyPath());
            if (lastNode != null) {
                sb.append(lastNode.getName());
                sb.append(" ");
            }
            sb.append(violation.getMessage());
            return sb.toString();
        }
    
        private static Path.Node lastNode(Path path) {
            Path.Node lastNode = null;
            for (final Path.Node node : path) {
                lastNode = node;
            }
            return lastNode;
        }
    }
    

    答案基于 javax 验证 https://www.baeldung.com/javax-validation 和 micronaut 中的错误处理 https://guides.micronaut.io/micronaut-error-handling/guide/index.html 的基础知识

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 1970-01-01
      • 2020-06-09
      • 2011-10-31
      • 2020-11-18
      相关资源
      最近更新 更多