You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BeanIO中record级别minLength校验失效问题求助

BeanIO minLength校验失效问题排查与解决

问题描述

配置BeanIO映射文件处理分隔符文件时,required校验可正常生效,但minLength校验失效。例如输入中Gregory记录的salary字段为空时,未触发minLength="1"的错误提示。

映射文件配置

<record name="detail" minOccurs="0" maxOccurs="unbounded"
   class="com.test.Person">
   <field name="firstName"/>
   <field name="surname"/>
   <field name="salary" minLength="1"/>
   <field name="age" required="true"/>
</record>

输入内容

John|Smith|300000.00|34
Peter|William|800000.00|
Gregory|Rocky||30

输出结果

[Person [firstName=John, surname=Smith, salary=300000.0, age=34], Person [firstName=Gregory, surname=Rocky, salary=0.0, age=30]]
Errors:
3 : age : [Required field not set]

Java代码

public void readCSVFileUsingBeanIo() throws FileNotFoundException {
        StreamFactory factory = StreamFactory.newInstance();
        factory.loadResource("person.xml");
        StringBuilder rejects = new StringBuilder();

        // 从类路径读取文件:src/main/resources
        InputStream in = new FileInputStream(new File(
                "person.csv"));
        BeanReader reader = factory.createReader("persons", new InputStreamReader(in));
        reader.setErrorHandler(new BeanReaderErrorHandlerSupport() {
            public void invalidRecord(InvalidRecordException ex) throws Exception {
                for (int i = 0, j = ex.getRecordCount(); i < j; i++) {
                    final int ii = i;
                    if (ex.getRecordContext(i).hasErrors()) {

                        ex.getRecordContext(i).getFieldErrors().keySet().stream().forEach(key -> {
                            rejects.append("\n");
                            rejects.append(ex.getRecordContext(ii).getLineNumber() + " : ");
                            rejects.append(ex.getRecordContext(ii).getRecordText() + " Field(" + key + ") : Error "
                                    + ex.getRecordContext(ii).getFieldErrors(key));
                            
                        });
                        rejects.append("\n");
                    }
                }
            }
        });
        Object record = null;
        List<Person> persons = new ArrayList<>();

        while ((record = reader.read()) != null) {
            if ("header".equals(reader.getRecordName())) {

                @SuppressWarnings("unchecked")
                Map<String, Object> header = (Map<String, Object>) record;
                System.out.println(header.get("fileDate"));
            } else if ("detail".equals(reader.getRecordName())) {
                Person person = (Person) record;
                persons.add(person);
            }
        }

        System.out.println(persons);
        System.out.println("Errors:");
        System.out.println(rejects);
    }

原因分析

BeanIO中minLength校验仅针对字符串类型字段的原始输入文本长度生效。当字段为数值类型(如salary对应Java类中的double类型)时,空字符串输入会被自动转换为该数值类型的默认值(double默认值为0.0),此时minLength校验不会触发——因为数值类型不存在"长度"属性,BeanIO不会对其应用文本长度校验规则。

解决方案

方案1:添加required校验(推荐,适用于不允许salary为空的场景)

直接给salary字段添加required="true"属性,强制校验字段不能为空,与age字段的校验逻辑一致:

<field name="salary" minLength="1" required="true"/>

此时空的salary输入会触发必填错误,符合业务预期。

方案2:将字段类型改为字符串(适用于需要校验输入文本长度的场景)

如果需要严格校验输入的文本长度(例如确保输入至少有1个字符),将salary字段的类型设为字符串,后续在Java代码中自行处理数值转换:

<field name="salary" type="java.lang.String" minLength="1"/>

对应的Java类中salary字段改为String类型,之后可通过Double.parseDouble()等方式转换为数值,空字符串输入会直接触发minLength校验错误。

方案3:自定义类型处理器(适用于复杂校验场景)

实现自定义TypeHandler,在解析空字符串输入时抛出异常,结合minLength校验实现自定义逻辑:

public class CustomDoubleTypeHandler extends AbstractTypeHandler {
    @Override
    public Object parse(String text) throws TypeConversionException {
        if (text == null || text.trim().isEmpty()) {
            throw new TypeConversionException("Salary cannot be empty");
        }
        try {
            return Double.parseDouble(text);
        } catch (NumberFormatException e) {
            throw new TypeConversionException("Invalid salary format");
        }
    }

    @Override
    public String format(Object value) {
        return value != null ? value.toString() : "";
    }
}

然后在映射文件中配置使用该处理器:

<field name="salary" typeHandler="com.test.CustomDoubleTypeHandler" minLength="1"/>

内容的提问来源于stack exchange,提问作者Jericho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:01:18