Browse DevX
Sign up for e-mail newsletters from DevX


Flex RESTing with MySQL






Adobe Flex is the premier rich Internet application (RIA) technology in the marketplace. Because of Flex's toolset and support, you have many options for creating your next user interface (UI).

Like many coders, I get an idea for my next application and start feverishly coding it with eye-popping effects and graphics. After my coding fury has subsided, I realize that I need some mechanism to persist my data remotely. I hate spending a lot of time integrating my back-end databases: I know that data management is important, but it's time consuming and yet another learning curve to overcome. To shorten that learning curve, I am going to introduce you to a simple data service infrastructure to quickly get your Flex application up and running with its remote data store. By the end of the article, you'll have a good understanding of the following technologies:
    * Configuring iBATIS, a lightweight data mapping framework, to communicate with a database
    * Developing a Representational State Transfer (REST) resource that exposes a Hypertext Transfer Protocol (HTTP) Web service to a Flex client
    * Configuring the Spring Framework, which is a lightweight Java container that can provide several important server features
    * Utilizing the Flex data components to communicate with a RESTful Web service
This article assumes that you have a basic understanding of Java 2 Platform, Enterprise Edition (J2EE) and the MySQL database. But the focus is to communicate a simple but comprehensive data service framework to quickly integrate with your Flex application. Figure 1 provides a high-level overview of the data service infrastructure that I am suggesting.

Figure 1. The proposed data service infrastructure.


The technologies used in this article are:
    * Database mapping technology: iBATIS version 2.3.4
    * Database: MySQL version 1.5
    * Server enterprise technology: Spring Framework version 2.5.6
    * REST Java library: Jersey 1.1.2
    * Serializing Java XML engine: XStream version 1.3.1
    * Remote client: Flex version 4
    * Java Virtual Machine (JVM): Java software development kit (JDK) version 1.5

Building the Bridge to the Database

To access my database in Java, the quickest and simplest path is using a database mapping framework. Several frameworks are available that can map a database into Java objects, but I chose to use iBATIS, a lightweight framework that maps Structured Query Language (SQL) statements into plain old Java objects (POJO). Think of a POJO as a row in the database. To interact with my database, I take advantage of Data Access Objects (DAO), which provide an application programming interface (API) to my database. DAOs provide a level of abstraction from my database that hides SQL specifics from my application, so I can easily replace my database vendor without affecting my existing code. iBATIS offers DAO functionality; but instead, I like using Spring DAOs. By combining iBATIS with Spring, I get so much more along with basic DAO functionality.

The Spring Framework offers many enterprise features along with data access. By using the Spring-iBATIS partnership, I get several other Spring features, such as transaction management, database exception handling, and authentication/authorization. iBATIS is configured by XML-based SQL-Map files. I know what you're thinking: How is XML configuration files quick integration? Yes, modifying XML configuration can be a painful, slow process. To lessen the torture, I use iBATIS's code generator tool called ibator, which inspects my database schema and generates code and configuration files based on my inspected database. Here is a list of the generated artifacts from ibator:
    * Spring (or iBATIS) DAO source code
    * POJO source code (one Java class per database table)
    * Helper Java objects to help build the SQL code
    * SQL-Map configuration files
Once I've set up my database schema, I run the ibator tool, and the majority of my back-end development is complete. Here is the Ant build file to run the ibator code generator:

<?xml version="1.0" encoding="utf-8"?> <project default="generateRestMySQLIbator"> <target name="generateRestMySQLIbator"> <eclipse.convertPath resourcepath="rest_mysql_build/resources/ibatorConfig-restmysql.xml" property="thePath"/> </target> </project>

Of course, ibator has an XML configuration file to generate the code. So, here is my ibator XML configuration:

<ibatorConfiguration> <ibatorContext id="ibatorContext" targetRuntime="Ibatis2Java5" defaultModelType="flat">
<ibatorPlugin type="org.apache.ibatis.ibator.plugins.SerializablePlugin"/>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/restmysql" userId="restmysql" password="abc123">     </jdbcConnection>
<javaModelGenerator targetPackage="app.vo"  targetProject=
"rest_mysql_java\src">   <property name="enableSubPackages" value="false" />   <property name="trimStrings" value="true" /> </javaModelGenerator> <sqlMapGenerator targetPackage="app.maps"  targetProject="rest_mysql_java\src"> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <daoGenerator type="SPRING" targetPackage="app.dao" targetProject="rest_mysql_java\src">   <property name="enableSubPackages" value="false" />   <property name="methodNameCalculator" value="extended" /> </daoGenerator> <table tableName="book" domainObjectName="Book"> <generatedKey column="bookId" sqlStatement="MySQL" identity="true" /> </table> </ibatorContext> </ibatorConfiguration>

If you need to write more complex SQL statements, you can create your own iBATIS SQL-Map file with your custom SQL code. Without writing any Java code, I have a complete Java API to access my database, as shown in Figure 2. Now, I just need to use it.

Figure 2. The Java API for accessing the database.

Designing My Restful Resource

REST is a fast-growing Web service architecture based on the concept of managing resources through HTTP methods. Because REST is based on HTTP, it provides a familiar interface to access a Web service. Java API for RESTful Web Services (JAX-RS) is a standard for developing REST Web services in Java.

Jersey is Sun Microsystems' open source implementation of the JAX-RS standard. There are a few Java-based REST libraries, but I decided to use Jersey because of its excellent support for the Spring Framework. Jersey and Spring annotations make exposing Java objects as a REST Web service quick and easy. Here is a Java code example using Jersey and Spring annotations:

@Path("/books") @Component @Scope("singleton") public class BookResource {} In this snippet:

    * @Path is a JAX-RS annotation that represents a relative Uniform Resource Identifier (URI) path.
    In other words, you could access the Web service via a browser with the URL http://localhost:8080/<context>/books.
    * @Component is a Spring annotation that indicates that the Java class is a Spring bean.
    * @Scope is a JAX-RS annotation that represents the scope of the transaction of the call to the Web service. In this
    case, singleton scopes a Spring bean to be an object instance per Web application. Jersey supports three Spring
    scopes: request, singleton, and prototype. For a complete list of the JAX-RS annotations, see Developing RESTful Web
    Services with Jersey.
    * To expose a method inside my Java class, I use JAX-RS annotation, as well:
    * @GET is a JAX-RS annotation indicating use of the HTTP GET method to access the requested Web service method.
    * @Produces is a JAX-RS annotation indicating that the Web service method produces an XML string result back to the client
In the example below, the client passes a bookid parameter to specify which Book object it is requesting from the database:

@Path("/books") @Component @Scope("singleton") public class BookResource {     @GET @Path("{bookid}")     @Produces("application/xml")     public String getBook(@PathParam("bookid") String bookid,     @DefaultValue("0") @QueryParam("deleteFlag") int deleteFlag) {} }

To access the above REST method, the client invokes the following HTTP method:

GET http://localhost:8080/rest_mysql/books/1
