Archives for "Tech"
A4j:jsFunction on page load
Problem
You need to send some data to the server on page access. One way to do this is by calling an a4j:jsFunction with the appropriate parameters.
The problem is that you have to call this function after the page has fully loaded.
Solution
Use the jQuery(document).ready for this.
If you call the function too early in an embedded Javascript code it will try to call the @Create method of the bean once again. That second call will probably throw some exceptions which are hard to detect.
Took me some time to figure this out since the console pointed me to the @Create method.
Update
After working with seam remoting component I figured out the answer to this behavior. Seam remoting behaves in the same way if used with the most basic settings. It considers the bean to be stateless. After pointing it to use the current conversation everything works ok. The a4j:jsFunction probably doesn’t have time to set it’s conversation status before being called in an inline javascript code. Hence the repeated call to the @Create method.
Paypal with JSF – Making payments from your Enterprise Application
If you have an enterprise application based on J2EE, Seam, Spring or just pure JSF and you want to start charging people for the services or products you provide you can use Paypal’s services to make credit card or bank transfer payments. The Paypal BuyNow button is a an easy approach to do this.
New! A complete Enteprise Sales Paypal Package is available from us for a small fee of 80EUR or 90USD. If you are interested please contact us in order to buy this package. Or simply let us know if this information was useful or interesting for you.
You can use the BuyNow JSF component which wraps the functionality of the Paypal button. The original implementation of the Paypal BuyNow button uses an HTTP form with POST method that sends predefined POST variables to Paypal.
The JSF Paypal BuyNow component
Download the bpcatalog-ee5-ea-0.8-installer.jar and see the reference documentation on Java Sun Blueprints.
The component can be linked to a backing bean and you can easily send additional post data to Paypal.
First you have to extract the downloaded bpcatalog. The installer should do this automatically; if it doesn’t just run the jar with the java -jar switch.
In the bpcatalog-ee5-ea-0.8/lib folder you’ll find the bp-ui-14.jar and shalem-remoting.jar libraries. You will need to include these two libraries into your project. The bp-ui-14.jar is the actual wrapper for the button.
Fix the tag library
The JSF component is missing its tag library. In order to include and use it as a JSF component you must insert a taglib.xml file into the bp-ui-14.jar/META-INF folder.
The taglib.xml file should contain the following:
<?xml version="1.0"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> <facelet-taglib xmlns="http://java.sun.com/JSF/Facelet"> <namespace>http://java.sun.com/blueprints/ui</namespace> <tag> <tag-name>buyNow</tag-name> <component> <component-type>com.sun.j2ee.blueprints.ui.shopping.BuyNow</component-type> <renderer-type>com.sun.j2ee.blueprints.ui.shopping.BuyNow</renderer-type> </component> </tag> </facelet-taglib>
Include it into your JSF page
Now you’re ready to use the Paypal button as a JSF component. Include the tag into the namespace of your page template:
<ui:composition .... xmlns:bp="http://java.sun.com/blueprints/ui" ..>
Include the component on your page:
<bp:buyNow amount="10.00" itemName="My Product" business="email@yourapp.com" quantity="1" returnUrl="http://yourapp.com/thankyou.page" paymentCancelledUrl="http://yourapp.com/billing.page" notifyUrl="http://yourapp.com/ipnscript.page" type="BuyNow">
There are a couple of smaller mistakes in the documentation:
- notify_url is wrapped as notifyUrl instead of postbackUrl as stated (use notifyUrl=”http://yourserver/YourIPNProcessingScript”)
- item_number does not send any value to Paypal
Another Paypal related common difficulty is parsing the date sent by Paypal. They are formatting it based on US PST/PDT time. The recommended formatting for the date parsing is:
String PAYPAL_DATE_FORMAT = "HH:mm:ss MMM dd, yyyy z";
Creating the pages
With the help of the return, paymentCancelled and notify URLs Paypal can send messages to your server about events. It can also redirect your customers to the pages you want them to view when an event occurs. When a payment occurs Paypal will invoke the notifyUrl page and send back some POST variables. You will have to process and validate these variables manually as the above component will not do this for you. A method in your backing bean should be able to process the Paypal message. This will be your so called IPN script.
Processing the Paypal response
The notifyUrl parameter tells Paypal where to send a message which notifies you of the event initiated by a paying customer. The PaypalProcessBean will take care of processing this message by checking whether the data of the transaction is correct. You can then proceed with providing the service to your customer.
You can process the POST variables sent by Paypal by reading them from the FacesContext:
FacesContext facesContext = FacesContext.getCurrentInstance(); HashMap<String, String> IPNPaypalVariables = new HashMap<String, String>(); IPNPaypalVariables.putAll(facesContext.getExternalContext() .getRequestParameterMap());
Validating the transaction
Paypal suggests that in order to verify the data which is being posted back you need to send back all these POST variables in the exact order starting with and additional cmd=_notify-validate parameter.
Paypal responds with a VERIFIED or INVALID message depending on the correctness of the information you have posted earlier. If you received the VERIFIED message the transaction was correct. Now you can rest assured it wasn’t a hacking attempt.
Conclusion
If you want to start earning money with your hard work Paypal is an easy to use service from the perspective of your customers. You can easily integrate the Sun Blueprints Library with your favorite enterprise application framework.
Selective rendering of elements in JSF, Ajax4JSF and RichFaces
When you need conditional rendering inside an Ajax4JSF <a4j:repeat> the JSF <c:if> tag will not work. You can remedy this problem by using an alternative solution.
Problem
Inside an <a4j:repeat var="_counter" value="#{bean.list}"> the <c:if> tag will not recognize the _counter variable. You won’t even notice it doesn’t work because no errors will be logged.
As an alternative you can use the <rich:togglePanel> component.
Solution
Let’s take this example as an alternative to the JSF <c:if> tag:
<rich:togglePanel id="switch" value="#{beanEntity.selectedPanel}"
switchType="server"
initialState="panelOne" stateOrder="panelOne,panelTwo">
<f:facet name="panelOne">
<rich:panel>
<h:outputtext value="This is the first panel"/>
<rich:toggleControl value="switch panel"
for="switch" switchToState="panelTwo"/>
</rich:panel>
</f:facet>
<f:facet name="panelTwo">
<rich:panel>
<h:outputtext value="This is the second panel"/>
<rich:toggleControl for="switch" value="switch panel"
switchToState="panelOne"/>
</rich:panel>
</f:facet>
</rich:togglePanel>
You have a few parameters which you can use:
1. switchType which can be either of
clientrenders all the panel’s faces, and switches between them on the client sideajaxrenders only one panel at a time, and the switch is done by communicating with the server dynamicallyserverrenders only one face at a time, the switch is made on page refresh
If you need something rendered only if a condition is true, server is the best option.
2. initialState controls what the first rendered panel should be. If it’s not specified the panels are rendered in the order specified by stateOrder. If that’s missing also they are rendered in the order the panels are declared.
For switching between panels you can use <rich:toggleControl>. This is similar to a link and has a value attribute (text to be shown). With the id attribute you can style content using css.
3. switchToState specifies to which state should the togglePanel control switch to. If this is not specified it will switch to the next panel in the stateOrder list. A toggleControl can be declared anywhere on the page. Not just inside a togglePanel control. It just needs the for attribute to point to the right component id.
Like in the case of the <c:if> tag, let’s say you want to render something if #{bean.booleanProperty} is false. You do the boolean check on the bean side. Then you set a bean property (eg. String panelState) to the value of panelOne if the booleanProperty is true. And subsequently to panelTwo if the booleanProperty is false. The togglePanel will have the initialState set to #{bean.panelState}.
Conclusion
The <c:if> JSF tag will just refuse - without any error notice – to parse the counter variable coming from a wrapping <a4j:repeat> tag. It can be a little bit of a stretch but if you have problems with the <c:if> tag the above solution offers a good way to do conditional rendering.