Adding JSON support to domain objects and controllers

Let's say that you have developed the persistence layer of your application using Roo. Now, you want to expose the CRUD operations and dynamic finder methods defined in the Roo-generated JPA entities to the outside world via a RESTful interface.

Roo supports exposing CRUD operations and dynamic finders of JPA entities via RESTful interfaces that use JSON documents for exchanging data. As JSON is used by Roo-generated RESTful interfaces, you can modify JSPX pages of the Roo-generated Spring Web MVC application to use Ajax to interact with these RESTful interfaces.

Roo provides two commands for adding JSON support to existing classes in the Roo project:

  • json add: Adds JSON support to the class specified using the class argument
  • json all: Adds JSON support to all the classes annotated with the @RooJavaBean annotation

The json add and json all commands add the @RooJson annotation to Java classes. the @RooJson annotation results in the creation of a *_Roo_Json.aj AspectJ ITD corresponding to the class annotated with the @RooJson annotation. In this recipe, we'll look at the *_Roo_Json.aj AspectJ ITD and at the @RooJson annotation.

It is important to note that @RooJson annotation allows you to control auto-generation of JSON related methods in the corresponding *_Roo_Json.aj ITD file.

Getting ready

Delete the contents of the ch04-recipe sub-directory inside the C: oo-cookbook directory.

Copy the ch04_web-app.roo script into the ch04-recipe directory.

Execute the ch04_web-app.roo script that creates the flight-app Roo project, sets up Hibernate as the persistence provider, configures MySQL as the database for the application, creates the Flight and FlightDescription JPA entities, and defines a many-to-one relationship between the Flight and FlightDescription entities. If you are using a different database than MySQL or your connection settings are different than what is specified in the script, then modify the script accordingly.

Start the Roo shell from the C: oo-cookbookch04-recipe directory.

Execute the controller all command to create controllers and JSPX views corresponding to JPA entities in the flight-app project, as shown here:

.. roo> controller all --package ~.web

Execute the perform eclipse command to update the project's classpath settings, as shown here:

.. roo> perform eclipse

Now, import the flight-app project into your Eclipse IDE.

How to do it...

To add the json support execute the json add command against the Flight JPA entity:

~.domain.Flight roo> json add --class ~.domain.Flight
Updated SRC_MAIN_JAVA...domainFlight.java
Created SRC_MAIN_JAVA...domainFlight_Roo_Json.aj
Created SRC_MAIN_JAVA...webFlightController_Roo_Controller_Json.aj

Alternatively, add the @RooJson annotation to the Flight.java class. Adding the @RooJson annotation to the Flight entity has the same effect as executing the json add command against the Flight entity. Adding the @RooJson annotation will result in auto-generation of Flight_Roo_Json.aj and FlightController_Roo_Controller_Json.aj AspectJ ITDs.

How it works...

Executing the json add command annotates the class (specified via class argument) with the @RooJson annotation. If a class is annotated with the @RooJson annotation, Roo creates a *_Roo_Json.aj AspectJ ITD, which defines methods for converting objects of the class to JSON documents and vice versa.

We saw that when the json addon command was executed against the Flight entity, it also resulted in the creation of a FlightController_Roo_Controller_Json.aj AspectJ ITD. This ITD is created if the value of the @RooWebScaffold's exposeJson attribute in the FlightController.java class is true. If the @RooWebScaffold's exposeJson attribute is not specified, the default value is true.

If the value of the exposeJson attribute is true and the JPA entity used as the form-backing object by the web controller is annotated with the @RooJson annotation, Roo creates a *_Roo_Controller_Json.aj ITD corresponding to the web controller class. This ITD defines JSON-based methods to perform CRUD operations and execute dynamic finder methods of the JPA entity. For instance, the FlightController_Roo_Controller_Json.aj ITD introduces JSON-related methods into the FlightController.java class for performing CRUD operations on the Flight entity.

The following listing shows the methods defined in the Flight_Roo_Json.aj ITD file that was created corresponding to the @RooJson annotated Flight entity:

import flexjson.JSONDeserializer;
import flexjson.JSONSerializer;

privileged aspect Flight_Roo_Json {
    
 public String Flight.toJson() {
  return new JSONSerializer().exclude("*.class").
        serialize(this);
 }
    
 public static Flight Flight.fromJsonToFlight(String json) {
  return new JSONDeserializer<Flight>().use(null, 
         Flight.class).deserialize(json);
 }
    
 public static String Flight.
toJsonArray(
      Collection<Flight> collection) {
   ...
 }
    
 public static Collection<Flight> 
     Flight.fromJsonArrayToFlights(String json) {
        ...
 } 
}

In the given code listing, Roo makes use of the Flexj son library to incorporate support for serializing and deserializing JSON documents. The auto-generated JSON methods that are defined in Flight_Roo_Json.aj are:

  • toJson: Converts the current Flight object into a JSON document
  • fromJsonToFlight: Converts the JSON document passed as an argument into the Flight object
  • toJsonArray: Converts a collection of Flight objects into a JSON document containing an array
  • fromJsonArrayToFlights: Converts a JSON array document into a collection of Flight objects
  • If you want to customize the names of the JSON methods generated by @RooJson, you can use the following attributes of @RooJson annotation:
    • fromJsonArrayMethod: For customizing the name of the fromJsonArrayTo<class_name> method
    • fromJsonMethod: For customizing the name of the fromJson<class_name> method
    • toJsonArrayMethod: For customizing the name of the toJsonArray method
    • toJsonMethod: For customizing the name of the toJson method

The <class_name> refers to the name of the JPA entity class to which the JSON method applies. If the value of an element is "", then the corresponding method is not generated by Roo in the *_Roo_Json.aj file.

It is important to note that you can use the json add command to add JSON support to any class. For instance, if you create a MyKlass class and annotate it with @RooJson, then Roo will auto-generate the given methods where the <class-name> is MyKlass.

Tip

Excluding fields from serializing

To exclude a field from serializing to JSON format, all you need to do is to annotate the field or the corresponding getter method with the @JSON(include=false) annotation.

In some JavaScript libraries, such as EXT JS, it is expected that the JSON document contains a root node. You can instruct Roo to set the root node of the generated JSON document either by using the rootName argument of the json add command or by setting the rootName attribute of the @RooJson annotation. When the rootName argument of the json add command is used, the generated @RooJson annotation's rootName attribute is set to the value of the rootName command argument.

The following code snippet shows the Flight_Roo_Json.aj ITD when the rootName attribute of the @RooJson annotation on the Flight.java file is set to myRoot:

import flexjson.JSONDeserializer;
import flexjson.JSONSerializer;

privileged aspect Flight_Roo_Json {
    
 public String Flight.toJson() {
   return new JSONSerializer().
     rootName("myRoot").exclude("*.class").serialize(this);
 }    
 ...  
 public static String Flight.toJsonArray(
   Collection<Flight> collection) {
    return new JSONSerializer().
      rootName("myRoot").exclude("*.class").
      serialize(collection);
 } 
 ...
}

The given code shows that if the rootName attribute of the @RooJson annotation is specified, the toJson and toJsonArray methods of the *_Roo_Json.aj ITD set the root node of the JSON document to myRoot using the rootName method of the JSONSerializer object of Flexjson. The argument passed to the rootName method is the value set for the rootName attribute of the @RooJson annotation.

The following code shows the FlightController_Roo_Controller_Json.aj ITD, which was generated because the value of the @RooWebScaffold's exposeJson attribute is true in the FlightController.java file:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ResponseBody;

privileged aspect FlightController_Roo_Controller_Json {
    
  @RequestMapping(value = "/{flightId}", 
    method = RequestMethod.GET, 
    headers = "Accept=application/json")
  @ResponseBody
  public Object FlightController.
     showJson(@PathVariable("flightId") Long flightId) {
    Flight flight = Flight.findFlight(flightId);
    if (flight == null) {
      HttpHeaders headers= new HttpHeaders();
      headers.add("Content-Type", "application/text");
      return new ResponseEntity<String>(headers, 
         HttpStatus.NOT_FOUND);
    }
    return flight.toJson();
  }
  ...
}

The given code shows the showJson method that the ITD adds to the FlightController.java class. The showJson method represents one of many JSON related methods defined in the ITD. The showJson method returns a Flight object as a JSON document. The showJson method returns the JSON representation of the Flight entity whose identifier is specified via request URI. If the request URI is /flights/10, then the showJson method returns the JSON representation of the Flight entity instance whose identifier value is 10. the @ResponseBody annotation instructs the Spring Web MVC framework to write the response to the HTTP response body. The headers attribute of the @RequestMapping annotation specifies the request headers that must be present in the web request.

To test the JSON related methods defined in FlightController_Roo_Controller_Json.aj, you can use the Poster add-on of Firefox or you can use the curl command of Linux.

See also

  • Refer to the Creating a Spring MVC controller for a specific JPA entity and Auto-generating Spring MVC controllers and JSPX views from JPA entities recipes to view details of methods generated by Roo
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.12.156