Tutorial: use Java to develop Facebook applications

27 04 2009

Create a FB application is funny and easy with Java. There are some open source libraries that can help you to achieve your goal. You find these libraires here :
http://wiki.developers.facebook.com/index.php/Java
I used the facebook-java-api to create this tutorial. It’s a good library but unfortunately it miss documentation (in the traditional OSS old style ;) )
http://code.google.com/p/facebook-java-api/
I used SpringMVC as framework, it’s very easy to pass values to web pages with Spring.
I created 2 pages , one for the login (index.htm) and a second page (results.htm) that shows the results :
Code of the first page :

IFacebookRestClient fbClient = new FacebookJsonRestClient(API_KEY, SECRET_CODE)

FacebookWebappHelper fh = new FacebookWebappHelper(request, response, API_KEY, SECRET_CODE, fbClient);
        fh.requireLogin("");

        if (!fh.isLogin())
            return null;

The goal of this page is to login the user if is still not logged in. Is in your application configuration on Facebook that you can decide where to send the user after the succesful login.

The second page contains this code :

protected ModelAndView handleRequestInternal(
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {
  String token = ServletRequestUtils.getStringParameter(request, "auth_token");
  IFacebookRestClient fbClient = new FacebookJsonRestClient(API_KEY, SECRET_CODE);
  fbClient.auth_getSession(token);

  // get your Facebook id
  Long id = fbClient.users_getLoggedInUser();

  // query Facebook database, ask for all friends single and give me their uid and their complete name
  JSONArray sqlResult = (JSONArray) fbClient.fql_query("SELECT uid, name FROM user WHERE  relationship_status='single' AND uid IN (SELECT uid2 FROM friend WHERE uid1 = " + id.toString() + ")");

  // write the result in a List
List users = new ArrayList();
        for (int i = 0; i < sqlResults.length(); i++) {
            User usr = new User();
            usr.setUid(Long.valueOf(sqlResults.getJSONObject(i).getString("uid")));
            usr.setName(sqlResults.getJSONObject(i).getString("name"));
            users.add(usr);
        }

// send the result to the webpage
ModelAndView mav = new ModelAndView();
mav.addObject("users", users);
return mav;
}
}

This code fragment return the list of my friends single and I put this friends in an ArrayList of User (class included in facebook-java-api).
Show the results in a jsp page is very easy :

<table border="1">
              <tr><td>First name</td><td>Name</td></tr>
              <tr><td>${user.uid}</td> <td>${user.name}</td></tr>
</table>




Use Groovy has Spring bean in a JSF web application

1 04 2009

It’s easy and powerful use Groovy classes in your Java web application using the Spring Framework. Here you can find a tutorial.

In my last project I had to scan a complex xml file and copy the information to a database. A Java class (using org.wc3.dom.* and DocumentBuilder) did the work but the hundreds lines of code were complex and not easy to maintain.

