passing query parameter to graphicImage to prevent img caching - java

I need to pass a query parameter to the graphicImage to prevent IE from using an old cached image.
I tried below and getting this error: File not found: /RES_NOT_FOUND
<h:graphicImage library="default" name="img/MSM_HeaderSplash.png?v=1.1"
alt=" " width="487" height="68" />
Below works, but I really don't want to hardcode the resources path:
<h:graphicImage value="resources/default/1_0/img/MSM_HeaderSplash.png?v=1.1"
alt=" " width="487" height="68" />

You can try this
Easiest would be to add the folder as a "virtual context" of the servletcontainer which you're using. It's unclear which one you're using. In Tomcat it's a matter of adding a new to the server.xml
<Context docBase="/path/to/images" path="/images" />
and in Glassfish it's a matter of adding an alternatedocroot to the glassfish-web.xml
<property name="alternatedocroot_1" value="from=/images/* dir=/path/to" />
Refer the documentation of the servletcontainer for details. Ultimately they should be accessible by a normal URL so that you can just use for example:
<p:graphicImage value="/images/MSM_HeaderSplash.png?v=1.1" />

I used below to resolve the issue. It is not as intuitive as using the graphicImage's library and name attributes. Please let me know if there is other work around. Thanks
<h:graphicImage value="#{resource['default:img/MSM_HeaderSplash.png']}&v=1.0" alt=" " width="487" height="68" />

The best option for your case seems to be to use HTML <img /> tag. Surprisingly, most of image cache solutions are based in a random generated String, as there is no HTML standard way to achieve it. That will cheat the browser and force it to download it again.
There's no need to hardcode the image path more than once, just make use of <ui:param /> to keep variales in facelets.
<ui:param name="imageFolder" value="resources/images" />
<img src="#{imageFolder}/image.jpg?#{currentDate.time}" />
Where #{currentDate} is a current Date instance. This can be implemented by adding a request scoped bean to your faces-config:
<managed-bean>
<managed-bean-name>currentDate</managed-bean-name>
<managed-bean-class>java.util.Date</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
That evaluates to kind of:
<img src="resources/images/image.jpg?1403302512505">
So your current image will be retrieved in each request.
Another choice is to disable the entire browser cache at web-filter level, despite this would affect your whole content.
See also:
Display Current Date on JSF Page
How to force a web browser NOT to cache images
How to control web page caching, across all browsers?

Related

c:url tag includes jsession id query string

What is the best way of obtaining context-root on a jsp page. If I hardcode my css/image to "/myapp/images/foo.gif" then it will be a broken link if the context root / app name is changed. Using relative path is not always preferrable because a context root can be multi-path (eg: /mysite/myapp)
So far I've tried using <c:url var="root" value="/"/> which works alright (${root} will give the context-root /myapp/), however if this is the very first time user is visiting the site (or if cookie is cleaned on the browser), the value assigned to ${root} became something like /myapp/;jsessionid=019762g1hk3781kh98uihilho and it breaks the images/css reference. Is there any other better way than this?
So far I've tried using <c:url var="root" value="/"/> which works alright (${root} will give the context-root /myapp/)
This is not the right way. The <c:url> should be applied on every single URL individually.
You'd better use
<c:set var="root" value="${pageContext.request.contextPath}" />
See also:
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP

Spring Webflow 2.0 with JSF 2 - Is a dynamic Flow possible?

