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

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>

Related

passing query parameter to graphicImage to prevent img caching

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?

Which is the better way to create dynamic layout managment in jsp

Here I am started to design a portal wise home,login,register ....around 10 common jsp pages.
Its very hard to create these many jsp pages for each portal ,which is an most elegant way.So decided to split the jsp's into header,body,footer and using common header and footer.each time body is changing.
<jsp:include /header.jsp>...body<jsp:include /footer.jsp>
Some thing like above.But the problem raises now is the header footer design is not same for all portals.
So decide to make each and every block dynamic which settings will come from database like menu list ,palce of blocks etc ...
Which is the best way to do it.I came to know there are few frameworks like Tiles
,Wicket,Sitemash etc ...
And also referred Better alternative to Apache Tiles confused to decide.
Can anyone familiar with those frameworks guide me in a right way ??or suggest any new ways which i am missing.
Using java(servlets),Msql as DB.I'm not using Struts(agreeing that don't know :)).
Thanks for your time.
IMO Tiles
because its stable and vast user base , and good documentation too.
It provides good compilation of multiple Jsp into view
example
<definition name="myapp.homepage" template="/layouts/classic.jsp">
<put-attribute name="title" value="Tiles tutorial homepage" />
<put-attribute name="header" value="/tiles/banner.jsp" />
<put-attribute name="menu" value="/tiles/common_menu.jsp" />
<put-attribute name="body" value="/tiles/home_body.jsp" />
<put-attribute name="footer" value="/tiles/credits.jsp" />
</definition>
Like wise you can define as many you want , based on the definition name you return from the servlet, tiles would construct the complete JSP for you.Isnt that neat.
They can be integrated with many popular MVC frameworks like
- Spring MVC
- Struts 2.0
and list goes on.

Spring Web Flow - Multiple forms on page - validating correct form

I am using Spring Web Flow 2.3 and I have a page that has two forms on it that transition to different places depending on which is submitted. To accomplish this, I have one composite model object for my view-state that holds the two forms inside. The problem I am seeing is that if transition A is fired, I only want to validate form A, and likewise with form B - only want to validate B if B transition fired. I am not sure how to indicate which form to validate. View state that is validating the entire compositeForm for each transition:
<view-state model="compositeForm">
<transition on="formAsubmit" to="formApage" validate="true"/>
<transition on="formBsubmit" to="formBpage" validate="true"/>
</view-state>
Does anyone know how I can trigger a custom validator to validate differently depending on which transition was fired?
Thanks for you help.
Steve
I don't know about a custom validator for each, but within your validation method, I think you could use the RequestContextHolder.getRequestContext() to getCurrentTransition() or getCurrentEvent() and compare manually to the getId() value.
What I ended up doing was to manually trigger my validation when form B was submitted and transition to a decision-state that checks if there were validation errors. It's a little ugly, but I feel like it's the best way:
<view-state id="start" model="compositeForm">
<transition on="formAsubmit" to="pageA" validate="true"/>
<transition on="formBsubmit" to="isFormBValid" validate="false">
<evaluate expression="formBValidator.validate(compositeForm.formB, messageContext)"/>
</transition
</view-state>
<decision-state id="isFormBValid">
<if test="messageContext.hasErrorMessages()" then="start" else="pageB"/>
</decision-state>
This is not the best solution, but at least is solves the problem. This is how I obtained my transition id and view-state id in vlaidator.
Transition id
RequestContextHolder.getRequestContext().getFlowExecutionContext().getActiveSession().getState().getId();
view-state id
RequestContextHolder.getRequestContext().getFlowExecutionContext().getActiveSession().getState().getId();

Include spring webflow controller in a jsp

