使用Spring控制器和Spring webflow中的可选属性进行一致的JSR-303验证?

时间:2013-10-26 17:37:57

标签: spring-mvc spring-webflow bean-validation

假设我有一个Model Bean“Vendor”,其强制属性为“name”,可选属性为“email”。

class Vendor {

    @Email
    private String email;

    @NotNull
    private String name;

}

@Email允许Null!

我想在我的@Controller和我的流程中使用hibernate验证。我在这两种情况下都有一个问题,即带有空字段的电子邮件的发布表单与“”绑定而不是NULL。

StringTrimmerEditor似乎通过将“”转换为NULL来解决我的问题。对于我的@Controller,我发现SPR-7077建议StringTrimmerEditor全局实施@ControllerAdvice。但这对我的流量不起作用。

如何实现全局空字符串(“”)在spring webflow中转换为NULL以进行JSR-303验证?

2 个答案:

答案 0 :(得分:1)

我似乎找到了一个支持空字符串的Null值的配置。对于我的@Controller,我坚持StringTrimmerEditor中的@ControllerAdvice。这里没什么新鲜的。

对于SWF ConversionService似乎可以解决问题:首先我创建一个{“1}},将”转换为Null:

Converter

现在我必须在Spring注册:

public class StringToNullConverter implements Converter<String, String> {

    @Override
    public String convert(String source) {
        if (StringUtils.isEmpty(source)) {
            return null;

        }
        return source;
    }

}

到目前为止,没有任何新的事情发生,我们正在讨论import org.springframework.core.convert.*; @Configuration public class SpringConfiguration { @Bean public ConversionService conversionService() { DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); conversionService.addConverter(new StringToNullConverter()); return conversionService; } } 包。现在,SWF粘合到org.springframework.core.convert包中:

org.springframework.binding.convert

将其连接到SWF中     import org.springframework.binding.convert.*; @Bean public ConversionService flowConversionService(org.springframework.core.convert.ConversionService conversionService) { DefaultConversionService service = new DefaultConversionService(conversionService); return service; }

这看起来有点太多了,但它确实起了作用。我确信必须有更好的方法,因为我有两个不同的实现(<webflow:flow-builder-services [..] conversion-service="flowConversionService" />StringTrimmerEditor)来实现同样的目的。对我而言,StringToNullConverter看起来似乎是唯一的出路。但是我没有弄清楚如何为Spring ConversionService完成它。

答案 1 :(得分:0)

如果要使用可选字段,可以创建包含@ConstraintComposition的注释。 例如:

import org.hibernate.validator.constraints.ConstraintComposition;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
@ConstraintComposition
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented

@NotBlank
@Length(min = 1, max = 5)
@Pattern(regexp = "[A-Z]*")
public @interface SpecialField {
    String message() default "{}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

@ConstraintComposition(OR)
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented

@Null
@SpecialField
public @interface OptionalSpecialField {

    String message() default "{}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

之后,标记可选提交:

class NewUser {

    @OptionalSpecialField
    private String firstName;

    @SpecialField
    private String lastName;

    @Min(18)
    private Integer age;
}

不需要名字,但如果不是null,则必须不是空白,匹配模式等

所有示例都在这里:https://github.com/lukaszguz/optional-field-validation/tree/master/src/main/java/pl/guz/domain/validation