RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1586861
Accepted
XelaNimed
XelaNimed
Asked:2024-07-11 19:20:46 +0000 UTC2024-07-11 19:20:46 +0000 UTC 2024-07-11 19:20:46 +0000 UTC

以编程方式为基本类型创建值验证器

  • 772

我需要根据动态定义的约束和规则检查各种基元类型及其集合的值。这对于检查/监控一组 CNC 机器的返回值是必要的,根据机器/订单/时间/员工/月相等,这些机器可能有不同的可接受值范围。检查还用于确定后续事件生成是否超出关键指标的阈值。
不幸的是,由于无法克服的情况,在数据库中保存值的选项是不可接受的,因此,目前正在考虑以下选项......

选项一:你自己的“自行车”

编写你自己的“自行车”,希望你有足够的资历和经验来开发一个好的库。


选项 2:实施 Bean 验证 API

与第一种选择一样,唯一的区别是“自行车”将根据一定的规则建造,这将有助于避免方形轮子,但使用/可靠性/维护仍然存在问题。


选项 3:Hibernate 验证器

使用 Bean Validation API(Hibernate Validator),可以动态创建规则。用法示例如下:

<!-- Maven dependencies -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.13.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.valueextraction.ExtractedValue;
import javax.validation.valueextraction.ValueExtractor;

import org.hibernate.validator.cfg.defs.*;

public class App
{
    public static void main( final String[] args )
    {
        try ( ValidatorFactory factory = Validation
                .byProvider( HibernateValidator.class )
                .configure()
                .addMapping( buildPrimitiveConstraintMapping() )
                .addValueExtractor( new IntegerValueExtractor() )
                .addValueExtractor( new StringValueExtractor() )
                .messageInterpolator( new ParameterMessageInterpolator() )
                .buildValidatorFactory() )
        {
            Validator validator = factory.getValidator();

            validator.validate( 7 )
                .stream()
                .map( ConstraintViolation::getMessage )
                .forEach( System.out::println );
            
            validator.validate( "" )
                .stream()
                .map( ConstraintViolation::getMessage )
                .forEach( System.out::println );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }

    private static ConstraintMapping buildPrimitiveConstraintMapping()
    {
        ConstraintMapping mapping = new DefaultConstraintMapping();

        mapping
            .type( Integer.class )
            .constraint( new NotNullDef() )
            .constraint( new MinDef().value( 18 ) )
            .constraint( new MaxDef().value( 50 ) );

        mapping
            .type( String.class )
            .constraint( new NotNullDef() )
            .constraint( new NotBlankDef() );

        return mapping;
    }

    // Value extractor for Integer
    public static class IntegerValueExtractor
            implements
            ValueExtractor<@ExtractedValue(type = Integer.class) Integer>
    {
        @Override
        public void extractValues(
            Integer originalValue,
            ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }

    // Value extractor for String
    public static class StringValueExtractor
            implements
            ValueExtractor<@ExtractedValue(type = String.class) String>
    {
        @Override
        public void extractValues(
            String originalValue,
            ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }

}

习惯上如何“根据风水”解决此类问题?所选库对于解决任务/问题是否多余?

java
  • 1 1 个回答
  • 28 Views

1 个回答

  • Voted
  1. Best Answer
    XelaNimed
    2024-07-18T19:55:33Z2024-07-18T19:55:33Z

    我不知道这是对还是错,但我是这样决定的:

    try (ValidatorFactory factory = Validation.byProvider( HibernateValidator.class )
                                    .configure()
                                    .addMapping( buildPrimitiveConstraintMapping() )
                                    .addValueExtractor( new IntegerValueExtractor() )
                                    .addValueExtractor( new StringValueExtractor() )
                                    .messageInterpolator( new CustomMessageInterpolator() )
                                    .buildValidatorFactory())
    {
        Validator validator = factory.getValidator();
    
        validator
            .validate( 7 ).stream()
            .map( ConstraintViolation::getMessage )
            .forEach( System.out::println );
        validator
            .validate( "" ).stream()
            .map( ConstraintViolation::getMessage )
            .forEach( System.out::println );
    }
    catch( Exception e )
    {
        e.printStackTrace();
    }
    
    private static ConstraintMapping buildPrimitiveConstraintMapping()
    {
        ConstraintMapping mapping = new DefaultConstraintMapping();
    
        mapping
            .type( Integer.class )
            .constraint( new NotNullDef() )
            .constraint( new MinDef().value( 18 ) )
            .constraint( new MaxDef().value( 50 )
                    .message( "The value {validatedValue} must not be greater than {value}" ) );
    
        mapping
            .type( String.class )
            .constraint( new NotNullDef() )
            .constraint( new NotBlankDef().message( "Value can't be null" ) );
    
        return mapping;
    }
    
    public static class IntegerValueExtractor implements ValueExtractor<@ExtractedValue(type = Integer.class) Integer>
    {
        @Override public void extractValues( Integer originalValue, ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }
    
    public static class StringValueExtractor implements ValueExtractor<@ExtractedValue(type = String.class) String>
    {
        @Override public void extractValues( String originalValue, ValueReceiver receiver )
        {
            receiver.value( null, originalValue );
        }
    }
    

    CustomMessageInterpolator 类与手头的任务没有直接关系,您可以继续使用 ParameterMessageInterpolator,如问题代码所示,但在这种情况下,将无法{validatedValue}在错误消息中使用(很可能是因为许多不使用 HibernateValidator 依赖项):

    import java.util.Locale;
    import java.lang.invoke.MethodHandles;
    
    import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm;
    import org.hibernate.validator.internal.engine.messageinterpolation.ParameterTermResolver;
    import org.hibernate.validator.internal.util.logging.Log;
    import org.hibernate.validator.internal.util.logging.LoggerFactory;
    import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator;
    
    public class CustomMessageInterpolator extends AbstractMessageInterpolator
    {
    
        private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
    
        @Override public String interpolate( Context context, Locale locale, String term )
        {
            if ( "{validatedValue}".equals( term ) )
            {
                return String.valueOf( context.getValidatedValue() );
            }
            else if ( InterpolationTerm.isElExpression( term ) )
            {
                LOG.warnElIsUnsupported( term );
                return term;
            }
    
            ParameterTermResolver parameterTermResolver = new ParameterTermResolver();
            return parameterTermResolver.interpolate( context, term );
        }
    
    }
    
    • 0

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5