Bit of a background:
We have an existing spring webflow that we want to have ajaxified so that the page can be displayed
in a "lightbox" (at a different URL) where the user can interact with the flow in a similar way to the full existing page.
The normal registration form sits at
http://localhost:8080/csso/customer/registration?execution=e1s1.
(csso is the application name)
The webflow in Spring Webflow has an id of /customer/registration.
<flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<flow-location id="customer/registration" path="/WEB-INF/views/customer/registration/registration-flow.xml"/>
</flow-registry>
registration-flow.xml
<view-state id="create" model="customer" view="customer/registration/create">
<on-render>
<evaluate expression="customer.setAcceptTermsAndConditions(false)"/>
</on-render>
<transition on="submit" to="confirm" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
Now my problem is I need to access this page in two different ways.
Directly. Which works currently.
As an include in a different JSP page
(tabEntry.jsp accessed with controller /tabEntry) in such a way that the flow of the form is not interrupted.
How can I include /customer/registration inside tabEntry in such a way that clicking on submit goes through the same flow?
Problems faced:
Including /customer/registration by jsp:include doesn't work since /customer/registration is not a controller. Also #include doesn't work since a call to /customer/redirection includes a redirect which sets the execution key for webflow
The form action is automatically set to /tabEntry but it should be set to the second state of /customer/registation to continue with the flow.
Happy to accept design changes instead of hammering it technically.

ZKSpring how to pass variables to the ZK zul from the Spring MVC controller?

i've beeing playing with zk a while and now comes serious things.
I've successfull integrated spring and zk and the routing
works as i use #controller annotation.so far so good
Now i needed to call a webservice which return a list of objects
import org.springframework.ui.Model;
//.....
#RequestMapping("/accounts/personal/list")
public String list(Model model){
try {
ArrayOfAccount result = port.getAccounts( null, 0, 20);
//i thought with this i can grab the result collection.
List<IAccount> accounts = result.getIAccount();
model.addAttribute("accounts", accounts);
} catch (Exception ex) {
// TODO handle custom exceptions here
}
return "accountslist";
}
the real problem is to get the object in the zul file.
<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/templates/mainlayout.zul"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<!--<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>-->
<!--<?variable-resolver class="org.zkoss.spring.init.WebflowVariableResolver"?>-->
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk xmlns="http://www.zkoss.org/2005/zul">
<window self="#{define(content)}" id="pAccountWin">
<label id="lblTest" value="click me" />
<div>
<listbox model="${c:l('accounts')}" id="lstAccount" multiple="true">
<listhead>
<listheader label="Account Name" />
<listheader label="Account Type" />
<listheader label="Mobile Phone" />
</listhead>
<listitem forEach="${c:l('accounts')}" value="${each}" >
<listcell label="${each.getAccountName()}" />
<listcell label="${each.getAccountType()}" />
<listcell label="${each.getMobilePhone()}" />
</listbox>
</div>
</window>
</zk>
it's not throwing an error but i feel like i'm not doing something right.And i also know that i can use GenrericForwardComposer to achieve the
same wihtout "hassle"(i believe).this confuses me about whether i'm doing the right thing.
question 1:
How can i achive what i was trying to do as in passing the accounts variable to the frontend?
question 2 :
What's the best way using ZKspring(no webflows)? Spring Controller to do the routing and ForwardComposer to handle the ajax behaviors (ie events)? for example should a write the code to handle the ajax call when going solely the Spring MVC way?
question 3:
i'm using listbox in this but i would need to do things from context menu on selected object.do you thing grid is suitable for it?
thanks for reading this.
Question 1 answer: ${c:l('accounts') will retrieve a label value with key accounts from i3label-properties file (normally used for internationalization in ZK). If you want to access a variable (normally a Java bean)
1. declare variable resolver at the top of your page using <variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?> directive
2. access Java bean in ZUML using EL expressions for. eg. ${accounts}
Question 2 answer: I would recommend doing it ZK MVC way i.e extend you controllers from ZK GenericForwardComposer to handle events. You can always use spring to handle the lifecycle of these controller using Spring framework.
Question 3 answer: I don't think there is any advantage using grid over listbox in this scenario. In any case you can popup context menu on either grid row select event or listbox listitem select event.

Categories

Resources