Spring Boot 2.6.10添加validation依赖后XSD HTTP访问受限问题
解决方案:Spring Boot 2.6.10 XSD校验HTTP访问受限问题
问题根源
引入spring-boot-starter-validation依赖后,Spring的XmlValidatorFactory在创建SchemaFactory时,并未正确继承或读取你设置的javax.xml.accessExternalSchema系统属性,导致HTTP方式加载XSD的权限限制依然生效。
有效解决方案
放弃使用XmlValidatorFactory,直接手动创建并配置SchemaFactory实例,显式设置外部访问权限属性。修改后的校验代码如下:
import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; public class XsdValidator { /** * Constructor. */ private XsdValidator() { // not used } /** * Validates the given XML against XSD schema referenced as URL resource. * * @param xml XML * @param xsdUrl XSD URL * @return list of validation exceptions, if there are any * @throws IOException in case of I/O error - reading URL resource * @throws SAXException in case of XML/SAX parsing error */ public static SAXParseException[] validateXml(String xml, String xsdUrl) throws IOException, SAXException { // 手动创建SchemaFactory并设置外部访问权限 SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "all"); schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "all"); // 加载远程XSD Schema URL xsdResourceUrl = new URL(xsdUrl); Schema schema = schemaFactory.newSchema(xsdResourceUrl); // 创建Validator并绑定错误处理器 Validator validator = schema.newValidator(); List<SAXParseException> validationExceptions = new ArrayList<>(); validator.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) { validationExceptions.add(exception); } @Override public void error(SAXParseException exception) { validationExceptions.add(exception); } @Override public void fatalError(SAXParseException exception) { validationExceptions.add(exception); } }); // 执行XML校验 validator.validate(new StreamSource(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)))); return validationExceptions.toArray(new SAXParseException[0]); } }
为什么之前的方法无效?
- 系统属性设置时机问题:
System.setProperty可能在SchemaFactory实例创建之后执行,而JAXP的SchemaFactory实例一旦创建,不会再读取后续修改的系统属性。 - Spring封装的限制:
XmlValidatorFactory内部创建SchemaFactory时,可能未传递或覆盖了你设置的系统属性,导致权限限制依然被应用。 - JAXP属性优先级:直接设置
SchemaFactory实例的属性,优先级高于系统属性和jaxp.properties配置,能确保权限设置生效。
内容的提问来源于stack exchange,提问作者mflame
相关产品推荐
相关产品推荐