Ex.

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder        docBuilder        = docBuilderFactory.newDocumentBuilder();
doc = docBuilder.parse(fileName);
doc.getDocumentElement().normalize();
NodeList listOfEntries = doc.getElementsByTagName("entry");
for (int s = 0; s < listOfEntries.getLength(); s++) {
  Node firstEntityNode = listOfEntries.item(s);
  if (firstEntityNode.getNodeType() == Node.ELEMENT_NODE) {
  ListEntry entry              = new ListEntry();
  Element   firstEntityElement = (Element) firstEntityNode;
  NodeList  uidList            = firstEntityElement.getElementsByTagName("uid");
  ...

For this reason I decided to integrate groovy in the Spring-JSF application, Groovy has the XMLSlurper class that allows to easily access an XML file like if it is a collection of classes.

You can see here a tutorial for SMLSlurper.

In my application the role of the first Groovy class were the following:

  • accept 2 parameters from a traditional java class (xml file address and an integer parameter)
  • process the xml file
  • use 2 existing Java classes
  • return an ArrayList of custom objects with the values found in the list

Tasks:

1. add the groovy jar to the libraries of your application

2. create a traditional Java Interface

package ch.genidea.checknames.importer;
import java.util.List;

import ch.genidea.checknames.model.ListEntry;
import ch.genidea.checknames.model.SourceList;

public interface Parser {
    List parse();
    void setFilename(String filename);
    void setSourceList(SourceList sourceList);
}

I had to declare the setters for the 2 variables to import in the groovy class.

3. create the groovy class in the classpath. If you are using maven add it to the src/main/resources directory.

Ex.

package ch.genidea.checknames.importer

import java.util.List;
import ch.genidea.checknames.model.ListEntry;
import ch.genidea.checknames.model.SourceList;

public class ParserImpl implements ch.genidea.checknames.importer.Parser{
    String filename
    List <ListEntry> result
    SourceList sourceList

    public List<ListEntry> parse(){
        def pers=new XmlSlurper().parse(new File(filename))

        List <ListEntry> result = new ArrayList<ListEntry>()
        def allEntry = pers.Entry

        allEntry.each{
                 result.add(addEntry(it))
                 it.akaList.aka.each{
                 result.add(addEntry(it))
                 }
        }
        return result
    }
    ListEntry addEntry(def it)
    {
            ListEntry entity = new ListEntry()
             entity.uid = (it.uid.text() as Integer)
             entity.sourceList=sourceList
             entity.familyName = it.lastName.text()
             entity.firstName = it.firstName.text()
             return entity
    }

    void setFilename(String filename)
    {
        this.filename = filename
    }
    void setSourceList(SourceList sourceList)
    {
        this.sourceList = sourceList
    }

}

In few lines the class did the same work of hundreds of lines of code of the previous implementation :)

In this groovy class we use ListEntry and SourceList that are traditional java classes and we return a List<ListEntry> object

4. Declare the bean in Spring


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:lang="http://www.springframework.org/schema/lang"
 ...
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd"
...
>
<lang:groovy id="parser" script-source="classpath:ch/genidea/checknames/importer/ParserImpl.groovy" />

<bean name = "listImportService" class="ch.genidea.checknames.lists.service.ListImportServiceImpl">
<property name="parser" ref="parser"></property>
</bean>

 

5. use the groovy class in your sourcecode :)

parser.setFilename(fileSource);
parser.setSourceList(sl);
List<ListEntry> list = parser.parse();

The only drawbacks I had are:

  • with Eclipse is not easy to debug groovy, but I used the groovyconsole to test rapidly the changes
  • 4MB added using the groovy-all.jar

Small issues compared to the great benefits of having less and more readable codeeasy a





Test your webservices

31 03 2009

During my last project I had to test the answer of some webservices (SOAP) of the application. I found SoapUI that allows to send request easily and fast. The tool is free but there is a more complete commercial version.

No need to create extra code to test the results :)





JSF and Spring Security (Acegi) using facelets

26 03 2009

Two tips for the people who is fighting with these technologies:

1. Implement the login page: here you have a great tutorial that explains how to implement a login page in JSF using Spring Security in only few lines of code.

2. Somebody is implementing the tags for jsf. You can try his library : BodyGuard





Spring MVC 3.0

11 03 2009

I found two interesting presentations of Spring MVC 3 (part of Spring Framework, still in RC phase)
Slides
and a second presentation in pdf

The big improvement is the full support of REST and logical URI parameters. Spring EL is now available and there is no more dependency with other EL libraries (JBoss and OSGI).





JPA: lazy loading for lazy developers, the performance issue

9 03 2009

