devxlogo

Flex RESTing with MySQL

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.

Requirements

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:

		

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

	

connectionURL="jdbc:mysql://localhost:3306/restmysql" userId="restmysql" password="abc123"> ???
"rest_mysql_javasrc"> ? ? ? ?

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//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/1The REST architecture recommends that developers use the HTTP methods explicitly on their resources:

    * Use HTTP POST to create a resource.
    * Use HTTP GET to retrieve a resource.
    * Use HTTP PUT to update a resource.
    * Use HTTP DELETE to delete a resource.

Because of a browser limitation, Adobe Flash Player is unable to issue any PUT or DELETE methods. To get around this recommendation, I use a modified REST implementation as follows:

    * Use the GET method for deletion when the client passes a query parameter of deleteFlag set to 1.
    * Use the POST method to update whether the client includes a valid ID. If the ID is not provided or is invalid, then the service creates a new resource.

Here is my modified RESTful Web service API:

@GET @Path("{bookid}")	@Produces("application/xml")public String getBook(@PathParam("bookid") String bookid, @DefaultValue("0") @QueryParam("deleteFlag")
int deleteFlag){}@POST @Consumes("application/xml") @Produces("application/xml") public String addOrUpdateBook(String bookContent) {} @GET @Produces("application/xml") public String getBooks() {}

This API is just one implementation to get around this limitation. Feel free to choose the best workaround for your application. The REST architecture is flexible enough to support quite a few solutions.

Using Spring DAOs in My RESTful Resource

As mentioned earlier, to access my database, I take advantage of Spring DAOs that ibator generates. To tie my DAO to my RESTful resource, I turn to Spring annotation again. I just add my Spring DAO as a member of my Java REST resource class with some Spring annotation sprinkled on top. @Autowire is a Spring annotation to inject a property into a Spring bean. Here is a Java code example to illustrate such a use:

@Path("/books")@Component@Scope("singleton")public class BookResource {			@Autowired		private BookDAOImpl bookDAO = null;	}

Now, I can use the Spring DAOs to manage any resource in my database. The ibator-generated DAOs provide a clean interface to my database without my having to worry about any database specifics. But the real value to the generated code from ibator is the utilization of the database-defined POJOs, which are called Value Objects (VO) in Flex.

Using Value Objects

VO (also known as a Data Transfer Object) is a commonly used term in the Flex world. Think of VOs as Adobe ActionScript versions of POJOs generated from ibator. VOs are tied to the Model-View-Controller (MVC) design pattern. The model in MVC is the client-side data store for saving application data. VOs are dummy objects stored in my model and are often bound to the view of my application. On the Flex side, VOs should be the only reference to its remote services.

To use VOs in my infrastructure, I need to perform a few tasks:

    * In my Flex project, I create identical ActionScript VOs for every POJO generated from ibator.
    * In my Java project, I write the code to serialize all of the POJOs returned from my database query into XML, return the XML to my Flex client, and de-serialize the XML into VOs on the Flex side. This is simply a crude serialization process to move my VOs from server to client and vice verse. Here is Java example code utilizing XStream to serialize my database POJOs into XML:
