返回介绍

2.6.2 验证模式的读取

发布于 2025-04-22 22:09:07 字数 3546 浏览 0 评论 0 收藏

了解了 DTD 与 XSD 的区别后我们再去分析 Spring 中对于验证模式的提取就更容易理解了。通过之前的分析我们锁定了 Spring 通过 getValidationModeForResource 方法来获取对应资源的的验证模式。

protected int getValidationModeForResource(Resource resource) {

  int validationModeToUse = getValidationMode();

 //如果手动指定了验证模式则使用指定的验证模式

  if (validationModeToUse != VALIDATION_AUTO) {

   return validationModeToUse;

 }

 //如果未指定则使用自动检测

  int detectedMode = detectValidationMode(resource);

  if (detectedMode != VALIDATION_AUTO) {

   return detectedMode;

 }

  return VALIDATION_XSD;

}

方法的实现其实还是很简单的,无非是如果设定了验证模式则使用设定的验证模式(可以通过对调用 XmlBeanDefinitionReader 中的 setValidationMode 方法进行设定),否则使用自动检测的方式。而自动检测验证模式的功能是在函数 detectValidationMode 方法中实现的,在 detectValidationMode 函数中又将自动检测验证模式的工作委托给了专门处理类 XmlValidationMode Detector,调用了 XmlValidationModeDetector 的 validationModeDetector 方法,具体代码如下:

protected int detectValidationMode(Resource resource) {

  if (resource.isOpen()) {

   throw new BeanDefinitionStoreException(

   "Passed-in Resource [" + resource + "] contains an open stream: " +

   "cannot determine validation mode automatically. Either pass in

   a Resource " +

   "that is able to create fresh streams, or explicitly specify the

   validationMode " +

   "on your XmlBeanDefinitionReader instance.");

 }

  InputStream inputStream;

  try {

   inputStream = resource.getInputStream();

 }

  catch (IOException ex) {

   throw new BeanDefinitionStoreException(

   "Unable to determine validation mode for [" + resource + "]: cannot

   open InputStream. " +

   "Did you attempt to load directly from a SAX InputSource without

   specifying the " +

   "validationMode on your XmlBeanDefinitionReader instance?", ex);

 }

  try {

   return this.validationModeDetector.detectValidationMode(inputStream);

 }

  catch (IOException ex) {

   throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +

   resource + "]: an error occurred whilst reading from the

   InputStream.", ex);

 }

}

XmlValidationModeDetector.java

public int detectValidationMode(InputStream inputStream) throws IOException {

  BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

  try {

   boolean isDtdValidated = false;

   String content;

   while ((content = reader.readLine()) != null) {

    content = consumeCommentTokens(content);

   //如果读取的行是空或者是注释则略过

    if (this.inComment || !StringUtils.hasText(content)) {

    continue;

   }

    if (hasDoctype(content)) {

     isDtdValidated = true;

    break;

   }

   //读取到<开始符号,验证模式一定会在开始符号之前

    if (hasOpeningTag(content)) {

    break;

   }

  }

   return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);

 }

  catch (CharConversionException ex) {

   // Choked on some character encoding...

   // Leave the decision up to the caller.

   return VALIDATION_AUTO;

 }

  finally {

  reader.close();

 }

}

private boolean hasDoctype(String content) {

  return (content.indexOf(DOCTYPE) > -1);

}

只要我们理解了 XSD 与 DTD 的使用方法,理解上面的代码应该不会太难,Spring 用来检测验证模式的办法就是判断是否包含 DOCTYPE,如果包含就是 DTD,否则就是 XSD。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。