Changing JSF prefix to suffix mapping forces me to reapply the mapping on CSS background images
Asked Answered
V

1

14

I've been using prefix mapping for years and decided to switch to suffix mapping, just to get rid of the /faces in the url really. I just wanted to check I'm going in the right direction before I dig myself a hole as there are a few unexpected things going on. I changed from this:

<servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

to this:

<servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

And then I see that everything going through FacesServlet has .xhtml appended to it, so that the browser is requesting background.png.xhtml files, style.css.xhtml file - is this right? It is called suffix mapping I suppose, but it looks a bit untidy to me and I'm trying to convince myself it's the way to go.

In my CSS files where an URI is referenced I also have to append .xhtml:

background-image: url(images/background.png.xhtml);

Then I saw a post from BalusC that gives a solution to prevent the download of resources without going via FacesServlet:

<security-constraint>
    <display-name>Restrict raw XHTML docs</display-name>
    <web-resource-collection>
        <web-resource-name>XHTML</web-resource-name>
        <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>

When I add this then only real .xhtml files load on the page, all other resources (despite having .xhtml appended) do not display.

All I want to know is:

  1. Is this appending .xhtml to everything normal (sorry if the years silliest question)

  2. Why does the 'restrict raw xhtml docs' security constraint prevent resource such as CSS, JavaScript and images from loading?

Thanks for any feedback. I am using Mojarra 2.1.2 on Glassfish 3.1.

Vibes answered 26/7, 2011 at 19:35 Comment(0)
P
18

and then I see that everything going through FacesServlet has .xhtml appended to it, so that the browser is requesting .png.xhtml files, .css.xhtml file - is this right?

This only applies to resources included by <h:outputStylesheet> and <h:outputScript>. This is not related to the change in the URL mapping. This is related to the change from JSF 1.x to JSF 2.x and the change from <link rel="stylesheet"> and <script> to the aforementioned JSF2 tags.

For your own scripts, stylesheets and other static stuff which is to be served from the public webcontent, you should not manually add the .xhtml extension. You should not need to change anything with regard to existing static resources.

