4

When I use

<h:outputStylesheet library="css" name="styles.css"> 

or

<h:graphicImage library="images" name="image.jpg">

then in html I get something like this

<link type="text/css" rel="stylesheet" href="/appName/javax.faces.resource/styles.css.xhtml?ln=css" />

so the user can see which framework was used to write this app. How can I avoid showing javax.faces.resource/styles.css.xhtml?ln=css to the user, but also still using facelets(not html, like <link rel=...>)? It will be good when the user simply will see the path to the css file as resources/css/styles.css

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
maks
  • 5,911
  • 17
  • 79
  • 123

2 Answers2

7

That's not directly possible without reimplementing the entire ResourceHandler with help of a ResourceHandlerWrapper as answered by lu4242 on this question, which is not exactly a trivial job. It's a hardcoded public static final field constant in ResourceHandler class, the ResourceHandler#RESOURCE_IDENTIFIER. You may want to post a feature request to make this externally configureable like as has happened for the NamingContainer separator character during the JSF 1.2 to JSF 2.0 step.

But why would you do this? There are a lot of other things which gives enough hints about the framework used. In case of JSF that can be the request URL pattern (/faces/*, *.jsf or *.xhtml), the response headers (X-Powered-By), specific hidden form fields (javax.faces.ViewState), the autogenerated client IDs (by default woodstocked), the JS libraries used (jsf.js), etcetera.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for reply. I have never seen any framework specific fetures in most webapps, just plain html with javascript, so I thought that jsf provide such an opprtunity. Or maybe, I have never seen any JSF webapp on the web. – maks Sep 09 '11 at 07:36
  • 1
    This answer is not true!!!!! the constant is used for the default ResourceHandler, but that does not means you can't use a default ResourceHandlerWrapper over the default one an write a full implementation that uses other different prefix structure. I'll write an answer for this one. – lu4242 Sep 10 '11 at 13:29
  • 1
    @lu4242: Ah right, that can also, didn't thought of it. But was it really needed to throw with those exclamation marks? Did you feel attacked or something? Sorry, that wasn't my intent. – BalusC Sep 10 '11 at 13:32
  • No, no, don't get me wrong ;-) It is just the spec was designed to precisely allow extensible ResourceHandler implementations, like the question is asking. – lu4242 Sep 10 '11 at 13:47
5

This is possible. The code on FacesServlet looks like this:

    ResourceHandler resourceHandler = facesContext.getApplication().getResourceHandler();

    // Call ResourceHandler.isResourceRequest(javax.faces.context.FacesContext).
    if (resourceHandler.isResourceRequest(facesContext))
    {
        // If this returns true call ResourceHandler.handleResourceRequest(javax.faces.context.FacesContext).
        resourceHandler.handleResourceRequest(facesContext);
    }

The default implementation uses ResourceHandler#RESOURCE_IDENTIFIER constant by default, but it is technically possible to write a ResourceHandlerWrapper that uses other structure. The only problem is the wrapper should implement everything, and you can't delegate anything to the default algorithm. You can reuse the code on MyFaces Shared but remember this are internals, so use something like maven shade plugin or a hard copy to relocate the package name.

What is not possible is change it for existing ResourceHandler implementations (for example, components that use a custom ResourceHandler implementation like t:captcha or other variants), because all those are tied to the constant.

Anyway, I created MFCOMMONS-36 to add this to the extended ResourceHandler implementation that is being added on MyFaces Commons.

lu4242
  • 2,318
  • 1
  • 15
  • 15