2010-06-18 9 views
7

Estoy usando la biblioteca de Apache web service xml rpc para realizar solicitudes a un servicio rpc. En algún lugar de ese proceso hay un documento xml con una referencia DTD al http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd, que la biblioteca intenta descargar al analizar el XML. Esa descarga falla con un código de estado 503 porque el w3c está bloqueando las descargas repetidas de este documento en gran medida estático de los clientes de Java.Uso de un catálogo XML con una biblioteca Java que utiliza JAXP internamente

La solución es XML Catalogs para almacenar en caché localmente la DTD. Sin embargo, aunque puedo encontrar ejemplos de cómo configurar EntityHandler en una instancia de JAXP SAXParser directamente para habilitar el soporte del analizador de catálogos, en realidad no tengo acceso al analizador subyacente aquí. Simplemente está siendo utilizado por la biblioteca xml rpc. ¿Hay alguna manera de establecer una propiedad global o algo que le diga a JAXP que use catálogos XML?

Respuesta

1

Creo que desea la propiedad del sistema xml.catalog.files.

Tome un vistazo a http://xml.apache.org/commons/components/resolver/resolver-article.html

Por cierto, este fue el tercer golpe en una búsqueda en Google de jaxp catalog

+0

que había visto ese artículo y que ya ha intentado integrar xml-resolver en mi proyecto. El problema es que la propiedad del sistema xml.catalog.files solo tiene efecto una vez que haya instalado XML Resolver como resolución de entidad en su instancia de lector JAXP. Mi problema es que no tengo acceso a la instancia del lector JAXP utilizada internamente por la biblioteca del servicio web. –

+0

Si configura esa propiedad en la línea de comando al iniciar el programa, ¿no es "vista" por la fábrica del analizador? –

1

Desafortunadamente, el establecimiento de xml.catalog.files no tiene ningún efecto sobre la fábrica analizador. Idealmente debería, por supuesto, pero la única forma de usar un resolver es agregar de alguna manera un método que delegue la resolución al sistema de resolución de catálogos en el controlador que usa el analizador SAX.

Si ya está utilizando un analizador SAX, eso es bastante fácil:

final CatalogResolver catalogResolver = new CatalogResolver(); 
    DefaultHandler handler = new DefaultHandler() { 
     public InputSource resolveEntity (String publicId, String systemId) { 
      return catalogResolver.resolveEntity(publicId, systemId); 
     } 
     public void startElement(String namespaceURI, String lname, String qname, 
      Attributes attrs) { 
      // the stuff you'd normally do 
     } 
     ... 
    }; 

    SAXParserFactory factory = SAXParserFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    SAXParser saxParser = factory.newSAXParser(); 
    String url = args.length == 0 ? "http://horstmann.com/index.html" : args[0]; 
    saxParser.parse(new URL(url).openStream(), handler); 

De lo contrario, tendrá que averiguar si usted puede proporcionar su propio resolvedor de entidades. Con un javax.xml.parsers.DocumentBuilder, puede. Con el objeto scala.xml.XML, no se puede, pero puede utilizar subterfugios:

val res = new com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver 

val loader = new factory.XMLLoader[Elem] { 
    override def adapter = new parsing.NoBindingFactoryAdapter() { 
    override def resolveEntity(publicId: String, systemId: String) = { 
     res.resolveEntity(publicId, systemId) 
    } 
    } 
} 

val doc = loader.load(new URL("http://horstmann.com/index.html"))enter code here 
Cuestiones relacionadas