I found and interesting article about loading and reading data with JPA. There are performance issues when you want to insert 1′000 or 10′000 records in the database.
Before ORM life was complicated … 25 lines of code to insert a line in the database, not it’s easier: entityManager.persist(object)!
The frameworks (Hibernate, Toplink …) do all the work and they do very well the work. The problem with JPA is that we cannot flush the session like in hibernate and send 50 or 100 records in a block to the DB. JPA send and retrieve each object in a transaction. Inserting 10′000 records takes minutes … 1′000′000 hours.
The solution is to use direcly JDBC, ETL product or frameworks (Spring Batch, …).
JPA is something great but it cannot manage everything :( no party for the lazy developers … yet!





Give to your client a dedicated J2EE server in ASP mode

9 03 2009

In my last project we had to sell ASP solutions to client. The software works on our servers and the clients have to connect remotely.
The projet has been launced by a small non-IT company, mantain a Server Park for them is not possible. For this reason we opted for dedicated server managed by exernal service provider.

The problem of this solution is that one server is very expensive and the approach to create multiple instances of Tomcat, mysql, … is a big risk in case of problem of one instance and it’s complicated in the configuration phase.

The solution adopted is to install VMWare Server (you can do the same with Virtuozzo, XEN, …) and install an Ubuntu VM for each client. Ubuntu has a server edition conceived for the VMs (Ubuntu JEOS). It needs only 128MB ram and 200 MB HD. We used Tomcat 6 (thanks Spring!!!) for this product (max 200MB for instance). 512 MB dedicated for each VM is largely sufficient.

Each client has a different ip port to connect to the appication. Configuring the nat.conf of VMWare on the server we can easily redirect the client request to his ‘dedicated server’. On a typical server with 4GB of ram we can install 8 VMs reducing the costs for us and the client.

A big advantage is the possibility to create locally the VM and transfer it to the ‘production’ when it’s ready copying the files. The maintenance is easier because when we have to upgrade the version we can redirect the port to a different VM with the updated product. This last options is not implemented yet because we preferred to maintain the DB server in the VM with tomcat. In the future (after benchmarks) it could be interesting to install a ’service’ VM with the DB and access it directly from the VMs.





Spring – Configuration file

7 03 2009

Problem
Spring is managing the database connection of my application. I want to extract the parameters outside my applicationContext.xml file

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/database" />
<property name="username" value="user"/>
<property name="password" value="password"/>
  </bean>

Solution
Add the PropertyPlaceholderConfigurer bean to your ApplicationContext with the name of the file(s) containing the data.

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
        <value>WEB-INF/data.properties</value>
    </property>
</bean>

If you have more property files you can use the <list> tag:

<property name="locations">
	<list>
<value>data.properties</value>
<value>...</value>
</list>
</property>

The data.properties should be like this:

database.url= jdbc:mysql://localhost/CheckNames
database.username=username
database.password=password

To use these properties in your applicationContext.xml file:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"><value>${database.url}</value></property>
<property name="username"><value>${database.username}</value></property>
<property name="password"> <value>${database.password}</value></property>
  </bean>

Spring reference





Spring: split the application context

6 03 2009

There are many reasons to declare the beans in more than one xml file. The most important reason is to maintain the code clear with a logical separation of the content of the file. The second reason is that when the application begin big only one file is not enough for the configuration.

In Spring is easy to split the content of the applicationContext.xml:
web.xml
You have to declare the contextConfigLocation

<context-param><param-name>
contextConfigLocation
<param-value>
/WEB-INF/yourApplicationServices.xml, /WEB-INF/yourApplicationDatabase
</param-value></context-param>

You can use Ant-style pattern to call your files e.g. /WEB-INF/yourApplication*.xml

Spring reference





Using Spring with JSF – the managed bean – tutorial

6 03 2009

Two J2EE technologies are becoming dominant in the Java environment: Spring and Java ServerFaces.
Spring beans could be easily integrated in a JSF project. Spring Beans can coexists with JSF managed beans or interact directly with the view.

The steps necessary to use Spring in a JSF projects are the following:

Libraries
Spring libraries must be accessible :)

web.xml
In web.xml you have to declare your spring listener:

<listener>
<listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>

To use the request values between the view (jsp/jsf) ad the bean you have to add a second listener:

<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>

faces-config.xml
In faces-config.xml usually you define the managed beans. To use spring beans you have to add the following lines:

<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver><code>
</application>

applicationContext.xml
In the applicationContext.xml you have to declare your beans like a standard Spring application, the only difference is the property scope:

<bean name ="personMB" class="ch.genidea.ofac.web.jsf.Person" <strong>scope="request"</strong>>
<property name= ... />
</bean>

Usually the scope property is set as singleton (default). For the web application you have 3 possibilities:

  • request: Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition.
  • session: Scopes a single bean definition to the lifecycle of a HTTP Session.
  • global session: Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context.

page.jsp

In your page you can call the bean directly :

<h:outputText value="First name"/> <h:inputText value="#{personMB.firstName}" id="personName"/>
<h:outputText value="Family name"/> <h:inputText value="#{personMB.lastName}" id="personFamilyName"/>