MusicAppUsingRESTRemoting
Music App using RESTful Web Service Remoting
The final version of the draft tutorial below is found here:
http://www.netbeans.org/kb/60/websvc/clientstub.html
Draft Tutorial:
In this tutorial you will learn how to develop a Music App (Web 2.0 client app) using RESTful Web Service Remoting mechanism in NB 6.0. After completing the tutorial you should enjoy music!
Preparation:
0. Required Installations:
- JDK 1.6.0_01
- Latest NetBeans 6.0 bits - http://download.netbeans.org/netbeans/6.0/final/ (If you choose Full install, then GlassFish AppServer gets installed also)
- GlassFish V2 - http://download.netbeans.org/netbeans/6.0/final/ or GF website (https://glassfish.dev.java.net/)
- After installing NB 6.0, get NB 6.0 'RESTful Web Services' plugin from the NB 6.0 IDE menu "Tools->Plugins->Available Plugins. After installing the plugin(s), IDE restarts.
1. Create 'MusicDB' Web Application:
- Click on 'New Project' button to bring up the wizard, select 'Web' category and 'Web Application' project type. Click 'Next'.
- Type 'MusicDB' for project name; select GlassFish V2 for target server and 'Java EE 5' for Java EE version. Click 'Finish'.
2. Create Database 'music'
- Create a new 'music' database following the menu (in NB 6.0) "Tools"->"Java DB Database"->"Create Database". Enter name 'music", username 'music', password 'music'
- Load (see attached musicdb_MusicAppUsingRESTRemoting.sql) music script into music Database you created earlier. You can load it by opening the musicdb_MusicAppUsingRESTRemoting.sql file in IDE, then select in the Connection bar : jdbc:derby://localhost:1527/music music on MUSIC
Facts:
- Java DB (Derby) integration is included as part of NetBeans bundle. JDBC driver for Java DB, is included by both NetBeans 6.0 and AppServer.
3. Create Entity Classes:
- Right click on 'MusicDB' project and do 'New > Entity Classes from Database...'
- Create 'jdbc/music' Data Source by selecting 'New Data Source...' from the Data Source select list. Enter 'jdbc/music' in the JNDI Name and select jdbc:derby://locahost:1527/music as the Database Connection. Then click 'OK'.
- Select 'PLAYLIST', 'SONG' and 'PLAYLIST_SONG' in Available Tables column and click 'Add'. Click 'Next'.
- Click 'Create Persistence Unit' and accept all default values.
- Type in non-default package name (say 'org.music') and click 'Finish'.
4. Create RESTful web services from Entity classes:
- Right click on 'MusicDB' project in the projects tab of the IDE, do 'New > RESTful Web Services from Entity Classes'. Click 'Add All' and then 'Next'.
- Prepend package for Resource and Converter with 'org.music.' and click 'Finish'.
- The files generated by the wizard are shown below
5. Test REST Web Services:
- Right click on the project and do 'Test RESTful Web Services'.
The web application will be built, deployed and the default browser will be opened with a standalone test client page.
6. Create 'MusicApp' Web Application:
- Click on 'New Project' button to bring up the wizard, select 'Web' category and 'Web Application' project type. Click 'Next'.
- Type 'MusicApp' for project name; select GlassFish V2 for target server and 'Java EE 5' for Java EE version. Click 'Finish'.
7. Create RESTful Web Service Client Stubs:
- Right click on the project and do 'RESTful Web Service Client Stubs'. Uncheck 'Create jMaki Rest Components' (since we are only going to use base javascripts stubs), then click 'Add Project...' to add "MusicDB" RESTful Web Service project that we created earlier.
On "Finish", the client stubs are generated under "MusicApp/web/rest".
- Run the project "MusicApp", and acess page "http://localhost:8080/MusicApp/rest/TestStubs.html". You should see all playlists uri's listed under "Playlists" table
and also song uri's displayed. This tests the Client Stub generation
- File Structure of MusicApp:
8. Create template html page in Music App to display Playlists:
- Create a folder "music" under "Web Pages" ("Web Pages" physical location is 'web') folder in MusicApp project, then create an index_MusicAppUsingRESTRemoting.html page under this folder. Then copy the following contents to this file.
Note:
- I you wanted you can copy the template from index_MusicAppUsingRESTRemoting.html, and skip this section.
- If you want to skip this section, then copy the attached style_MusicAppUsingRESTRemoting.css to "Web Pages"/music and unzip the attached images_MusicAppUsingRESTRemoting.zip under "Web Pages"/music.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>DeeJay - PlayList Community</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" href="./style_MusicAppUsingRESTRemoting.css" type="text/css"/>
<script type="text/javascript" src="../rest/Support.js"></script>
<script type="text/javascript" src="../rest/musicdb/MusicDB.js"></script>
<script type="text/javascript" src="../rest/musicdb/Playlists.js"></script>
<script type="text/javascript" src="../rest/musicdb/Playlist.js"></script>
<script type="text/javascript" src="../rest/musicdb/Songs.js"></script>
<script type="text/javascript" src="../rest/musicdb/Song.js"></script>
<script type="text/javascript" src="./main_MusicAppUsingRESTRemoting.js"></script>
</head>
<body>
<div class="outerBorder">
<div class="border2">
<div class="header">
<div class="banner2"><img src="./images/b_MusicAppUsingRESTRemoting.gif" width="500" height="100"/></div>
</div> <!-- header -->
<div id="main" class="main">
<table>
<tr>
<td id="leftSidebar" class="leftSidebar bkgclr" valign="top">
<br/>
<span class="ml5">Welcome 'Geertjan'</span>
<br/>
<br/>
<table width="150">
<tr><td class="cell ht"><a href="javascript:showPlayLists()" class="links"><span class="text2">Playlists</span></a></td></tr>
</table>
</td>
<td class="seperator" valign="top"></td>
<td id="content" class="content bkgclr" valign="top">
<div id="vw_pl" class="hide">
<div class="clr"></div>
<div class="heading mglf">Playlists</div>
<div id="vw_pl_content" class="form-container"></div>
</div>
<div id="cr_pl" class="hide">
<div class="clr"></div>
<div class="heading mglf">Create Playlist</div>
<div id="cr_pl_content" class="form-container"></div>
</div>
<div id="vw_pl_item" class="hide">
<div class="clr"></div>
<div class="heading mglf">Playlists</div>
<div id="vw_pl_item_content" class="form-container"></div>
<br/><br/>
<div id="add_song_content" class="form-container"></div>
</div>
</td>
</tr>
</table>
</div> <!-- main -->
</div> <!-- border2 -->
</div> <!-- outerborder -->
<script language="Javascript">
showPlaylists();
</script>
</body>
</html>
Also
- copy the attached style_MusicAppUsingRESTRemoting.css to "Web Pages"/music
- Unzip the attached images_MusicAppUsingRESTRemoting.zip under "Web Pages"/music.
Now lets look at the /"Web Pages"/music/index_MusicAppUsingRESTRemoting.html.
What we have done is, we have added the location of MusicDB remoting scripts generated earlier.
<script type="text/javascript" src="../rest/Support.js"></script>
<script type="text/javascript" src="../rest/musicdb/MusicDB.js"></script>
<script type="text/javascript" src="../rest/musicdb/Playlists.js"></script>
<script type="text/javascript" src="../rest/musicdb/Playlist.js"></script>
<script type="text/javascript" src="../rest/musicdb/Songs.js"></script>
<script type="text/javascript" src="../rest/musicdb/Song.js"></script>
<script type="text/javascript" src="./main_MusicAppUsingRESTRemoting.js"></script>
Inside the body we have added a banner for our Application using following lines
<div class="header">
<div class="banner2"><img src="./images/b_MusicAppUsingRESTRemoting.gif" width="500" height="100"/></div>
</div> <!-- header -->
With following lines we have added a menu to the left side of the home page
<div id="main" class="main">
<table>
<tr>
<td id="leftSidebar" class="leftSidebar bkgclr" valign="top">
<br/>
<span class="ml5">Welcome 'Geertjan'</span>
<br/>
<br/>
<table width="150">
<tr><td class="cell ht"><a href="javascript:showPlayLists()" class="links"><span class="text2">Playlists</span></a></td></tr>
</table>
</td>
...
</tr>
</table>
</div> <!-- main -->
In the following section, we have added 3 Note:
- "cr_pl" is not used in this tutorial. It is left as an exercise to user to Create a playlist.
<div id="main" class="main">
<table>
<tr>
...
<td id="content" class="content bkgclr" valign="top">
<div id="vw_pl" class="hide">
<div class="clr"></div>
<div class="heading mglf">Playlists</div>
<div id="vw_pl_content" class="form-container"></div>
</div>
<div id="cr_pl" class="hide">
<div class="clr"></div>
<div class="heading mglf">Create Playlist</div>
<div id="cr_pl_content" class="form-container"></div>
</div>
<div id="vw_pl_item" class="hide">
<div class="clr"></div>
<div class="heading mglf">Playlists</div>
<div id="vw_pl_item_content" class="form-container"></div>
<br/><br/>
<div id="add_song_content" class="form-container"></div>
</div>
</td>
</tr>
</table>
</div> <!-- main -->
And finally we have added a hook to invoke a javascript function "showPlaylists()" that will be described shortly
<script language="Javascript">
showPlaylists();
</script>
9. Add javascript to Music App to handle events in the client:
Now lets create the only script that we need to write for music app. This javascript handles show playlists, show songs in playlists, etc.,
- Create an main_MusicAppUsingRESTRemoting.js javascript file under "Web Pages/music" folder of "MusicApp" project.
Note:
- I you wanted you can copy the javascript from main_MusicAppUsingRESTRemoting.js, and skip this section
Music App should display lists of playlists from the MusicDB App. To do this, lets write the script that reads all the playlists (using "Web Pages/rest/musicdb/*.js" scripts) and displays them.
Copy and Paste the following javascript snippet to the main_MusicAppUsingRESTRemoting.js file.
var playlistsObj;
function showPlaylists() {
var app = new MusicDB();
var resources = app.getResources();
for(i=0;i<resources.length;i++) {
var resource = resources[I];
if(resource instanceof Playlists) {
playlistsObj = resource;
var style = 'otab';
var str = '<div><table class="result"><tr>';
str += '<td class="tab '+style+'"><a class="links" href="javascript:createPlayList()">'+
'<span class="text2">Create Playlist</span></a></td></tr></table></div>';
var playlists = playlistsObj.getItems();
for(i=0;i<playlists.length;i++) {
var playlist = playlists[I];
var uri = playlist.getUri();
var playlistId = playlist.getPlaylistId();
var title = playlist.getTitle();
var desc = playlist.getDescription();
//alert(uri+' '+playlistId+' '+title+' '+desc);
str += "<div id='playListsTable'><a href=\"javascript:showPlayList("+i+")\" >"+title+
"</a><br/>"+desc+"</div>";
}
var node = document.getElementById('vw_pl_content');
node.innerHTML = str ;
doShowContent('vw_pl');
}
}
}
First we create a "playlistsObj" global variable, that can be shared across other functions. Next we create a "Playlists" object and set its uri. Then we create button "Create Playlist" for creating a playlist. "Playlists" object uses a function "getChildren" that returns a list of "Playlist" objects, each initialized with their uri's. A "Playlist" object has functions such as "getTitle()", "getDescription()", that help display each playlist information.
To help a user of music app to see all the songs in a playlist, we provide a link (javascript:showPlaylist(index)) along
with playlist information. Finally we update thefor displaying all playlists.
Now lets add "showPlaylist(index)" function to the main_MusicAppUsingRESTRemoting.js file.
function showPlayList(index) {
var playlist = playlistsObj.getItems()[Index];
var uri = playlist.getUri();
var playlistId = playlist.getPlaylistId();
var title = playlist.getTitle();
var desc = playlist.getDescription();
//alert(desc);
var songsObj = playlist.getSongs();
//alert(songsObj.toString());
var songs = songsObj.getItems();
//alert(songs.length);
var c = '<div><table class="result"><tr>';
c += '<td class="tab otab"><a class="links" href="javascript:addSong('+
'\''+playlistId+'\', \'playlist\', \''+uri+'\')"><span class="text2">'+
'Add Song</span></a></td>';
c += '<td class="tab otab"><a class="links" href="javascript:editPlayList('+
'\''+playlistId+'\', \''+uri+'\', \'1\')"><span class="text2">Edit</span></a></td>';
c += '<td class="tab otab"><a class="links" href="javascript:deletePlayList('+
'\''+playlistId+'\', \''+uri+'\', \'1\')"><span class="text2">Delete</span></a></td>';
c += '</tr></table></div>';
var s = '<div><b>'+title+'</b></div><br/>'+c;
var i = 0;
var str = '';
for(i=0;i<songs.length;i++) {
var song = songs[I];
//alert(song.toString());
var uri = song.getUri();
var songId = song.getSongId();
var title = song.getTitle();
var sourceUrl = song.getSourceUrl();
//alert(uri+' : '+songId+' : '+title+' : '+desc);
str += "<div id='songsTable'><a href=\"javascript:showSong('"+songId+"', '"+title+
"', '"+sourceUrl+"')\" >"+title+"</a><br/>"+sourceUrl+"</div>";
}
var node = document.getElementById('vw_pl_item_content');
node.innerHTML = s + str;
doShowContent('vw_pl_item');
}
"showPlaylist(index)" function takes an argument that identifies the playlist the user has selected in the playlistsObj's array. After retreiving playlist details, we invoke "playlist.getSongs()". This methods returns a "Songs" object, is a container for all songs in a playlist. After creating buttons to add a song to the playlist, edit playlist and delete playlist, we need to iterate through the list of song from the "Songs" object. To do this we invoke "songsObj.getChildren()". A "Song" object has functions getTitle(), getSourceUrl(). These functions let us display a song detail along with song source url.
We add a link ( javascript:showSong(songId, title, sourceUrl) ) on each song that let the user play the music. Finally we update
theNow lets add the function "showSong(id, title, songURL)" to show a selected song from the playlist
function showSong(id, title, songURL) {
var songContent = getSongOverlay(id, title, songURL);
var c = '<div><table class="result"><tr>';
var style = 'otab';
c += '</tr></table></div>';
c += songContent;
var f = document.getElementById('add_song_content');
f.innerHTML = c;
doShowContent('vw_pl_item');
}
function getSongOverlay(songId, title, songURL) {
var songContent = title;
if(songURL != '') {
if(songURL.length > 7 && songURL.substring(0, 7) == '<object') {
songContent = '<div id="video_content_'+songId+'"><br/>' + songURL+ '<br/></div>';
} else {
songContent = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'+
'codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"'+
'width="400" height="15" >'+
'<param name="allowScriptAccess" value="sameDomain"/>'+
'<param name="movie" value="./xspf/xspf_player_slim.swf"/>'+
'<param name="quality" value="high"/>'+
'<param name="bgcolor" value="#E6E6E6"/>'+
'<embed src="./xspf/xspf_player_slim.swf?playlist_url='+getPlayfile(songId)+'&autoplay=true"'+
'quality="high" bgcolor="#E6E6E6" name="xspf_player" allowscriptaccess="sameDomain"'+
'type="application/x-shockwave-flash"'+
'pluginspage="http://www.macromedia.com/go/getflashplayer"'+
'align="center" height="15" width="330"> </embed>'+
'</object>';
}
}
var sid = 'song_overlay_'+songId;
return '<div id="'+sid+'" class="songOverlay">'+songContent+'</div>';
}
function getPlayfile(songId) {
return './xspf/songs/playlist'+songId+'.xspf';
}
function doShowContent(id) {
var nodes = new Array();
nodes[0] = 'vw_pl';
nodes[1] = 'cr_pl';
nodes[2] = 'vw_pl_item';
for(i=0;i<nodes.length;i++)
{
doHideContent(nodes[I]);
}
var node = document.getElementById(id).style;
node.display="block";
}
function doHideContent(id) {
document.getElementById(id).style.display="none";
}
showSong() function creates a song overlay based on the song type. If the song source url content is
non-url (ie., an <object> tag), then that content from source url is embedded into the html page. The plugin
in the browser lets run the content. If the song url is a url, then we would display a music player from xspf
("http://sourceforge.net/projects/musicplayer/"). xspf needs a metadata file to play a song.
Note:
- doShowContent() and doHideContent() functions are used to show and hide tags.
10. Download and install XSPF Music Player:
Now lets make music player.
- Download the xspf mp3 player from http://sourceforge.net/project/downloading.php?groupname=musicplayer&filename=xspf_player_slim-correct-0.2.3.zip&use_mirror=umn
and unzip all its contents to "MusicApp/web/music/xspf" directory to play music for this music application.
Note:
- the essential file for our music player is xspf_player_slim.swf.
- Download and unzip songs_MusicAppUsingRESTRemoting.zip to "Web Pages/music/xspf/" directory. You should see 6 files with xspf extension in the songs directory.
Each file contains metadata to play a song.
- "Web Pages/music/xspf/songs/playlist1.xspf file content is shown below.
<?xml version="1.0" encoding="UTF-8"?> <playlist version="0" xmlns = "http://xspf.org/ns/0/"> <trackList> <track> <location>http://magnatune.com/all/07-Motorway-Nova%20Express.mp3</location> <image>http://he3.magnatune.com/artists/img/nova_express2.jpg</image> <annotation>Motorway</annotation> </track> </trackList> </playlist>
11. Run MusicApp and Enjoy!:
- Deploy "MusicApp". Then access page "http://localhost:8080/MusicApp/music/index_MusicAppUsingRESTRemoting.html".
You should see a cool music application. Click on the "Nova" playlist, you should see all the songs under "Nova". Click on a song link to play the song.
Note:
- "Create Playlist" button javascript event handler is intentionally left out of this exercise.
Try it!
Download the attached MusicDB_MusicAppUsingRESTRemoting.zip or MusicDB_MusicAppUsingRESTRemoting.war, MusicApp_MusicAppUsingRESTRemoting.zip or MusicApp_MusicAppUsingRESTRemoting.war, unzip and deploy to GlassFish AppServer to test the REST Remoting capability.
Attachments
- Media:musicdb_MusicAppUsingRESTRemoting.sql
- Media:musicWizard_MusicAppUsingRESTRemoting.PNG
- Media:songs_MusicAppUsingRESTRemoting.zip
- Media:MusicAppTest_MusicAppUsingRESTRemoting.PNG
- Media:index_MusicAppUsingRESTRemoting.html
- Media:MusicApp_MusicAppUsingRESTRemoting.zip
- Media:MusicApp_MusicAppUsingRESTRemoting.war
- Media:MusicDB_MusicAppUsingRESTRemoting.war
- Media:main_MusicAppUsingRESTRemoting.js
- Media:images_MusicAppUsingRESTRemoting.zip
- Media:MusicDB_MusicAppUsingRESTRemoting.zip
- Media:style_MusicAppUsingRESTRemoting.css