Only for CSS background images and other url() references in CSS files which is to be included using the <h:outputStylesheet> tag (and thus not for <link rel="stylesheet>), you would need to change the url() location to be dynamically resolved by EL. You would need to use the following syntax instead:

body {
    background-image: url("#{resource['libraryname:path/to/image.png']}");
}

Imagine that you have the following /resources folder structure:

WebContent
 |-- META-INF
 |-- resources
 |    `-- default
 |         |-- images
 |         |    `-- background.png
 |         `-- css
 |              `-- style.css
 |-- WEB-INF
 `-- test.xhtml

and that you're including the style.css in test.xhtml as follows

<h:outputStylesheet library="default" name="css/style.css" />

then you should be defining the background image URL as follows

body {
    background-image: url("#{resource['default:images/background.png']}");
}

Or when you're relying on the default library, thus you aren't using the library, then it should rather look like this:

WebContent
 |-- META-INF
 |-- resources
 |    |-- images
 |    |    `-- background.png
 |    `-- css
 |         `-- style.css
 |-- WEB-INF
 `-- test.xhtml

test.xhtml:

<h:outputStylesheet name="css/style.css" />

style.css:

body {
    background-image: url("#{resource['images/background.png']}");
}

As to the securiry constraint, it is not needed when you're already using the *.xhtml mapping. The security constraint is intended to prevent the enduser from seeing the raw XHTML source code when the FacesServlet is mapped on a pattern other then *.xhtml. The enduser would be able to see the XHTML source code by just removing /faces part from the URL in case of a /faces/* mapping or renaming .jsf to .xhtml in case of a *.jsf mapping. Get rid of the security constraint, it makes in your case things worse as you're already using a *.xhtml mapping which makes it already impossible to see the raw XHTML source code by hacking the URL.

Pleione answered 26/7, 2011 at 19:50 Comment(18)
Thanks for that. The final point I don't understand is why I'm having to append .xhtml in my background-image: url properties. I use a ResourceManager which appends a build version number for cache refresh purposes, but I don't see how this is a factor (in fact I notice that the version number is NOT appended for resources requested from the css file). I would like to nail this final point and then I'll be happy. The css is loaded from a template in root with h:outputStylesheet library="css" name="styleSheet.css". So what config issues causes me to have to append the suffix? Thanks.Vibes
I should clarify that everything is going through with a .xhtml suffix including my own files, i.e. login.xhtml.xhtml...Vibes
I create a template NetBeans JSF project, configure *.xhtml suffix mapping, in the index.xhtml have the line <h:outputStylesheet name="styles.css"/>, and then I see the browser requesting styles.css.xhtml. No filter, no resource managers, no container security, that just seems to be the way it works. I work with JSF 7 days a week, yet totally unable to get even the simplest application working with *.faces suffix. Correction to previous comment, not getting login.xhtml.xhtml, just login.xhtml, but all non .xhtml (js, css etc.) has .xhtml appended.Vibes
With .xhtml it works, with the slight inconvenience of having to add .xhtml to url() references in stylesheets. Verified with a 10 line NetBeans generated web project with <h:outputStylesheet name="styles.css"/>. Using chrome dev tools (& NB http monitor) I clearly see a GET for styles.css.xhtml. I'm just concerned that this is hiding a more serious mis-configuration, if you're surprised at this I must be doing something wrong. Could it be a glassfish configuration issue I wonder... I must check the domain.xml.Vibes
My final comment on the matter: the issue of styles.css.xhtml only occurs if you load with h:outputStylesheet, not with <link type="text/css" rel="stylesheet" href="..."/>. I have logged this java.net/jira/browse/JAVASERVERFACES-2153Vibes
Ah right, now I finally understand your issue. When you include CSS by <h:outputStylesheet> instead of <link>, you would need to change the URLs of all referenced CSS background images as well to match the FacesServlet's URL pattern to get them loaded. This is regardless of whether you used a prefix or suffix mapping! Please check the updated answer.Pleione
I got the same problem and BalusC answer didn't help me much, because it is not only my own resources that are unproperly suffixed but also RichFaces ones. There don't seem to get a way to prevent JSF to suffix resources with .xhtml with suffix mapping.Garratt
@PomCompot - Hi, did you ever resolve this problem? I'm just coming back to look at this again, after all this time, and just wondered if you'd got anywhere with it. Thanks.Vibes
He is just not clear about the concrete problem so I ignored him. He namely seems to imply that JSF should not suffix the resources, but this is untrue as stated in my answer. If he has a concrete problem with it, he should have posted a separate question for it.Pleione
@Vibes - No I did not solve my problem, and I'm not confronted to it anymore as I stop working on the concerned project.Garratt
@Pleione - In fact, I got exactly the same problem, it's why I didn't open another question. All retrieved static resources (mine and those internal to Richfaces) are suffixed by .xhtml (seen with Firebug). Not critical but not really nice. And I don't understand from your answer why JSF should suffix resources. If it has to, as stated above, it's really not a common behavior for a Web app, moreover I you want the user to be technology agnostic.Garratt
@Pom: They're passed through FacesServlet so that it can evaluate EL in CSS and load them from JAR files. I really don't see why that would possibly form a problem to the client.Pleione
@Pleione - Ok, the case of EL evaluation in CSS makes the thing clearer. Clearly, the end user will never see those suffixed static resources and it's in no case a problem. But, you must admit that retrieving a CSS or JS resource with an xhtml suffix is not really elegant and quite strange in fact.Garratt
@Pom: The extension doesn't matter. It's all about the response Content-Type header. Is for example PHP also strange if a CSS/JS resource is served by .php extension? Think pragmatic.Pleione
Appending .xhtml to the resource causes problems if you have filters to set http response headers for dynamic & static resources. I have a @WebFilter which sets *.xhtml to no-cache, and another for *.js, *.css etc... which tries to set max-age=0, must-revalidate. Because of the .xhtml append even the static resources are treated as .xhtml files by the filter and don't cache. I've given up with suffix mapping, too many problems... And I think there are performance benefits from not having to use EL syntax to access resources in stylesheets... i.e. url("#{resource['img:a.png']}");)Vibes
@Oversteer: just check in the filter if it's a JSF resource request or not. See also the filter example in for example stackoverflow.com/questions/7838910/… Don't think the hard way.Pleione
I'm trying not to, believe me! I was using @WebFilter(urlPatterns= but that approach needs tweaking to use ResourceHandler.RESOURCE_IDENTIFIER. Thanks for the link, I noticed that the post hadn't been upvoted, so I did so as you need the reputation.Vibes
@Pleione - Yeah, it's exactly a question of pragmatism. Perhaps, I'm pursuing an unreachable ideal. Just a last point, when you get this behavior and try to download for instance an image, you get a proposal for saving it under 'image.png.xhtml' under Firefox. Still thinking it's not very nice. But, I don't want to seem to advocate against JSF2 too long on such a little grip as it's a useless time consumming activity. I'm back to pragmatism!Garratt

© 2022 - 2024 — McMap. All rights reserved.