The Source for Java Technology Collaboration
User: Password:



Brian Leonard's Blog

July 2007 Archives


An Introduction to Building RESTful Web Services in Java Using NetBeans 6.0

Posted by bleonard on July 18, 2007 at 12:54 PM | Permalink | Comments (10)

So, REST based web services are simpler than SOAP, right? Then why's it so difficult to create a REST based web service in Java? Using tools I can crank out a SOAP based web service in seconds - not so easy with REST. But help is on the way.

JSR 311: JAX-RS: The Java API for RESTful Web Services aims to simplify the process. Paul Sandoz, co-specification lead along with Marc Hadley, does a nice job of introducing JAX-RS in the presentation he delivered last month at Jazoon, specifically by comparing the work you'd have to do using just the servlet API versus the proposed JAX-RS annotations.

The Sun Web Developer Pack contains an early access implementation of JAX-RS along with a tutorial. The tutorial starts with your standard hello application, but it provides a working copy of the application rather than instructions how how to build it from scratch. That's where I come in...

Setting Things Up

  • Download and install NetBeans 6.0. If you don't already have GlassFish installed, grab the Standard and Full distribution which has it included.
  • Download and install the SWDP to GlassFish.

Creating the hello Application

  1. Start NetBeans 6.0 and create a new Web Application named hello.
  2. Expand GlassFish under the Libraries node to verify that the SWDP was properly installed. If so, you'll see restbeans-api.jar and restbeans-impl.jar:



    If you do not see the rest libraries, try removing and adding the GlassFish to NetBeans.

  3. Create a new Java class named Hello. Set the package name to anything you like. I used rest. Hello will be a "resource class" identifiable by a URI.

  4. To associate the resource with a URI we use a UriTemplate annotation as follows:

    @UriTemplate("/hello")
    public class Hello {

  5. Next, define a method to handle the request:

        public String sayHello() {
            return new String("Hello there.");
        }

  6. Then use an HttpMethod annotation to indicate which type of HTTP request it responds to: GET, POST, PUT or DELETE.

        @HttpMethod("GET")
        public String sayHello() {
            return new String("Hello there.");
        }

  7. Finally, use a ProduceMime annotation to specify what type should be returned to the client:

        @HttpMethod("GET")
        @ProduceMime("text/plain")
        public String sayHello() {
            return new String("Hello there.");
        }

Building the hello Application

Before we can deploy the application, we need to generate a class that will load our resource classes (hello in our case), into the application. JAX-RS ships with an annotation processor that will generate this class for us. And NetBeans 6.0 ships with the Ant tasks necessary to call the annotation processor. You'll find it in build-impl.xml. The only problem is these tasks will only run if REST support is turned on:



and NetBeans 6.0 does not yet include an option to turn on REST support via the project's properties, so we just have to do it manually.

  1. Alt+Shift+O to open private.properties and add the following:

    rest.support.on=true
  2. Press F11 to build the project and generate the class RESTBeansResources, which you'll find in the build/generated/rest-gen/restbeans folder under the Files tab:



There's one more piece to the runtime puzzle, and that's the servlet that kicks everything off, which is provided by the JAX-RS runtime: com.sun.ws.rest.impl.container.servlet.ServletAdaptor. If you look in the WEB-INF directory above, you see a web.xml, which loads this servlet, was also generated for us:

  <servlet>
    <servlet-name>RESTBeans Application</servlet-name>
    <servlet-class>
        com.sun.ws.rest.impl.container.servlet.ServletAdaptor
    </servlet-class>
    <init-param>
      <param-name>resourcebean</param-name>
      <param-value>restbeans.RESTBeansResources</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>RESTBeans Application</servlet-name>
    <url-pattern>/restbean/*</url-pattern>
  </servlet-mapping>


However, the contents of this web.xml did not make it into our distributable.

  1. Ctrl+1 to switch to the Projects tab.
  2. Open web.xml under Configuration Files, switch to the XML view, and paste the code above just after the opening web-app tag.

Running the Application

  1. Open Project Properties and select the Run category. Set the Relative URL to /restbean/hello.
  2. Press F6 to run the application:



How It All Works

Much of how all of this works is explained in detail in the resources I list below. I found the RESTful Web Services tutorial and the Getting Started With RESTful Web Services Development articles particularly useful. However, in summary, we have an application flow which looks like the following:

ServletAdapter => RESTBeansResources => Hello

The ServletAdapter is provided by the JAX-RS runtime and loads the generated RESTBeansResources class, which in turn provides the REST resources - Hello in our application. The URL, /hello/restbean/hello, breaks down as follows:

/hello - the context root, configured in sun-web.xml
/restbean - mapped to the ServletAdapter, configured in web.xml
/hello - mapped to the Hello resource, configured using the @UriTemplate annotation in the Hello resource itself.

The Working Application

Admittedly, the application is very simple, but the real point of this post was to get you up and running with JAX-RS in NetBeans 6.0. It should now be possible to continue with the other exercises provided in the tutorial.

Resources



Using Selection Lists in Rails

Posted by bleonard on July 10, 2007 at 07:17 AM | Permalink | Comments (0)

Selection lists (drop down boxes) are common to just about every web application. In this entry I extend the web log I've been building to include a category selection list.

Setting Things Up

I'm going to begin from where I left off in my previous post: An Introduction to Using AJAX with Rails. Alternatively, you can start from BlogDemoAJAX.zip, which is the completed project from that post.

Test the BlogDemo Project

  1. Open the BlogDemo project.
  2. Note, if you are starting with the provided BlogDemo project, you will also need to create the BlogDemo_development database and run the migrations.
  3. Run the project and browse to http://localhost:3000/blog to verify that it works.

The Plan

We're going to add the ability to assign our blog entries a category. We're going to do this by providing a list of categories to choose from when the entry is created. The list of available categories will be retrieved from a database table.

Step 1: Create the Categories Model

  1. Generate a new model named Category.
  2. Open CreateCategories and add the following to the self.up method which will create the categories table with the category string, create a category reference in the posts table (which will be required), and for good measure, define the foreign key relationship. Oh yeah, we also insert some test data.

      def self.up
        create_table :categories do |t|
          t.column 'category', :string
        end
    
        add_column 'posts', 'category_id', :integer, {:null => false}
       
        execute "alter table posts add constraint fk_post_categories " <<
        "foreign key (category_id) references categories(id)"
         
        # Insert some test data...
        Category.create(:category => 'Java')
        Category.create(:category => 'Ruby')
        Category.create(:category => 'JavaScript')
        Category.create(:category => 'NetBeans')
        Category.create(:category => 'Personal')
      end

  3. For completeness, add the following to the self.down method:

      def self.down
        execute "alter table posts drop foreign key fk_post_categories"
        remove_column 'posts', 'category_id'
        drop_table :categories
      end

  4. Right-click the project and select Migrate Database > To Current Version:



  5. If you try to create a new blog entry now, it will fail because category_id can't be null:

Add the Category Select List

  1. Alt+Shift+O to open the _form.rhtml partial.
  2. Here we'll use the select helper to create our drop down box. Above the post title in _form.rhtml, add the following:

    <!--[form:post]-->
    <p><label for="post_category">Category</label><br/>
    <%= select 'post', 'category_id',
    Category.find(:all).collect {|c| [c.category, c.id]},
    :prompt => "Select a Category" %>
    'post' and 'category_id' map to the post model just like the title and body fields. The 3rd parameter:

    Category.find(:all).collect {|c| [c.category, c.id]},
    returns a collection of all the categories (for display to the user) and their associated ids (for storage in the post tables category_id field). The final parameter:

    :prompt => "Select a Category" %> 
    Just set's prompt instructing the user to select a category.

  3. Now we should be able to create an entry if we select a category:



  4. But if you fail to select a category, we get the same 'category_id' cannot be null error.

Validate Presence

  1. Alt+Shift+O to open Post.
  2. Type vp+tab to insert the validates_presence_of template and set the :attribute to :category_id

    validates_presence_of :category_id
  3. Save and try to insert the post again without a category selected:

Display the Selected Category

As a final step we're going to update the show page to display the post's category.

  1. Alt+Shift+0 to open show.rhtml.
  2. Replace the for loop at the top of the file with the following:

    <p><b>Category:</b> <%= @post.category.category %></p>
    <p><b>Title:</b> <%= @post.title %></p>
    <p><b>Body:</b> <%= @post.body %></p>
  3. Save and browse to the show page:




    Although we set up the foreign key relationship between posts and categories in our database, Rails knows nothing about it.

  4. Switch to post.rb and add the following:

    belongs_to :category
    And try again:

 

The Completed Application

BlogDemoCategory.zip


An Introduction to using AJAX with Rails

Posted by bleonard on July 06, 2007 at 11:16 AM | Permalink | Comments (1)

The Rails framework comes bundled with the Prototype and Scriptaculous Javascript libraries. In this entry I'll introduce how to use those libraries in a Rails application.

Setting Things Up

I'm going to begin from where I left off in my previous post: Rails and Model Relationships. Alternatively, you can start from BlogDemoComments.zip, which is the completed project from that post.

Test the BlogDemo Project

  1. Open the BlogDemo project.
  2. Note, if you are starting with the provided BlogDemo project, you will also need to create the BlogDemo_development database and run the migrations.
  3. Run the project and browse to http://localhost:3000/blog to verify that it works.

The Plan

Currently, when a new comment is added, the entire page - blog entry and comments - are reloaded. Instead, we'll use AJAX to only reload the comments. Just for fun, we will also show how to apply a visual effect to highlight the most recently added comment.

Preparation

First we're going to move the fragment of rhtml that we want to dynamically reload into a partial template.

  1. Ctrl+N to create a new RHTML file. Name the file _comments and place it in the app\views\blog folder.
  2. Alt+Shift+O to open show.rhtml.
  3. Cut the following block of code from show.rhtml:



    And paste it into _comments.rhtml, replacing all existing content in _comments.rhtml.

  4. Return to show.rhtml and insert the following call to the partial from where you cut the code. Note, the <div> will be used later to reference this chuck of code when we dynamically reload the comments:

    <div id="comments">
        <%= render(:partial => "comments", :object => @post_comments) %>
    </div>
  5. Test your changes. The application should behave as it did before.

Change the POST to an XMLHTTPRequest

  1. First, let's make sure the JavaScript libraries we're going to use are included in our application. Alt+Shift+O to open blog.rhtml and add the following line below the stylesheet_link_tag:

     <%= javascript_include_tag :defaults  %>
    We're passing :defaults as the source because we're going to be using the Prototype and Scriptaculous libraries that come bundled with Rails.

  2. In show.rhtml, change the form_tag, which performs a HTTP POST, to a form_remote_tag, which performs an XMLHTTPRequest, as follows:

    <% form_remote_tag :url => {:action => "post_comment"} do %>

  3. Test. The entire show page is still reloaded on submit. This is because the post_comment action in blog_controller forces the reload by calling the show action.



  4. Comment out the redirect_to call in the post_comment action and try again. Things are getting worse, as now we get a Template is missing error:



    This is actually progress, as now we can insert an RJS (Ruby JavaScript) template to handle the XMLHTTPRequest.

  5. Right-click the Views -> blog folder and select New -> Empty RJS Template. Name the template post_comment.

  6. Now we'll use the page object to replace the html at the <div> we labeled "comments" above:

    page.replace_html "comments", :partial => "comments", :object => @post_comments
  7. Test again:



    As the message indicates, the problem is with line 4 above -- @post_comments is nil. If we look back into the blog_controller, @post_comments was being set in the show action, which we are no longer calling.

  8. Add the following three lines after the redirect we commented out earlier in post_comment action:

          #redirect_to :action => 'show', :id => flash[:post_id]
          @post = Post.find(flash[:post_id])
          @post_comments = @post.comments.collect    
          flash[:post_id] = @post.id  #Store the post.id back in the flash 
  9. Test one final time and our comments should now be dynamically updated.

Apply Visual Effects

The Scriptaculous library comes with a bunch of visual effects. I'm going to apply the highlight effect to the comment just posted. Once in place, you can easily swap in and try out any of the other effects.

  1. Like we did above for the entire comments section, we need to label the comment to which we want to apply the visual effect. We'll do this by adding a div to the most recently added comment. Open _comments.rhtml and replace the <li> line with the following:

        <% if @post_comments.index(comment) == @post_comments.length-1 %> 
    <!-- This is our new comment --> <li id="new_comment"><%=h comment.comment %><br> <% else%> <li><%=h comment.comment %><br> <% end %>
  2. Then switch to post_comment.rjs and add the following:

    page[:new_comment].visual_effect :highlight
  3. Test the end result:



    The highlight will appear for just a second and then fade away.

 

The Completed Application

BlogDemoAJAX.zip




Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds