 |
Community: NetBeans Archives
OpenSolaris 2008.05: Installing NetBeans 6.1
Posted by bleonard on June 19, 2008 at 10:56 AM | Permalink
| Comments (1)
Unfortunately, NetBeans 6.1 has not yet made it into the package repository for OpenSolaris 2008.05 yet. Here's how to install it.
Step 1: Install the JDK
OpenSolaris 2008.05 does not ship with the JDK, so if you haven't already done so, it needs to be installed first.
- Download JDK 6 Update 6 (or newer)
- For the Platform select Solaris x86. Even if you're running in 64-bit mode you need to install the x86 version first:

- Download the Solaris x86 packages -tar.Z. You can use the Sun Download Manager, but I just clicked the file name and saved it to a JDK folder I created on my Desktop (I created a folder so the extracted files would be easier to clean up):

- Extract the tar file. Open a terminal and enter:
cd Desktop/JDK
zcat jdk-6u6-solaris-i586.tar.Z | tar -xf -
- Install the JDK (OpenSolaris 2008.05 ships with the JRE, so there's no need to install that package):
bleonard@opensolaris:~/Desktop/JDK$ pfexec pkgadd -d . SUNWj6dev SUNWj6cfg SUNWj6man SUNWj6dmo
Processing package instance <SUNWj6dev> from </export/home/bleonard/Desktop/JDK>
JDK 6.0 Dev. Tools (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
Using </usr> as the package base directory.
## Processing package information.
## Processing system information.
4 package pathnames are already properly installed.
## Verifying package dependencies.
WARNING:
The <SUNWmfrun> package "Motif RunTime Kit" is a
prerequisite package and should be installed.
Do you want to continue with the installation of <SUNWj6dev> [y,n,?]
The Motif RunTime Kit (SUNWmfrun) isn't included with OpenSolaris 2008.05, so I'm just going to ignore this warning and continue...
Do you want to continue with the installation of <SUNWj6dev> [y,n,?] y
Installing JDK 6.0 Dev. Tools (1.6.0_06) as <SUNWj6dev>
## Installing part 1 of 1.
/usr/jdk/instances/jdk1.6.0/LICENSE
/usr/jdk/instances/jdk1.6.0/README.html
...
/usr/jdk/instances/jdk1.6.0/lib/tools.jar
/usr/jdk/instances/jdk1.6.0/src.zip
[ verifying class <none> ]
## Executing postinstall script.
Installation of <SUNWj6dev> was successful.
Processing package instance <SUNWj6cfg> from </export/home/bleonard/Desktop/JDK>
JDK 6.0 Host Config. (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
Using </> as the package base directory.
## Processing package information.
## Processing system information.
1 package pathname is already properly installed.
## Verifying package dependencies.
WARNING:
The <SUNWmfrun> package "Motif RunTime Kit" is a
prerequisite package and should be installed.
Do you want to continue with the installation of <SUNWj6cfg> [y,n,?]
You get the same warning with the Dev. Tools package. Again, continue...
Do you want to continue with the installation of <SUNWj6cfg> [y,n,?] y
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.
This package contains scripts which will be executed with super-user
permission during the process of installing this package.
Do you want to continue with the installation of <SUNWj6cfg> [y,n,?] y
Installing JDK 6.0 Host Config. (1.6.0_06) as <SUNWj6cfg>
## Installing part 1 of 1.
[ verifying class <none> ]
[ verifying class <preserve> ]
## Executing postinstall script.
Installation of <SUNWj6cfg> was successful.
Processing package instance <SUNWj6man> from </export/home/bleonard/Desktop/JDK>
JDK 6.0 Man Pages (1.6.0_06)(i386) 1.6.0,REV=2006.12.07.16.42
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
Using </usr> as the package base directory.
## Processing package information.
## Processing system information.
3 package pathnames are already properly installed.
## Verifying package dependencies.
## Verifying disk space requirements.
## Checking for conflicts with packages already installed.
## Checking for setuid/setgid programs.
Installing JDK 6.0 Man Pages (1.6.0_06) as <SUNWj6man>
## Installing part 1 of 1.
/usr/jdk/instances/jdk1.6.0/man/man1/appletviewer.1
/usr/jdk/instances/jdk1.6.0/man/man1/apt.1
...
/usr/jdk/instances/jdk1.6.0/man/man1/wsimport.1
/usr/jdk/instances/jdk1.6.0/man/man1/xjc.1
[ verifying class <none> ]
Installation of <SUNWj6man> was successful.
Processing package instance <SUNWj6dmo> from </export/home/bleonard/Desktop/JDK>
JDK 6.0 Demo Programs (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
Using </usr> as the package base directory.
## Processing package information.
## Processing system information.
3 package pathnames are already properly installed.
## Verifying package dependencies.
WARNING:
The <SUNWmfrun> package "Motif RunTime Kit" is a
prerequisite package and should be installed.
Do you want to continue with the installation of <SUNWj6dmo> [y,n,?]
And one final warning with the Demo Programs package...
Do you want to continue with the installation of <SUNWj6dmo> [y,n,?] y
/usr/jdk/instances/jdk1.6.0/sample/webservices/EbayServer/src/ebay/server/Main.java
[ verifying class <none> ]
Installation of <SUNWj6dmo> was successful.
bleonard@opensolaris:~/Desktop/JDK$
- Delete the JDK directory
cd ..
rm -r JDK
- If you're running in 64-bit mode, you can now optionally install the 64-bit version of the JDK. To check, run:
isainfo -b
The output will either be 32 or 64.
Step 2: Download NetBeans 6.1
- Download NetBeans 6.1. Personally I'm choosing the "All" packs configuration, but any of the bundles should work with these instructions. Save the NetBeans installer to your Desktop (which is the default location if you haven't configured Firefox otherwise).
Step 3: Install NetBeans 6.1
- Make the installer executable. Open a terminal and run:
chmod +x Desktop/netbeans-6.1-ml-solaris-x86.sh
- Run the installer:
./netbeans-6.1-ml-solaris-x86.sh
You'll see the following as the installer GUI starts...
bleonard@opensolaris:~/Desktop$ ./netbeans-6.1-ml-solaris-x86.sh
Configuring the installer...
Searching for JVM on the system...
Extracting installation data...
Running the installer wizard...
Followed by the welcome screen where you can continue with the installation:

Step 4: Launching NetBeans
- Once NetBeans is Installed you'll find an icon on your desktop:

- As well as a menu item under Applications > Developer Tools:

Resources
Drag & Drop with Rails
Posted by bleonard on April 18, 2008 at 11:45 AM | Permalink
| Comments (0)
The ability to drag and drop has been a staple of desktop applications for years. With the advent of Ajax, the ability to drag and drop has now found its way to web applications. In this entry I spice up the blogging application we've been building with the ability to drag comments to the trash. This is an appropriate feature to add as our own blogs here on java.net have been prone to spam attacks via the comments which require cleanup.
Setting Things Up
I'm going to continue from where the tutorial Using Ajax with Ruby on Rails leaves off. However, I'll be using NetBeans 6.1 and Rails 2.0, so you may want to start with this updated version of the rubyweblog project which has been updated to Rails 2.0 (the entire tutorial series is in the process of being updated).
Test the Existing rubyweblog Project
- Open the rubyweblog project.
- Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database (Run Rake Task > db > create) and run the migrations.
- Run the project and browse to http://localhost:3000/posts to verify that it works. Add at least one blog entry with a couple of comments.
The Plan
Currently, the application does not provide the means to delete a comment. Now, I know this application is severely lacking any sort of user model or administrative interface, but my intent is to show how to do cool things with Rails, not create a replacement for roller, so I squeeze the features in where I can. In this case, I'm going to add a trash can icon to the page and allow users to drag comments to the trash for deletion.
Step 1: Make the Comments Draggable
Here we'll employ the draggable_element helper, a Rails wrapper around the Scriptaculous Draggable object, to make the comments draggable.
- Open _comment.html.erb, which is the partial for displaying a single comment, and make it draggable by adding the draggable element helper to the bottom of the file as shown in bold below:
<% comment_id = "comment_#{comment.id}" %> <li id=<%= comment_id %> > <%= h comment.comment %><br> <div style="color: #999; font-size: 8pt"> Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %> </div> </li> <%= draggable_element(comment_id, :revert=>true) %>
Note, since comment_id is used twice, I pulled it out into a local variable to keep the code a bit cleaner. Revert returns the comment to its original location if we drop it anywhere but on the trash can (which we haven't added yet).
- Add a visual indicator that the comments are draggable. Open scaffold.css (Public > stylesheets) and add the following style:
#comments { cursor: -moz-grab; }
- Test your changes. The comments are now draggable, but we haven't specified anywhere to drop them yet.
Step 2: Add the Trash Icon
- Save
(trashfull.jpg) to the public/images directory of your rubyweblob project directory.
- Open show.html.erb and add the following <image_tag> after the <text_area>:
<%= text_area 'comment', 'comment' %> <%= image_tag "trash.jpg", :id=>'trash'%>
Step 3: Make the Trash Icon a Drop Receiver
Here we'll use the drop_receiving_element helper, a Rails wrapper around the Scriptaculous Droppables.add method to give the comment a drop destination and call the action to delete the comment.
- Open show.html.erb and add the drop_receiving_element to the bottom of the file as show below:
<%= drop_receiving_element('trash', # The id of the receiving element :accept => "comment", # The CSS class of the dropped element :with => "'comment=' + (element.id.split('_').last())", # The query string parameters :url => {:action=>:trash_comment} # The action to call )%>
Note the :with parameter - this is a piece of JavaScript code that extracts the comment ID form the DOM ID, which if you recall from above is something like "comment_123". We also still have some work to do: first, we don't have anything with a CCS class named "comment" and second we need to code the trash_comment action.
- Open _comment.html.erb and add class="comment" to the <li> tag:
<li class="comment" id=<%= comment_id %> >
- Open posts_controller.rb and add the following trash_comment action:
def trash_comment comment_id = params[:comment] Comment.delete(comment_id) render :update do |page| page.replace_html "comment_#{comment_id}", "" end end
- Test your changes. Dragging a comment to the trash can should delete it and clear it from the list, although the bullet still remains. That's because the replace_html method above is replacing the html inside of the bulleted list item. Wrapping the bulleted list items in a <div> solves this problem.
- Open _comment.html.erb and wrap the <li> in a <div>, also moving the class and id properties to the <div>:
<% comment_id = "comment_#{comment.id}" %> <div class="comment" id=<%= comment_id %> > <li> <%= h comment.comment %><br> <div style="color: #999; font-size: 8pt"> Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %> </div> </li> </div> <%= draggable_element(comment_id, :revert=>true) %>
- Now the comments should delete completely.
Step 4: Adding Visual Clues That Something's Happening
- Save
(trashfull.jpg) to the public/images directory of your rubyweblob project directory.
- Add a couple of JavaScript methods to show.html.erb to swap the source of the trash image from empty to full and back:
<script> function fill_trash() { $('trash').src = "/images/trashfull.jpg"; } function empty_trash() { $('trash').src = "/images/trash.jpg"; } </script>
- Add a couple of properties to the drop_receiving_element method, :onHover and :complete:
<%= drop_receiving_element('trash', # The id of the receiving element :accept => "comment", # The CSS class of the dropped element :with => "'comment=' + (element.id.split('_').last())", # The query string parameters :url => {:action=>:trash_comment}, # The action to call :onHover => "function() {fill_trash()}", :complete => "empty_trash()" )%>
Note, I can't tell you why :onHover requires a function definition while :complete takes any arbitrary JavaScript, but that's the way it works.
- Test your changes. You should now see a full garbage can when you drag a comment over it and then empty again once the delete completes.
- There's still one minor problem - if you drag a comment over the trash but don't actually drop it, your trash can remains full. We can fix this using the onMouseOut event. Add it to the image_tag as follows:
<%= image_tag "trash.jpg", :id=>'trash', :onMouseOut=>"empty_trash()"%>
And that should pretty much complete the drag and drop functionality. Remember to refresh the browser to pick up changes to Javascript. Also, Firebug is your friend whenever you're working with Ajax and not seeing what you're expecting.
The Completed Application
RubyWeblogDND.zip
Autovalidation with Rails
Posted by bleonard on April 16, 2008 at 12:31 PM | Permalink
| Comments (0)
Actually, I don't know what this feature is called, but I love it when a web application gives me instant feedback on the validity of my entry. For example:

This is especially true when I'm registering a new user account - submitting the page over and over again because the username I've selected is already taken or the password doesn't meet the requirements is always a drag.
So I started looked for examples on how to do this in Rails and couldn't really find anything (possibly because I don't actually know what to call it) - I guess it's most similar to autocompletion, so I'm going with autovalidation. And here are the steps I've put together to get it to work...
Setting Things Up
- Download and install MySQL.
- Download and install NetBeans 6.1 RC1 or later.
Creating the Rails Project
- Create a new Ruby on Rails Application named autovalidation. You can select Finish after the first page of the New Ruby on Rails Application dialog:

- Right-click the project and select Run Rake Task > db > create:

- Right-click the project and select Generate. Generate a scaffold with the Model Name User and the Attribute Pairs username:string:

- Right-click the project and select Migrate Database > To Current Version.
- Open user.rb and type the following:
vu[tab]
- this will expand to:

type username over the attribute and press enter.
- On the next line in user.rb type the following:
vl[tab] this will expand to:

type username over the attribute and press enter. Type 5..10 over the 3..20 and press enter. The completed code should look as follows:
class User < ActiveRecord::Base
validates_uniqueness_of :username
validates_length_of :username, :within => 5..10
end
Traditional Server Side Validation
- Run the project and browse to http://localhost:3000/users. Try to create a new user such as bill:

- Okay, create william.
- Try to create william again:

Let's enhance this application with more user friendly "autovalidation"...
Lets Autovalidate
In addition to the server side validation that's being performed, we're going to add some client side validation using Ajax. We'll do this by displaying a message to the right of the field on the validity of what's been entered. Since we're validating against the database, we will need to make an XMLHTTPRequest back to the server. We can use Rails' observe_field helper method for this task.
- First we need to create a named placeholder for the message. Open new.html.erb and add a <span> tag after the text field as follows:
<%= f.text_field :username %><span id="message"></span>
- Now we'll use Rails' observe_field method to watch changes to that field. Add the following before the closing <% end %> tag:
<%= observe_field :user_username, # The field to observe :with => "username", # The input to validate :frequency => 0.25, # The frequency in seconds to watch for changes :url => {:action => :validate }, # The action to call when changes occur :update => :message # The DOM ID to update %>
- Create the validate action. Open users_controller.rb and add the following:
def validate color = 'red' username = params[:username] if username.length < 5 message = 'Too short' elsif username.length > 10 message = 'Too long' else user = User.find_all_by_username(username) if user.size > 0 message = 'Taken' else message = 'Available' color = 'green' end end @message = "<b style='color:#{color}'>#{message}</b>" render :partial=>'message' end
You'll notice in the last line of the validate action above we're rendering a partial. This partial, which we'll create next, will be dynamically rendered inside the span tag we defined in step 1 above.
- Create a new ERB file named _message in Views > users. Replace its contents with the following:
<%= @message %>
- Open users.html.erb and add the following before the closing </head> tag:
<%= javascript_include_tag 'prototype' %>
All Rails applications come with the prototype and scriptaculous libraries ready to use, but you do need to tell the application that you want to use them.
Run with Autovalidate
- Switch to the browser and start creating a new user (you'll need to refresh the browser once to load the prototype JavaScript libraries):




Troubleshooting
Firebug is your friend for troubleshooting Rails applications. With Firebug enabled, you can see the requests as you type:
A couple of things that tripped me up
Forgetting to include the Prototype libraries:

Misspelling the field to observe:

The Completed Application
autovalidation.zip
Blogging for Dollars (and T-Shirts)
Posted by bleonard on March 18, 2008 at 11:37 AM | Permalink
| Comments (0)
The NetBeans team has started a blogging contest. Simply download the NetBeans 6.1 Beta and tell us your thoughts. What, you're not a blogger? Well, here are some places to get started:
See the blogging contest web site for details on how to enter, ideas for your blog, rules and deadlines.
Hello Grails!
Posted by bleonard on January 30, 2008 at 06:37 PM | Permalink
| Comments (19)
NetBeans 6.1 M1 was just released, and with it comes rudimentary support for the Groovy language and the Grails framework. I say rudimentary because this is M1, but there's a lot of work in progress as you can see from this task list.
So, of course I'm anxious to compare Grails to Rails. What better way to do than by creating the same blog application I've been blogging about with Rails?
Setting Things Up
Unlike with Rails, the NetBeans Groovy plugin does not come bundled with Groovy and the Grails framework - these must be pre-installed on your system (don't worry, it's easy):
- Download and install Groovy
- Download and install Grails
- Download and install NetBeans 6.1 M1.
- Install the Groovy and Grails plugin (Tools > Plugins > Available Plugins)
- Open the NetBeans Options dialog and select the Groovy category. Set the Groovy and Grails home directories.
Creating the Grails Project
- Choose File > New Project to create a new Grails Application named GroovyWebLog. Your new Grails application will appear in the IDE:

Creating the Model
Or as Grails prefers to call them, Domain classes.
- Right-click the Domain classes node and select "Create new Domain Class":

- Name the class Post.
- When Post.groovy opens in the editor, add a single field, title:
class Post {
String title
}
Creating the Controller
- Right-click the Controllers node and select "Create new controller"
- Name the controller Blog.
- For now, we'll use dynamic scaffolding to create the application views at runtime. Replace the default contents of BlogController with the following:
class BlogController {
def scaffold = Post
}
Note, if our controller named matched the domain class name, we could then use def scaffolding = true. I kept the model and controller names different to match what we did with Rails.
Run the Application
- Right-click the GrailsWebLog project and select Grails > Run Application.
- If all goes well, NetBeans will start the Jetty server that comes bundled with Grails and launch your browser where you will see the Grails welcome page:

- Click the BlogController link:

- Create a New Post:

It's not immediately obvious, but the Id is a link which you can use to view the post details. From the detail page you can then edit and/or delete the post:

Adding Another Field
Our blog needs a body field.
- Edit Post.groovy and add a body field:
class Post {
String title
String body
}
- Return to the browser and depending on what you do, you may get an error. By default Grails is configured to drop and create the database every time a change is made, so if you tried to edit the existing record you were viewing, you got a NullPointerException. However, if you navigate back to the list, you will see that the body field has been detected and you can add a new record again:

A Friendlier Database Configuration
Surprisingly, we haven't had to talk about databases yet as the Grails framework magically took care of this for us. The Grails framework includes HSQLDB and all of the necessary configuration was setup for us in DataSource.groovy, which you'll find under the Configuration node:

You can also see from this configuration file that Grails supports the same three environments as Rails: development, test and production. It's also easy to switch to another database, just set the driver class name, jdbc url and copy the JDBC driver to the project's lib directory.
Do the following:
- Change the dbCreate property from "create-drop" to "update".
- Right-click the GrailsWebLog project and choose Grails > Stop Application.
- Richt-click the project again and choose Grails > Run Application.
- Now experiment with adding and/or deleting fields - you'll notice that the behavior is much more "Railsesque".
Validating Input
Like Rails, validation in Grails is very straightforward.
- Open Post.groovy and add the following constraints:
class Post {
String title
String body
static constraints = {
title(blank:false)
body(blank:false)
}
}
- Attempt to add a new Post without entering any data:

Customizing the View
Okay, enough with this dynamic scaffolding. Let's generate our controller and view code. Unfortunately, for this step I haven't found the menu option in NetBeans yet, so we'll resort to the command line for now.
- Open your command prompt and navigate to the GrailsWebLog project directory. If you've forgotten where this is, you can find it in the project's Properties dialog.
- Run the command grails generate-all Post:

- Now this created a new controller named PostController. I don't see a way to specify a controller name when using generate-all (or generate-controller). That's fine - I'll leave BlogController to do the dynamic scaffolding and use PostController for my customizations.
- Also created were a set of GSP (Groovy Server Pages) for managing the view for the PostController:

- Open list.gsp and delete everything from from the <h1>Post List<h1> to the </div> following the pagination buttons. In its place put the following:
<h1>The Groovy Blog</h1>
<g:each in="${postList}" var="post">
<h2>${post.title}</h2>
<p>${post.body}</p>
<small><g:link action="show" id="${post.id}">permalink</g:link></small>
<hr>
</g:each>
- Return to the browser and refresh the list page:

- To display the blog with the most recent entry first, add .reverse() to the end of postList in list.gsp:
<g:each in="${postList.reverse()}" var="post">

The Completed Application
GrailsWebLog.zip
Testing Rails Applications
Posted by bleonard on January 04, 2008 at 11:04 AM | Permalink
| Comments (0)
All well developed applications are supported by tests. In this entry I extend the web log I've been building to include some unit, functional and integration tests.
Setting Things Up
I'm going to begin from where I left off in my previous post: An Introduction to using AJAX with Rails: Take 2. Alternatively, you can start from RubyWeblogAJAX.zip, which is the completed project from that post.
Test the RubyWeblog Project
- Open the rubyweblog project.
- Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database and run the migrations.
- Run the project and browse to http://localhost:3000/blog to verify that it works.
The Plan
We're going to look at the facilities Rails provides for testing our model classes, controller classes and entire application.
Model Testing (Unit Tests)
The Rails framework uses unit tests for testing of the model classes. Back when we first created the Post model class, a couple of test files were created for us, test/unit/post_test.rb and test/fixtures/post.yml:

The post.yml file contains test data that's made available to the unit test and reloaded in the database every time the test is run. Don't worry, this isn't going to affect your development database, but rather the test database that's configured in database.yml, which we haven't created yet:

Create the rubyweblog_test Database
- Switch to the Services window and expand the Databases node. We'll use an existing MySQL connection to create the test database. If you don't already have an existing MySQL database connection, create one for the development database.
- Expand the Drivers node, right-click the MySQL driver and choose Connect Using
- Set the Database URL to: jdbc:mysql://localhost/rubyweblog_development
- Set the User Name to: root
- Leave the Password blank
- Click OK to establish the connection
- Right-click an existing MySQL connection (connect first if not already) and select Execute Command.
- Enter create database rubyweblog_test
- Right-click the commend and select Run Statement
Prepare the Database
We need to run the migrations against the test database. This is done using the rake task db:test:prepare
- Right-click the rubyweblog project and choose Run Rake Task > db > test > prepare
Run the Default Unit Test
The default unit test that was created for us when the model was generated is very basic and really only servers to prove our test environment is properly configured.
- Open post_test.rb
- Right-click the file and select Run File.

If for some reason the test fails to run, the error messages are generally descriptive enough to alert you to the problem, like "Unknown database 'rubyweblog_test' if you forgot to create the test database first.
Test the Validations
The post model is pretty simple and doesn't offer a lot to test, but it does have a couple of validations when can test, so therefore, we can assert that an empty model is invalid:
def test_invalid_with_empty_attributes
post = Post.new
assert !post.valid? # An empty Post model will be invalid
assert post.errors.invalid?(:title) # The title field will have validation errors
assert post.errors.invalid?(:body) # The body field will have validation errors
end
Using Fixture Data
To give us something more to test, let's require blog titles be unique.
- Navigate to the tested class (Navigate > Go to Tested Class)
- Add
validates_uniqueness_of :title
- Open fixtures/post.yml and add the following:
first:
id: 1
title: George Jetson
body: Was a man ahead of his time
- Navigate back to the post_test.rb and add the following test method:
def test_unique_title
post = Post.new(:title => posts(:first).title, # Pull the title from the fixture
:body => "Whatever")
assert !post.save
assert_equal "has already been taken", post.errors.on(:title)
end
Run the Tests
There are several way to run the test:
- From the test file, right-click the file and choose Run File or Test File, as both do the same when executed from a test file.
- From the tested class, right-click the file and choose Test File.
Controller Testing (Functional Tests)
When the scaffolding was generated, Rails also generated a functional test stub in the test/functional directory, which has 8 tests for the actions created by the generator (index, list, show, new, create, edit, update, destroy).
- Open test/functional/blog_controller_test.rb.
- Right-click the file and choose Run File. You should see one failure:

This failure is caused by the validations we've added to the Post model as this line from the test_create method doesn't pass any arguments in with the post:
post :create, :post => {}
(Note, the first "post" in the line above refers to the HTTP Post method, while ":post" refers to the Post model).
- Add required parameters to the empty :post hash:
post :create, :post => { :title => "Astro",
:body => "Was loved by George" }
All 8 tests and 25 assertions should now pass.
Testing the post_comment Action
The default tests provide excellent examples on how to create tests for other controller actions. I'll create a new test for the additional controller action we've created since the controller was generated, post_comment:
def test_post_comment
xhr :post, # Simulate xml_http_request
:post_comment, # the action to call
{ :comment => { :comment => "What about Jane?" }}, # the parameters to post
nil, # session variables expected by the action
{ :post_id => 100 } # flash variables expected by the action
assert_response :success
assert_template '_comment'
assert_equal 'Comment was successfully added.', flash[:notice]
assert_equal 'What about Jane?', Comment.find_by_post_id(100).comment
end
Application Testing (Integration Tests)
Integration tests are used for testing application flow and generally test a scenario of events. The blog application is very simple, but we can still create a test scenario such as creating an entry, viewing the entry, editing the entry and adding a comment.
Integration tests are very much like functional tests, but since they can span multiple controllers you have to pass the controller as well as the action to the HTTP method (e.g., get "/blog/index"). Also, the Rails framework has not created a default integration test file for us, one must first be generated.
- Generate an Integration Test named ApplicationUsage.
- Add the following test method:
def test_creating_a_post
# Clear the database tables
Comment.delete_all
Post.delete_all
# Load the home page
get "/blog/index"
assert_response :success
assert_template "list"
# Load the New post page
get "/blog/new"
assert_response :success
assert_template "new"
# Create a new blog post
post "/blog/create", :post => { :title => "Integration Test Title",
:body => "Integration Test Body"}
assert_response :redirect
# Get the post variable from the controller so we can fetch the generated id
# which we'll use to get the record.
post_id = @controller.instance_variable_get(:@post).attributes['id']
# Show the newly created post
get "/blog/show/#{post_id}"
assert_response :success
assert_template "show"
# Edit the post
get "/blog/edit/#{post_id}"
assert_response :success
assert_template "edit"
# Post the edits
post "/blog/update/#{post_id}", :post => { :title => "Integration Test Title Updated",
:body => "Integration Test Body Updated"}
assert_response :redirect
# Verify the post exists
posts = Post.find(:all)
assert_equal 1, posts.size
# Confirm it's contents
post = posts[0]
assert_equal "Integration Test Title Updated", post.title
assert_equal "Integration Test Body Updated", post.body
end
- Run the file to execute the test.
You may have noticed that the test above does not test adding a comment. This is because I couldn't figure out how to set the flash from an integration test. Here's the signature for the xhr method I used from the functional test:
xhr(request_method, action, parameters = nil, session = nil, flash = nil)
and here's the signature for the xhr method for integration testing:
xhr(request_method, path, parameters = nil, headers = nil) And I just don't see a way to set the flash. If anyone knows, please let me know.
Running All Tests
You can run the entire suite of tests by selecting Run > Test "rubyweblog" or right-clicking the project and selecting Test. You'll also see a nice summary at the bottom of the editor window (this summary is there for every test run - it's just more useful in this case because it shows the aggregate of all test runs).

The Completed Application
RubyWebLogTested.zip
References
An Introduction to using AJAX with Rails: Take 2
Posted by bleonard on December 04, 2007 at 04:25 PM | Permalink
| Comments (0)
In my first take on introducing AJAX with Rails, when a new comment is posted to an entry, the entire set of existing comments is replaced with a new set containing the new comment. Although the request is asynchronous, it's still inefficient, especially if the list of comments grows large. Ideally I would just insert the new comment to the bottom of the existing list, and that's what I show here.
Setting Things Up
I'm going to begin where the Building Relationships Between Rails Models tutorial leaves off. Alternatively, you can start from RubyWeblogComments.zip, which is the completed project from that tutorial.
Test the rubyweblog Project
- Open the rubyweblog project.
- Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database and run the migrations.
- 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 just insert the new comment to the bottom of the list. Just for fun, I will also show you 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 insert, that being a single comment, into a partial template.
- Open show.rhtml
- Cut the following block of code from show.rhtml
<li><%= h comment.comment %><br>
<div style="color: #999; font-size: 8pt">
Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
</div>
</li>
- Create a new RHTML file named _comment and place it in the app\views\blog folder.
- Paste in the code you cut above, replacing all existing content in _comment.rhtml.
- Return to show.rhtml and insert a call to the partial from where you cut the code. Also, place a <div> tag with the id of "comments" inside the <ul> elements. We'll use this div to refer to this block of HTML when we insert the new comment. The new chunk of code in show.html should now look as follows:
<ul>
<div id="comments">
<% @post_comments.each do |comment| %>
<%= render :partial=>"comment", :object => comment %>
<% end %>
</div>
</ul>
- Test your changes. The application should behave as it did before.
Change the POST to an XMLHTTPRequest
- First, let's make sure the JavaScript libraries we're going to use are included in our application. 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.
- 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 %>
- Test. The entire page is no longer reloaded on submit. This is because submit is now performing an XMLHTTPRequest rather that a POST. As a matter of fact, it appears as though nothing has happened. However, if you refresh the browser at this point, you will see the comments are indeed being added.
- Open blog_controller.rb and navigate to the post_comment action.
- Replace the existing redirect_to method with the following render method:
render :update do |page|
page.insert_html :bottom, 'comments', :partial => 'comment'
page[:comment_comment].clear
flash.keep(:post_id)
end
The code above is dynamically inserting the _comment.rhtml partial into the bottom of the "comments" <div> we defined above. It's important to keep the post_id in the flash, otherwise, any additional comments the user decides to insert will have a nil post_id, and will therefore be orphaned (there's no referential integrity defined on the comments table).
- Test and our comment should now be dynamically inserted into the bottom of the list.
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.
- 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 unique, deterministic id to each comment - what better than the comment id itself? Open _comment.rhtml and add the following id property to the <li> element:
<li id=<%= "comment_#{comment.id}" %>>
- Then switch to blog_controller.rb and add the following to the block provided by render :update:
page["comment_#{@comment.id}"].visual_effect :highlight, :duration => 3.5
- Test the end result:
The highlight will appear for 3 1/2 seconds and then fade away.
Troubleshooting
Working with AJAX can be frustrating because when things go wrong you often don't get a notification in the browser (or if you do, it's a bunch of confusing JavaScript). In such cases I found the server output invaluable. For example, if you misspell the partial "comment" above when inserting the html, nothing happens when you click Post to add the comment. However, looking at the server's output shows the following helpful message:

The Completed Application
RubyWeblogAJAX.zip
Rails and JPA (Instead of ActiveRecord)
Posted by bleonard on September 26, 2007 at 08:30 AM | Permalink
| Comments (10)
Out of sheer morbid curiosity, I wondered what it would take to replace ActiveRecord with JPA in the classic blog demo. Jeroen Zwartepoorte, a developer I met last week at RailsConf, convinced me to go ahead and publish my results.
In almost all cases, I tried to keep the view and controller code similar to what you would expect from generated scaffolding, so all of the JPA code is isolated in the model class. I also refrained from making any changes to the Java entity classes, but certainly that's also a route worth exploring.
Getting Started
- Download and install NetBeans 6.0 Beta 1. Grab the Full distribution so you can get the Java IDE, Ruby and GlassFish.
Creating the Java Entity Classes
For consistency, I'm going to create the same blog application that's know to every Rails developer. However, instead of generating a model and running migrations, we'll create an Entity class and a persistence unit.
- Create a new Java Application named Post. There's no need for a Main Class.
- Create a new Persistence Unit. Select jdbc:derby://localhost:1527/sample [app on App] as the database connection and click Finish. Switch the the XML view and set the toplink.jdbc.password property to app.
- Create a new Entity Class named Posts. Set the package name to entity.
- Add fields and accessors for title and body. Your completed class should look as follows:
/*
* Posts.java
*
* Created on Sep 26, 2007, 10:15:53 AM
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
*
* @author bleonard
*/
@Entity
public class Posts implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String title;
private String body;
public void setId(Long id) {
this.id = id;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
Test the Entity Classes
- Create a new JUnit Test named PostsTest in the entity package. You can uncheck the Test Initializer and Finalizer, we will not be using them.
- Add code to initialize the Entity Manager and test the Post entity. My complete PostTest class looks as follows:
/*
* PostsTest.java
* JUnit 4.x based test
*
* Created on September 24, 2007, 7:42 PM
*/
package entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author bleonard
*/
public class PostsTest {
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("PostPU");
private static EntityManager em = emf.createEntityManager();
private static EntityTransaction trans = em.getTransaction();
public PostTest() {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testPersist() {
// Persist some data...
trans.begin();
Posts post = new Posts();
post.setId(new Long(100));
post.setTitle("George");
post.setBody("Jetson");
em.persist(post);
trans.commit();
// Retrieve the data...
Posts result = em.find(Posts.class, new Long(100));
assertEquals(post, result);
//Clean up for the next test...
trans.begin();
em.remove(post);
trans.commit();
}
}
- Add the Java DB Driver Library to the project's Test Libraries.
- Start the Database (Tools > Java DB Database > Start Server)
- Press Shift+F6 to run the test:
Create the Rails Application
Now that we appear to have a functioning entity class, let's create the Rails application that will use that class.
- Create a new Ruby on Rails application named jpa_blog.
- Generate a controller named blog with views list, new, show and edit. We'll develop each of these views in turn.
- In the Models folder, create a new Ruby class named Post (note, we are not generating a Post model).
Step 1: Listing the Entries
Code the View
- Replace the contents of list.rhtml with the following:
<h1>The Ruby Blog</h1>
<% @posts.reverse.each do |post| %>
<h2><%= post.title %></h2>
<p><%= post.body %></p>
<small> <%= link_to 'Permalink', :action => 'show', :id => post %></small>
<hr>
<% end %><br />
<%= link_to 'New post', :action => 'new' %>
Code the Controller
- Add the following to blog_controller.rb:
def index
list
render :action => 'list'
end
def list
# Declare a paginator for the posts table
@post_pages, @posts = paginate :posts, :per_page => 10
end
Code the Model
- Add the following to the top of post.rb:
require 'java'
include_class 'javax.persistence.Persistence'
include_class 'javax.persistence.EntityManager'
include_class 'javax.persistence.EntityManagerFactory'
include_class 'java.util.List'
include_class 'java.lang.Long'
include_class 'entity.Posts'
- Add the accessors:
attr_accessor :id, :title, :body
- Define private methods for getting the entity manager and finding all rows in the table:
private
def self.getEntityManager
emf = Persistence.createEntityManagerFactory("PostPU")
return emf.createEntityManager()
end
def self.find_all
query = getEntityManager.createQuery("SELECT p FROM Posts p")
list = query.getResultList()
posts = [] #Create a new array to return
list.each {|post|
temp = Post.new
temp.id = post.getId
temp.title = post.getTitle
temp.body = post.getBody
posts << temp
}
return posts
end
- Define the methods that will be called by the paginate method used in the controller (these are public):
# Called by `paginate'
def self.count(*args)
query = getEntityManager.createQuery("SELECT p FROM Posts p")
count = query.getResultList().size();
puts count
end
def self.find(*args)
case args.first
when :all then find_all
else find_from_id(args.first)
end
end
Configure JRuby
- Open the Options dialog to find the location of your JRuby interpreter.
- Copy the following jars to your JRuby lib directory:
- Post.jar (build your project if you don't have a Post.jar)
- derbyclient.jar (Tools > Java DB Database > Settings will give you the location of derbyclient.jar)
- toplink-essentials.jar and toplink-essentials-agena.jar (check the Library Manager for the location of TopLink Essentials)
Test the List
This will not be very exciting because the list is empty (you can tweak the unit test to add some entries). But we will verify the application runs without exceptions. With your cursor in the index action, press F6 to start WEBrick and launch the browser. Browse to http://localhost:3000/blog.
Step 2: Creating a New Entry
Code the View
- Create a new partial, _form.rhtml, to be used by both the new and edit pages:
<p>Title<br/>
<%= text_field 'post', 'title' %></p>
<p>Body<br/>
<%= text_area 'post', 'body' %></p>
- Replace the contents of new.rhtml with the following:
<h1>New post</h1>
<% form_tag :action => 'create' do %>
<%= render :partial => 'form' %>
<%= submit_tag "Create" %>
<% end %>
<%= link_to 'Back', :action => 'list' %>
Code the Controller
- Add the following to blog_controller.rb:
def create
@post = Post.new(params[:post])
if @post.save
flash[:notice] = 'Post was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
Code the Model
- Define the initialize and save methods in post.rb:
def initialize(attributes = nil)
if !attributes.nil?
@title = attributes[:title]
@body = attributes[:body]
end
end
def save
p = Posts.new
p.title = title
p.body = body
em = Post.getEntityManager
em.getTransaction().begin()
em.persist(p);
em.getTransaction().commit()
return true
end
Test Adding a New Entry
- Return to the browser and click the new link. Add a new post.


Step 3: Viewing an Entry
Code View
- Replace the contents of show.rhtml with the following:
<p>
<b>Title:</b> <%= h @post.title %>
</p>
<p>
<b>Body:</b> <%= h @post.body %>
</p>
<%= link_to 'Edit', :action => 'edit', :id => @post %>
<%= link_to 'Back', :action => 'list' %>
Code the Controller
- Add the following to blog_controller.rb:
def show
@post = Post.find(params[:id])
end
Code the Model
- Add the following to_param convenience method which I copied from base.rb:
# Copied from base.rb. Allows us to specify post rather than post.id in list.rhtml.
# Enables Active Record objects to be used as URL parameters in Action Pack automatically.
def to_param
# We can't use alias_method here, because method 'id' optimizes itself on the fly.
(id = self.id) ? id.to_s : nil # Be sure to stringify the id for routes
end
- Add the following private method:
def self.find_from_id(id)
result = getEntityManager.find(Posts.java_class, Long.new(id))
post = Post.new
post.id = result.get_id
post.title = result.get_title
post.body = result.get_body
return post
end
Test Viewing and Entry
- Return to your browser, refresh the page (so the Permalink is generated correctly) and click the Permalink:

Step 4: Editing an Entry
Code the View
- Replace the contents of edit.rhtml with the following:
<h1>Editing post</h1>
<% form_tag :action => 'update', :id => @post do %>
<%= render :partial => 'form' %>
<%= submit_tag 'Edit' %>
<% end %>
<%= link_to 'Show', :action => 'show', :id => @post %>
<%= link_to 'Back', :action => 'list' %>
Code the Controller
- An edit and update methods to blog_controller.rb:
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
if @post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
redirect_to :action => 'show', :id => @post
else
render :action => 'edit'
end
end
Code the Model
- Add the update_attributes to post.rb:
def update_attributes(attributes)
p = Posts.new
p.id = id
p.title = attributes[:title]
p.body = attributes[:body]
em = Post.getEntityManager
em.getTransaction().begin()
em.merge(p);
em.getTransaction().commit()
return true
end
Test Editing an Entry
- Return to your browser and click the Edit link:


Resources
Rails to Java via REST
Posted by bleonard on August 16, 2007 at 03:37 PM | Permalink
| Comments (5)
Since I've been studying the Rails framework, I've had an interest in integration with Java. Yes, JRuby is one possible solution, but if you have some large Java system that you want to integrate with, it' unlikely that you're just going to get the jar files to access that system's APIs. More likely is that system will expose itself as a service, and the service type du jour is REST.
So, in this entry I'm going to expose an entity class as a RESTful web service and then create a Rails client for that entity.
Setting Things Up
- Download and install NetBeans 6.0 M10. Grab the Full distribution so you can get the Java IDE, Ruby and GlassFish.
- Download and install the SWDP to GlassFish. This is required to create the RESTful web service.
Creating the RESTful Web Service
Here we'll expose the manufacturer table as a RESTful web service.
Create the Manufacturer Entity Class
- Start NetBeans 6.0 and create a new Web Application named Manufacturers.
- Right-click the project and select Entity Classes from Database.
- Select jdbc/sample as the Data Source and MANUFACTURER as the Table (your list of available tables will be different then mine, but you should have MANUFACTURER):
- Click Next and set the package to model.
- Click the Create Persistence Unit button and then Create on the Create Persistence Unit dialog:

- Click Finish to generate the Manufacturer entity class.
Create the REST Web Service from the Entity Class
- Right-click the project and select REST Web Services from Entity Classes
- Select the Manufacturer Entity Class and click Next.
- Set the package to rest and click Finish.
Test the REST Services
- Right-click the project and choose Test REST Services.
- This will deploy the Manufacturers application to GlassFish and launch a Test REST Services tool:
This tool is very handy for working with the RESTful interface.
The Completed Project
Manufacturers.zip
Creating the Rails REST Client
If you know REST then you know that its operations are basically the HTTP methods: POST, GET, UPDATE and DELETE, which correspond nicely to SQL's Create, Read, Update and Delete. I will implement each one in turn.
GET the Manufacturers
Create the Project
Create a new Ruby on Rails Application named manufacturer_client.
Create a Model to Represent the Manufacturer
The Manufacturer entity contains a bunch of fields. For the purposes of this tutorial, we're only going to work with a handful of them: name, email and phone.
- Since we're not using ActiveRecord, we're not going to run the model generator. Instead, right-click the Models folder and select New > Ruby Class.
- Name the class Manufacturer.
- Add the following code:
require 'open-uri'
class Manufacturer
BASE_URI = 'http://localhost:8080/Manufacturers/restbean/manufacturers/'
attr_accessor :manufacturerId, :name, :email, :phone
def initialize(id, name=nil, email=nil, phone=nil)
@manufacturerId, @name, @email, @phone = id, name, email, phone
end
def uri
BASE_URI + manufacturerId
end
def get
doc = REXML::Document.new(open(uri).read)
@name = REXML::XPath.first(doc, "//name").text
@email = REXML::XPath.first(doc, "//email").text
@phone = REXML::XPath.first(doc, "//phone").text
end
end
Generate a Controller and View to Display the Manufacturers
- Right-click the project and choose Generate. Select Controller and set the Name to Manufacturer and the Views to index list.
- Redirect the index to the list:
def index
list
render :action => 'list'
end
- Define list as follows:
def list
@manufacturers = []
doc = REXML::Document.new(open(Manufacturer::BASE_URI).read)
REXML::XPath.each(doc, "//manufacturerId/") do |entry|
id = entry.text
@manufacturers << Manufacturer.new(id)
end
@manufacturers.each do | manufacturer |
manufacturer.get
end
return @manufacturers
end
Code the View the Display the Manufacturers
- Open list.rhtml and replace its contents with the following:
<h1>Manufacturer List</h1> <table> <tr> <th>Manufacturer Name</th> <th>Phone</th> </tr> <% for manufacturer in @manufacturers %> <tr> <td><a href="mailto:<%= manufacturer.email%>"><%= manufacturer.name %></a></td> <td><%= manufacturer.phone %></td> </tr> <% end %> </table>
Test
- Test F6 to run the project and hit: http://localhost:3000/manufacturer:

Getting the rest-open-uri Gem
Before we can continue, the open-uri library we're using above only supports HTTP GET. Fortunately for us, Leonard Richardson has extended the library (rest-open-uri) to accept the additional HTTP methods.
- Open the Gem Manager: Tools > Ruby Gems
- Select the New Gems tab and enter rest-open-uri in the Search field:
- Install the rest-open-uri gem:
- Restart your server. This is necessary for the new library to be picked up.
POST new Manufacturers
- Add the following link to the bottom of list.rhtml:
<p>
<%= link_to 'New Manufacturer', :action => 'new' %>
- Right-click the Views > manufacturer folder and create a new rhtml file named _form. We'll use this partial for both the new and edit pages. Populate it with the following:
<p>Name<br/>
<%= text_field 'manufacturer', 'name' %></p>
<p>E-Mail<br/>
<%= text_field 'manufacturer', 'email' %></p>
<p>Phone<br/>
<%= text_field 'manufacturer', 'phone' %></p>
- Right-click the Views > manufacturer folder and create a new rhtml file named new. Populate it with the following:
<h1>New Manufacturer</h1> <% form_tag :action => :create do %>
<p>Manufacturer ID<br/>
<%= text_field 'manufacturer', 'manufacturerId' %></p>
<%= render :partial => 'form' %>
<%= submit_tag "Create" %>
<% end %>
<%= link_to 'Back', :action => 'list' %>
- Switch to the ManufacturerController and add the following create action:
def create
values = params[:manufacturer]
@manufacturer = Manufacturer.new(values[:manufacturerId], values[:name], values[:email], values[:phone])
if @manufacturer.post
redirect_to :action => 'list'
else
render :action => 'new'
end
end
- Switch to the Manufacturer model and add the post method and and a couple of helper methods:
def post
value = get_as_xml
args = prepare_args(:post, value)
result = open(BASE_URI, args)
puts 'HTTP Status: '
puts result.status
return true if result.status[0] = 201
end
private
def get_as_xml
result = "<manufacturer>"
instance_variables.each do | var| var.sub!('@', '')
puts send(var)
result += "<#{var}>" + send(var) + "</#{var}>"
end
result += "</manufacturer>"
end
def prepare_args(http_method, body)
args = {:method => http_method}
args["Content-Type"] = "application/xml"
args["Content-Length"] = body.size.to_s
args[:body] = body
return args
end
- Test:: http://localhost:3000/manufacturer/new
PUT Updates Back
- Open list.rhtml and add the following column to the end of the table:
<td><%= link_to 'Edit', :action => 'edit', :id => manufacturer.manufacturerId %></td>
- Right-click the Views > manufacturer folder and create a new rhtml file named edit. Populate it with the following:
<h1>Editing Manufacturer</h1>
<% form_tag :action => "update", :id => @manufacturer.manufacturerId do %>
<%= hidden_field 'manufacturer', 'manufacturerId' %></p>
<%= render :partial => 'form' %>
<%= submit_tag 'Edit' %>
<% end %> <%= link_to 'Back', :action => 'list' %>
- Switch to the ManufacturerController and add the following edit and update actions:
def edit
@manufacturer = Manufacturer.new(params[:id])
@manufacturer.get
end
def update
values = params[:manufacturer]
@manufacturer = Manufacturer.new(values[:manufacturerId], values[:name], values[:email], values[:phone])
@manufacturer.update
redirect_to :action => 'list'
end
- Switch to the Manufacturer and add the update method:
def update
doc = REXML::Document.new(open(uri).read)
manufacturer = REXML::XPath.first(doc, "//manufacturer/")
manufacturer.elements.each do |element|
case element.name
when 'name'
element.text = @name
when 'email'
element.text = @email
when 'phone'
element.text = @phone
end
end
value = manufacturer.to_s
args = prepare_args(:put, value)
result = open(uri, args)
puts 'HTTP Status: '
puts result.status
end
- Test http://localhost:3000/manufacturer/edit/19985678
DELETE Manufacturers
This is the easiest one :-).
- Open list.rhtml and add the following column to the end of the table:
<td><%= link_to 'Delete', :action => 'delete', :id => manufacturer.manufacturerId %></td>
- Press Ctrl+Shift+A to switch to the ManufacturerController and add the following delete action:
def delete
uri = Manufacturer::BASE_URI + params[:manufacturerId]
result = open(uri, :method => :delete)
puts result.status
redirect_to :action => 'list'
end
- Test: http://localhost:3000/manufacturer/list. Now you can delete all those entries you added above :-).
Summary
And there you have it, full CRUD operations against a RESTful Web Service. Now this application can use a lot of improvements, like basic error handling and validatation. Pagination on the list page would also be nice. All potential topics for a future blog :-).
The Completed Project
Resources
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
- Start NetBeans 6.0 and create a new Web Application named hello.
- 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.
- 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.
- To associate the resource with a URI we use a UriTemplate annotation as follows:
@UriTemplate("/hello")
public class Hello {
- Next, define a method to handle the request:
public String sayHello() {
return new String("Hello there.");
}
- 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.");
}
- 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.
- Alt+Shift+O to open private.properties and add the following:
rest.support.on=true
- 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.
- Ctrl+1 to switch to the Projects tab.
- 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
- Open Project Properties and select the Run category. Set the Relative URL to /restbean/hello.
- 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
- Open the BlogDemo project.
- Note, if you are starting with the provided BlogDemo project, you will also need to create the BlogDemo_development database and run the migrations.
- 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
- Generate a new model named Category.
- 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)"
Category.create(:category => 'Java')
Category.create(:category => 'Ruby')
Category.create(:category => 'JavaScript')
Category.create(:category => 'NetBeans')
Category.create(:category => 'Personal')
end
- 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
- Right-click the project and select Migrate Database > To Current Version:

- 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
- Alt+Shift+O to open the _form.rhtml partial.
- 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 |