Passing request scoped beans from one page to another - spring

If I have a request scope bean on a page in JSF2....how do I pass it to another page (I'm using JSF2 with Spring)?
I've tried the following but it doesnt work:
<h:commandButton action="complete.xhtml?faces-redirect=true" value="Confirm Booking">
<f:setPropertyActionListener target="#{quoteHolder.item}" value="#{quoteHolder.item}"/>
</h:commandButton>

action="complete.xhtml?faces-redirect=true"
You're sending a redirect. The <f:setPropertyActionListener> won't help much here as the request scoped bean will be garbaged after the invoke action phase anyway.
You have basically the following options:
Send all the data as request parameter(s) instead (conversion to/from String necessary!)
Don't send a redirect (the <f:setPropertyActionListener> becomes superfluous then)
Store it in a session scoped bean (not recommended! may be bad for user experience).

Related

METADATA parameters disappear after AJAX action

in template i'm defining a parameter
<f:metadata >
<f:viewParam name="pageKey" value="#{parameterProvider.pageKey}" />
</f:metadata>
All works fine except AJAX requests with makes this param disappear?
example ajax button in xhtml page:
Message value from server= [#{lockerBean.msg}]<br/>
<h:form>
<h:commandButton value="Ajax Action" styleClass="systemButton" >
<f:ajax execute="#all" render="#all" listener="#{lockerBean.ajaxButton(event)}"/>
</h:commandButton><br/>
</h:form>
ajax action is simply
public void ajaxButton(ActionEvent event){
msg="Ajax reload";
}
After ajax request pageKey is gone. If i set required="true" i get valudation error
j_idt3: Validation Error: Value is required. with clearly indicates, that parameter has been deleted. how can i preserve it?
I know about includeViewParams, but i don't understand this mechanism very well and it is not easy to add to all kinds of buttons and links... can i somehow force it to be passed or can i inject them somewhere in context?
EDIT:
this log might help to understand what is happening:
ParameterProvider, is sessionscoped CGI that holds pageKey. I modified getter & setter, so they log info about being called. In whole aplication getters and setters to this value is used only when applying request value in jsf lifecycle (my own code uses different methods)
14:04:06,400 OFF [ParameterProvider] (default task-12) Getting pageKey[-1] into viewParams.
14:04:06,401 OFF [ParameterProvider] (default task-12) Setting pageKey[2] from viewParams.
14:04:06,401 OFF [MultiActionLockListener] (default task-12) AJAX ACTION
14:04:06,414 OFF [ParameterProvider] (default task-12) Getting pageKey[3] into viewParams.
as you can see, before anything we have calling getter and setter for key (2 has been send from client 3 suppose to be sent to client in response)
calling another action will cause to log:
14:08:54,281 OFF [MultiActionLockListener] (default task-14) AJAX ACTION
14:08:54,294 OFF [ParameterProvider] (default task-14) Getting pageKey[7] into viewParams.
as you see, there is no getter and setter, which means pageKey is gone?

Apache-Shiro: User authenticates within AJAX, how to restore GET-Variables after login?

in my JavaEE-Application, I am using Apache Shiro[1] for user-authentication.
My users are navigating via GET-URLs, as for example "/company/index.xhtml?companyId=327".
I have enabled programmatic login, following a guide[2] from BalusC:
SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
My problem is, that savedRequest.getRequestUrl() does not contain the previous mentioned GET-parameteres, when my case is asynchronous POST with or without RememberMe; just "/company/index.xhtml" is returned, for example. It seems as if "FacesAjaxAwareUserFilter" (see [2]) is not GET-params aware. Everything works fine on synchronous GET-calls.
How do I get the GET-parameters after an shiro-redirect because of authentication-needed in case of using "FacesAjaxAwareUserFilter"?
[1] https://shiro.apache.org/
[2] Followed this great article about JavaEE and Shiro: http://balusc.blogspot.de/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html
JSF ajax requests are sent to the URL as generated by <h:form>. This is however by default not exactly the current URL including the query string, it's by default the current URI without the query string.
There are several ways to fix this. The simplest but ugliest way is to use JS:
<h:form id="foo">
...
</h:form>
<script>document.getElementById("foo").action += "?" + location.search;</script>
The cleanest way would be to create a custom ViewHandler whose getActionURL() (as used by <h:form>) will return the desired URL with the query string.
JSF utility library OmniFaces has already such a component which does that based on view parameters: the <o:form> which basically extends the <h:form> with support for includeViewParams="true" (exactly the same way as <h:link> does).
<f:metadata>
<f:viewParam name="companyId" value="#{bean.company}" />
</f:metadata>
...
<o:form includeViewParams="true">
...
</o:form>

How to know whether JSF bean setter is invoked from AJAX event or as part of form POST processing

I have a form that contains a Part Number inputText field and some other fields that represent the attributes of a part. If the user enters an existing part number, I want to populate the other fields with the part's existing attributes. The operator then has the option to change Part Number to something else (essentially creating a new part using the existing part as a template) and/or modify its attributes. I have an AJAX event defined to update the model when Part Number changes, so I can retrieve the attributes from the database:
<f:ajax event="valueChange" execute="#this" render="partlength" />
My question is this: How does the Part Number setter (e.g. setPartNumber() ) know whether it is being invoked as part of an AJAX event, in which case I want to fetch the attributes, or as part of the Update Model Values phase of the form being posted, in which case I don't? Or is there a better way to accomplish what I'm trying to do?
You can determine by PartialViewContext#isAjaxRequest() whether the current request is an ajax request or not. You can obtain the PartialViewContext by FacesContext#getPartialViewContext().
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// The current request is an ajax request.
}
An alternative is to just do the job in the listener method of <f:ajax> instead of in the getter/setter (doing business job in getters/setters is a poor practice anyway):
<f:ajax listener="#{bean.listener}" render="partlength" />
(note that I omitted the event and execute attributes as you've used the default values already)

<ui:param> facelet tag performance

I have a file with large content to display. For example in displaying user profile, every EL expression in <h:outputText/> needs an userId as an argument to bean which is taken from the session context. I declared this userId in xhtml file as
<ui:param name="userId" value="#{currentUser.id}"/>
I am passing this userId to bean methods as
<h:outputText value="#{profile.getAddress(userId)}"/>
<h:outputText value="#{profile.getContact(userId)}"/>
<s:link>
<f:param name="userId" value="#{userId}"/>
</s:link>
I am expectiong the session variable is invoked once for a page. But each time when the userId is processed the sessiion variable is called. Is this the correct behaviour? How to optimize this?
Yes this is the correct behavior. It would be interesting to see which is faster. I would guess it is faster to inject the currentUser in your profile component, and then to retrieve the correct object from there, instead of getting the address and contact by the userId each time. (Depends if you cache it in the component or not).
However, I would try to optimize it by injecting the currentUser in the profile component. That is the standard way of doing it.

what is data.foo syntax in JSF/Rich Faces

what is data.foo syntax in JSF/Rich Faces?
Say for example,
<a4j:support event="onchange" action="#{bean.retrieveStates}"
reRender="states_dropDown" data="#{student}"></a4j:support>
i am passing student object in data attribute. can I access in managed bean?
Documentation says this
"Serialized (on default with JSON) data passed on the client by a developer on AJAX request. It's accessible via "data.foo" syntax "
can some one please explain.
From this blogpost:
Another attribute is data, which allows you to get any additional data from
the server during an Ajax request. The data attribute can simply point to a
bean property via EL, and the data will be serialized in JSON format and
available on the client side. Here’s an example:
<a4j:commandButton value="Submit" reRender="out"
data="#{bean.text}"
oncomplete="alert(data)"/>
So yes - you can access any attribute of the managed bean and reference it (most often) in oncomplete.

Resources