I´m new to Spring Webflow, so I have a Question about a (or more) Flows.
I want to build a few facelets in JSF and one start Page that can have different ui-params in an ui-include, depending on what i want to add in the flow later.
Example application.xhtml:
`<ui:include src="start.xhtml">
<ui:param name="page1" value="page1.xhtml" />
<ui:param name="page2" value="page2.xhtml" />
<!-- page 3 should be ignored -->
<!-- <ui:param name="page3" value="page3.xhtml" /> -->
<ui:param name="page4" value="page4.xhtml" />
</ui:include>`
Now i have my start-flow.xml where i want to check, which ui:params the page got.
But i don´t knwo how to to that, and i couldn´t find anything similar on the web. so i assume, this might be the wrong way to do so :-)
Can anyone help me out?
My goal is to have a flow (independent from hardcoded facelets, so i can check a list of ui:params what facelets i have and to use them, like:
`<view-state id="start" view="${flowScope.allViews[0]}">
<!-- assuming every facelet has a next-action -->
<transition on="next" to="${flowScope.allViews[1]}" />
</view-state>`
Pretty sure you cant just get a list of JSF includes/params in Spring Webflow.
The closest thing you can get to it is to grab FacesContext and try to locate known components by their ids:
boolean haveComponent1 = (FacesContext.getCurrentInstance().getViewRoot().findComponent("component1") != null);
Assuming you know component IDs in included pages in webflow you can do something like:
<decision-state id="doSomSink">
<on-entry>
<evaluate expression='FacesContext.getCurrentInstance().getViewRoot().findComponent("component1") != null)' result="flowScope.haveComponent1" result-type="bool"></evaluate>
</on-entry>
<if test="flowScope.haveComponent1" then="doIt" else="doNothing"/>
</decision-state>

How to use JSF tags in resource bundles / How to rewrite URLs in a resource bundle?

Enviornment:
JSF 2.1.7
SEAM 2.3.0
JBOSS 5.1.2
My application has a string that needs to be localized
"I agree to WorldSite's Privacy Policy and Cookie Notice"
Where the italicized Privacy Policy and Cookie Notice are hyperlinks to other pages.
Originally our facelet was set up like this:
<h:outputText value="#{messages['iAgreeTo']}" />
<h:outputLink target="_blank" value="#{bean.privacyPolicy}">#{messages['privacyPolicy']}</h:outputLink>
<h:outputText value="#{messages['and']}"/>
<h:outputLink target="_blank" value="/jsf/Notice.xhtml">
<h:outputText value="#{messages['cookieNotice']}"/>
<f:param name="content" value="Cookie-Notice"/>
<f:param name="application" value="#{bean.application}"/>
</h:outputLink>
Note: We have URL rewriting in place that takes /jsf/Notice.xhtml and rewrites to
rewrite pattern: /#{application}/Notice/#{content}
result:http://contextRoot/contextPath/myApp/Notice/Cookie-Notice
This allowed for piecemeal translations of the individual keys
iAgreeTo=I agree to WorldSite's 
privacyPolicy=Privacy Policy
and= and 
cookieNotice=Cookie Notice
But this required a workaround for some languages (in "iAgreeTo" and "and" keys)
iAgreeTo=J'accepte la 
privacyPolicy=Politique de la vie privée
and= de WorldSite et les 
cookieNotice=Note D'information sur les Cookies
Ideally I would like to be able to have the links be movable within the key. Something like this:
iAgreePhrase=I agree to WorldSite's #{messages['privacyPolicyLink']} and the #{messages['cookieNoticeLink']}
privacyPolicy=Privacy Policy
cookieNotice=Cookie Notice
//The following non-translatable keys held in a separate file
privacyPolicyLink=<h:outputLink target="_blank" value="#{bean.privacyPolicy}">#{messages['privacyPolicy']}</h:outputLink>
cookieNoticeLink=<h:outputLink target="_blank" id="cookieNoticeLink" value="/jsf/Notice.xhtml">\
#{messages['cookieNotice']}\
<f:param name="content" value="Cookie-Notice"/>\
<f:param name="application" value="#{bean.application}"/>\
</h:outputLink>
But the facelet returns the JSF tags (h:outputLink) as strings instead of expanding them to their HTML tags. I can use <a> tags, but then I'm putting rewrite logic in the properties file which is difficult to maintain
iAgreePhrase=I agree to WorldSite's #{messages['privacyPolicyLink']} and the #{messages['cookieNoticeLink']}
privacyPolicy=Privacy Policy
cookieNotice=Cookie Notice
//The following non-translatable keys held in a separate file
privacyPolicyLink=<a target="_blank" href="#{bean.privacyPolicy}">#{messages['privacyPolicy']}</a>
cookieNoticeLink=<a target="_blank" href="#{contextPath}/#{bean.application}/Notice/Terms-and-Conditions">\
#{messages['cookieNotice']}</a>
Is there a way I can achieve my desired effect without having to put rewrite logic in the resource bundle? Some thoughts I have are forcing the application container to process the facelet twice/reorder it, so it inserts the resource bundles first, and then expands the JSF tags.
Alternatively I may be able to construct the rewritten URL in a bean then call that from my resource bundle?
You seem to have got everything round the wrong way and I'm sorry to have to say that I found the question poorly analysed, overlong and confusing to read.
What you should be trying to do is use resource bundles from within JSF tags and not the other way round. Where you need to parameterise a message you use a construct such as this:
messages.properties
nameHeader=My name is {0}
index.xhtml
<h:outputFormat value="#{msgs.nameHeader}">
<f:param value="#{bean.name}"/>
</h:outputFormat>
If you have a scenario where this doesn't work you would have to build the string in a backing bean.
While Oversteer's answer is certainly applicable, this could also prove helpful. You can create URLs from EL expressions like this:
#{facesContext.externalContext.encodeActionURL('/myapp/Notice/Privacy-Policy')}
To include HTML markup in a message, you need to use escape="false" in <h:outputText/>, for example:
<h:outputText escape="false" value="#{messages['iAgreePhrase']}" />
And, in your messages.properties (or localized version):
iAgreePhrase=I agree to WorldSite's Privacy Policy and ...
This has the problem that the URL is calculable only from within an HTTP request, if you for example use the message key from within an asynchronous thread, the URL will not be calculated (there's no facesContext available).

How do i refer to any image in my java web application from root of my web application?

I have a folder named Common/Images/Photounavailable.jpg. Is this right way of refering to a image from root? I want to refer this image from any page in any folder in my web application.
private String getPhotoUnavailablePath = "/Common/Images/PhotoNotAvailable.jpg";
private String getPhotoUnavailablePath(){
return photoUnavailablePath;
}
And from my JSF page i write something like :-
<h:outputLink id ="blogPhoto" value="#{BlogBean.photoUnavailablePath}" >
<h:graphicImage value="#{BlogBean.photoUnavailablePath}" style="width: 180px;height: 180px;"/>
</h:outputLink>
I get the image to see in h:graphicImage. But when i click on it, i get 404 error. OutputLink doesn't get proper link to image. How is it possible? That h:graphicImage gets proper link and h:outputLink doesn't?
Further, this code works perfectly :-
<h:outputLink id ="blogPhoto" value="..#{BlogBean.photoUnavailablePath}" >
<h:graphicImage value="#{BlogBean.photoUnavailablePath}" style="width: 180px;height: 180px;"/>
</h:outputLink>
Just by putting .. it works! Can anybody explain me what is happening and how do I solve this?
<h:graphicImage> uses context-relative paths.
<h:outputLink> uses absolute paths. That's why you can't use the / (unless in the root context).
You can use something like
value="#{facesContext.externalContext.context.contextPath}/#{bean.path}"
to specify that the start of the path is the context root, not the server root.

JSF - 2 a4j:actionParam in one commandlink bug

I have such structure in my jsp:
<h:commandLink action=#{docbean.save}>
<a4j:actionParam name="somename" value="bill_all" assignTo="#{billdoc.billType}"/>
<a4j:actionParam name="somename" value="bill_document" assignTo="#{docbean.doctype}"/>
</h:commandLink>
While debugging i saw, that billdoc.billtype and docbean.doctype have the same values: "bill_document".
Is it bug? If not, then how can i put value to my managed-bean?
UPDATED:
Found the answer:
I had two actionParams with one name. ActionParam is f:actionListener + f:param. So, if you have several actionparams with one name, you will have the problem i had. RichFaces and JSF doesn't warn you about it.
First, you need a space here <a4j:actionParamvalue - before value
Second, You may try this instead of <a4j:actionParam>:
<f:setPropertyActionListener value="bill_all" target="#{billdoc.billType}" />
You may need to put immediate="true" on your commandLink if there are validation errors in your form. You can view these errors by adding <rich:messages /> ontop of the page.
Try using an a4j:commandLink. Or - if you stick to h:commandLink - try embedding your a4j:actionParams in an a4j:support tag.

Categories

Resources