javascriptxmlservletsweb-inf

Strange error during XSL/XML load in Javascript


I understand that any resource under WEB-INF is not in public domain and this is by design.
I can access a resource under WEB-INF, say an HTML, by configuring it in web.xml as

   <servlet>
    <servlet-name>resourceId</servlet-name>
    <jsp-file>/WEB-INF/resource.xsl</jsp-file>
  </servlet>

  <servlet-mapping>
    <servlet-name>resourceId</servlet-name>
    <url-pattern>/resource.xsl</url-pattern>
  </servlet-mapping>

But I face a strange situation where, using document creation api on client side i.e document.implementation.createDocument fails shooting a deprecation warning and suggesting XMLHttpRequest instead. I am trying to load and XSL/XML document using this api as follows

xmlFile = document.implementation.createDocument("", "", null);
xmlFile.async = false;
xmlFile.load("resource.xsl");

And I get a warning:

Use of Document.load() is deprecated. To upgrade your code, use the DOM XMLHttpRequest object. For more help https://developer.mozilla.org/en/XMLHttpRequest*

But if I place the resource under WebContent or WebRoot folder directly and remove any web.xml configuration for that, it works smoothly. I do not understand this. I tested this on FF 3.6.5, 5.0.1, 9, 10. Please explain this to me.

I also realize that during failure, i.e when warning shows up due to the resource placed in WEB-INF folder, the browser does succeed in loading despite warning. Firebug shows it. But the XSL or the XML is loaded as text/html and object xmlFile is rather empty and unpopulated. In case of success, I see application/xml in response headers and xmlFile object nicely populated. Please help


Solution

  • But the XSL or the XML is loaded as text/html and object xmlFile is rather empty and unpopulated. In case of success, I see application/xml in response headers and xmlFile object nicely populated.

    Apparently the container doesn't check the mime type when the resource is served from /WEB-INF by a web.xml hack and defaults to text/html. The wrong content type explains all the JavaScript errors you're facing.

    I'd create a wrapper servlet which explicitly sets the content type and forwards to the XSL resource in the doGet() method:

    response.setContentType("application/xml");
    request.getRequestDispatcher("/WEB-INF/resource.xsl").forward(request, response);
    

    Map it as follows instead.

    <servlet>
        <servlet-name>resourceId</servlet-name>
        <servlet-class>com.example.XSLResourceServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>resourceId</servlet-name>
        <url-pattern>/resource.xsl</url-pattern>
    </servlet-mapping>
    

    Make the /WEB-INF/resource.xsl if necessary an <init-param> setting so that you can define and configure it in web.xml instead of hardcoding in the servlet code.