@GET 	@Produces("application/xml")	public String getBooks() {		int i = 0;		List bookList = null;		String xmlStr = null;		XStream xstream = null;		Book book = null;		Integer id = null;					if (bookDAO != null) {			xmlStr = "";			try {bookList = bookDAO.selectBookByExample(null);if (bookList != null && bookList.size() > 0) ?{					xstream = new XStream();					xstream.alias("Book", Book.class);					for (i=0; i

In the above code, I traverse the booklist of POJOs and pass each Book POJO into the XStream engine to be serialized into an XML string that is appended to my returning XML back to the client. This process creates a simple, manageable VO. By using VOs in my data management, I get the following benefits:

    * During Flex development, I can focus on managing the VOs, not on the how and where my application data is being stored.
    * The VOs provide a level of abstraction from the data services layer, so I am not tied to my current data service. I can change my data services layer with minimal code changes in Flex.

Using VOs in my Flex application provides some nice benefits that allow me to concentrate on creating better UIs.

Configuring Spring to Glue Everything Together

To complete my RESTful data service, there are a few ugly configuration items that I have to take care of. Using Spring, I normally reference the Spring servlet in my web.xml file, but in this case, because I am using Jersey and Spring, I have to use a custom Jersey-Spring servlet built with Spring 2.5. Here is the configuration in my web.xml file:

     ???????Jersey Spring Web Application ???????com.sun.jersey.spi.spring.container.servlet.SpringServlet ??????? ???????????debug ???????????1 ??????? ???????1 ??? ??? ???????Jersey Spring Web Application ???????/resources/* ???

Now, I must define all my resources, such as data sources and DAOs, to tie everything together. I configure them in my applicationContext.xml file. Here is my configuration:

 ????	 ?? ???	 ???		 ?? ????			 ??????		 ??????		 ??????				 ???? ???? ???????	 ???????	 ???WEB-INF/config/my-sql-map-config.xml ???????	 ???????	 ???????????	true ???????	 ???????	 ???????????	 ??			 ???	 ???	 ???		 ??? ??????????	 ??????	 ??????

Using Spring to tie these technologies together is nice, but Spring offers a myriad of other features, such as database transaction, authentication, and authorization, to support a more advanced application design. In other words, as your application grows, Spring has the functionality and features to support that growth.

After finishing the Spring configuration, my RESTful resource is complete. Now, I just compile my Java source code and deploy my Web archive (WAR) to Apache Tomcat (or whatever application server is in use). For a quick test, I just point my browser to the GET method to see the resulting XML, as shown in Figure 3.

Figure 3. The XML resulting from deploying my WAR to Tomcat.

Now, I turn to the Flex side of the equation. How do I consume this RESTful resource from Flex?

Consuming My Restful Resource

After designing my RESTful data service, I am ready to start Flex development to consume the service. In this example, I am using Flex 4, but most of what I develop can be accomplished in Flex 3, as well. Flex provides a vast collection of data components, but none of them are specific to REST. Because Jersey REST is implemented over HTTP, the best option is the Flex HTTPService data component.

As I mentioned earlier, a browser limitation prevents the Flash Player from issuing any HTTP PUT methods or HTTP DELETE methods, so I use HTTP GET and HTTP POST to implement all of my commands to manage my resource. The Flex MXML code below illustrates two separate HTTPService data components (one for HTTP GET and one for HTTP POST):

 ???	

Within any Flex data component, I specify event listeners for the result and fault events. If the HTTP request succeeds, the service dispatches the result event, and my result handler is invoked. If the HTTP request fails, the service dispatches the fault event, and my fault handler is invoked. Once my result handler is invoked, I start processing my VOs.

Revisiting VOs

To start de-serializing the XML data from the Web service, I need to create ActionScript VOs to match my ibator-generated POJOs on the server. In other words, the names of the public getters and setters of the members in the POJO must have the same names as public members in the ActionScript VO. Here is my ActionScript VO class:

	public class Book {		public var bookid:int = -1;		public var author:String = null;		public var title:String = null;	}

Here is my POJO class:

public class Book implements Serializable {	private Integer bookid;	private String author;	private String title;			public Integer getBookid() {		return bookid;	}	public void setBookid(Integer bookid) {		this.bookid = bookid;	}	public String getAuthor() {		return author;	}	public void setAuthor(String author) {		this.author = author == null ? null : author.trim();	}	public String getTitle() {		return title;	}	public void setTitle(String title) {		this.title = title == null ? null : title.trim();	}}

For the serialization process to work, the objects must have matching public members. As you see above, bookid, author, and title are defined in both objects. For every POJO Java source file, there should be a VO ActionScript source file.

De-serializing XML into a VO

Now, I have developed all of my VOs. I can start the de-serialization from XML into VOs. Inside my result handler of the getBooks component, I start the process of de-serializing the resulting XML. Here is my ActionScript example code to illustrate:

var i:int = 0;var resp:XML = (event.result as XML);var count:int = resp.children().length(); ????????????	if (count > 0) {	model.bookModel.clearList();}						for (i=0; i

In the code above, I store all of my VOs in my model, so I can easily bind them to any Flex UI component.

Serializing VO to XML

Now, say the user has made changes to an existing VO or wants to add a new VO. First, I need to serialize the VO into XML, and then pass the XML as a parameter to my RESTful data service for storage. In the code below, I am serializing the VO into XML for transportation to my service:

public function serialize():XML {		var qName:QName = new QName("app.vo.Book"); ?????????var xmlDocument:XMLDocument = new XMLDocument();var encoder:SimpleXMLEncoder = new SimpleXMLEncoder(xmlDocument);var xmlNode:XMLNode = encoder.encodeValue(this, qName, xmlDocument); ?????????var xml:XML = new XML(xmlDocument.toString()); ???????	return xml;	}

The user clicks Save, and my event listener starts the process of saving my book VO. I pass the serialized book VO as a parameter to my send request. Here is my ActionScript example code:

protected function saveBtn_clickHandler(event:MouseEvent):void {		// updatingif (selectedBook != null) { ???			pendingUpdate = new Book(); ???			pendingUpdate.bookid = selectedBook.bookid; ???			pendingUpdate.title = titleText.text; ???			pendingUpdate.author = authorText.text;			addOrUpdateBook.send(pendingUpdate.serialize()); ???		}		// adding new record ???		else { ???			pendingUpdate = new Book(); ???			pendingUpdate.bookid = -1; ???			pendingUpdate.title = titleText.text; ???			pendingUpdate.author = authorText.text; ???			addOrUpdateBook.send(pendingUpdate.serialize()); ???		}}

When the server responds to my request, I update my model. Once the VO is updated in the model, I can bind it to any view in my application, as shown in Figure 4.

Figure 4. Binding my VO to an application.

Conclusion

By combining a few server technologies, I can create a lightweight enterprise data service infrastructure that has the flexibility to support a more advanced application design for my Flex application. iBATIS provides me with a quick and simple API to my database without writing any Java code. Jersey REST provides a simple HTTP interface to my Web service without a lot of configuration. Spring glues all of the server technologies together, at the same time giving me some important server functionality to support a more advanced application design in the future. Flex's data components provide an easy mechanism for integrating with my RESTful data service. Hopefully, this infrastructure will allow you to focus on your application's look and feel to create more elaborate and elegant Flex applications.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist