以编程方式添加新的约束映射 HV000121:无法解析约束映射文件
Programmatically add new constraint-mappings HV000121: Unable to parse constraint mapping file
正在尝试创建 ValidatorFactory
并以编程方式向配置添加新约束。
想象一下在初始 bootstrap 验证后创建的新 constraint-mappings
文件。
但在下面的单元测试中,由于下面的错误,ValidatorFactory
从未创建。
知道应该如何加载新的约束映射文件吗?
HV000121: Unable to parse constraint mapping file.
javax.validation.ValidationException: HV000121: Unable to parse constraint mapping file.
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:85)
at org.hibernate.validator.internal.xml.mapping.MappingXmlParser.parse(MappingXmlParser.java:107)
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:652)
at java.xml/com.sun.xml.internal.stream.XMLEventReaderImpl.peek(XMLEventReaderImpl.java:277)
at org.hibernate.validator.internal.xml.XmlParserHelper.getRootElement(XmlParserHelper.java:111)
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:80)
测试:
@Test
void test() {
AnotherPojo anotherPojo = new AnotherPojo();
assertNoViolations(anotherPojo);
anotherPojo.setAge(0);
assertExpectedViolation(anotherPojo, JAVAX_DEFAULT_MIN_MSG_TEMPLATE, "age");
anotherPojo.setAge(200);
assertNoViolations(anotherPojo);
// Create path to additional constraint mappings file
String fileName = "constraints-xml-pojo-additional.xml";
File file = new File("src/test/resources");
String absolutePath = file.getAbsolutePath() + "/" + fileName;
InputStream targetStream = new ByteArrayInputStream(absolutePath.getBytes());
// Try create new ValidatorFactory and programmatically add new constraint-mappings
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.addMapping(targetStream) // Passes if this line removed
.buildValidatorFactory(); <---- Error
..
}
目录结构:
.
├── main
│ ├── java
│ │ └── com
│ │ └── org
│ │ └── beanvalidation
│ │ ├── SpringBootApplication.java
│ │ └── model
│ │ └── AnotherPojo.java
│ └── resources
│ └── META-INF
│ ├── validation
│ │ └── constraints-xml-pojo.xml
│ └── validation.xml
└── test
├── java
│ └── com
│ └── org
│ └── beanvalidation
│ └── AnotherPojoTest.java
└── resources
└── constraints-xml-pojo-additional.xml
main/resources/META-INF/validation.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration
http://xmlns.jcp.org/xml/ns/validation/configuration/validation-configuration-2.0.xsd">
<constraint-mapping>META-INF/validation/constraints-xml-pojo.xml</constraint-mapping>
</validation-config>
main/resources/META-INF/validation/constraints-xml-pojo.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
version="2.0">
<default-package>com.org.beanvalidation.model</default-package>
<bean class="AnotherPojo" ignore-annotations="true">
<field name="age">
<constraint annotation="javax.validation.constraints.Min">
<element name="value">1</element>
</constraint>
</field>
</bean>
</constraint-mappings>
test/resources/constraints-xml-pojo-additional.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
version="2.0">
<default-package>com.org.beanvalidation.model</default-package>
<bean class="AnotherPojo" ignore-annotations="true">
<field name="age">
<constraint annotation="javax.validation.constraints.Max">
<element name="value">100</element>
</constraint>
</field>
</bean>
</constraint-mappings>
AnotherPojo.java
:
public class AnotherPojo {
int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
需要将 XML 内容读入 InputStream
。错误地传递了文件名而不是文件内容。
String fileName = "constraints-xml-pojo-additional.xml";
File file = new File("src/test/resources");
String absolutePath = file.getAbsolutePath() + "/" + fileName;
Path d = Path.of(new File(absolutePath).getPath());
String content = Files.readString(d, StandardCharsets.UTF_8);
InputStream targetStreamDynamic = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
Scanner scanner = new Scanner(targetStreamDynamic).useDelimiter("\A");
String result = scanner.hasNext() ? scanner.next() : "";
InputStream inputStream = new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8));
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
Configuration configuration = Validation
.byDefaultProvider()
.configure()
.addMapping(bufferedInputStream);
configuration.buildValidatorFactory().getValidator();
正在尝试创建 ValidatorFactory
并以编程方式向配置添加新约束。
想象一下在初始 bootstrap 验证后创建的新 constraint-mappings
文件。
但在下面的单元测试中,由于下面的错误,ValidatorFactory
从未创建。
知道应该如何加载新的约束映射文件吗?
HV000121: Unable to parse constraint mapping file.
javax.validation.ValidationException: HV000121: Unable to parse constraint mapping file.
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:85)
at org.hibernate.validator.internal.xml.mapping.MappingXmlParser.parse(MappingXmlParser.java:107)
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:652)
at java.xml/com.sun.xml.internal.stream.XMLEventReaderImpl.peek(XMLEventReaderImpl.java:277)
at org.hibernate.validator.internal.xml.XmlParserHelper.getRootElement(XmlParserHelper.java:111)
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:80)
测试:
@Test
void test() {
AnotherPojo anotherPojo = new AnotherPojo();
assertNoViolations(anotherPojo);
anotherPojo.setAge(0);
assertExpectedViolation(anotherPojo, JAVAX_DEFAULT_MIN_MSG_TEMPLATE, "age");
anotherPojo.setAge(200);
assertNoViolations(anotherPojo);
// Create path to additional constraint mappings file
String fileName = "constraints-xml-pojo-additional.xml";
File file = new File("src/test/resources");
String absolutePath = file.getAbsolutePath() + "/" + fileName;
InputStream targetStream = new ByteArrayInputStream(absolutePath.getBytes());
// Try create new ValidatorFactory and programmatically add new constraint-mappings
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.addMapping(targetStream) // Passes if this line removed
.buildValidatorFactory(); <---- Error
..
}
目录结构:
.
├── main
│ ├── java
│ │ └── com
│ │ └── org
│ │ └── beanvalidation
│ │ ├── SpringBootApplication.java
│ │ └── model
│ │ └── AnotherPojo.java
│ └── resources
│ └── META-INF
│ ├── validation
│ │ └── constraints-xml-pojo.xml
│ └── validation.xml
└── test
├── java
│ └── com
│ └── org
│ └── beanvalidation
│ └── AnotherPojoTest.java
└── resources
└── constraints-xml-pojo-additional.xml
main/resources/META-INF/validation.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration
http://xmlns.jcp.org/xml/ns/validation/configuration/validation-configuration-2.0.xsd">
<constraint-mapping>META-INF/validation/constraints-xml-pojo.xml</constraint-mapping>
</validation-config>
main/resources/META-INF/validation/constraints-xml-pojo.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
version="2.0">
<default-package>com.org.beanvalidation.model</default-package>
<bean class="AnotherPojo" ignore-annotations="true">
<field name="age">
<constraint annotation="javax.validation.constraints.Min">
<element name="value">1</element>
</constraint>
</field>
</bean>
</constraint-mappings>
test/resources/constraints-xml-pojo-additional.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="http://xmlns.jcp.org/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/mapping
http://xmlns.jcp.org/xml/ns/validation/mapping/validation-mapping-2.0.xsd"
version="2.0">
<default-package>com.org.beanvalidation.model</default-package>
<bean class="AnotherPojo" ignore-annotations="true">
<field name="age">
<constraint annotation="javax.validation.constraints.Max">
<element name="value">100</element>
</constraint>
</field>
</bean>
</constraint-mappings>
AnotherPojo.java
:
public class AnotherPojo {
int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
需要将 XML 内容读入 InputStream
。错误地传递了文件名而不是文件内容。
String fileName = "constraints-xml-pojo-additional.xml";
File file = new File("src/test/resources");
String absolutePath = file.getAbsolutePath() + "/" + fileName;
Path d = Path.of(new File(absolutePath).getPath());
String content = Files.readString(d, StandardCharsets.UTF_8);
InputStream targetStreamDynamic = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
Scanner scanner = new Scanner(targetStreamDynamic).useDelimiter("\A");
String result = scanner.hasNext() ? scanner.next() : "";
InputStream inputStream = new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8));
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
Configuration configuration = Validation
.byDefaultProvider()
.configure()
.addMapping(bufferedInputStream);
configuration.buildValidatorFactory().getValidator();