创星网络[分享知识 传递快乐]

标题: RESTful services with jQuery and Java using JAX-RS and Jersey [打印本页]

作者: luinstein    时间: 2012-12-13 23:05
标题: RESTful services with jQuery and Java using JAX-RS and Jersey
NOTE: This is the Java version of this article and its companion app. A PHP version is available here.
This is a more in depth version of my previous post on the same topic. The previous article only covered the HTTP GET method for building RESTful services. This article (and its new  companion app) provides an example of building a complete RESTful API using the different HTTP methods:
The application used as an example for this article is a Wine Cellar app. You can search for wines, add a wine to your cellar, update and delete wines.

You can run the application here. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.

The REST API consists of the following methods:
MethodURLAction
GET/api/winesRetrieve all wines
GET/api/wines/search/ChateauSearch for wines with ‘Chateau’ in their name
GET/api/wines/10Retrieve wine with id == 10
POST/api/winesAdd a new wine
PUT/api/wines/10Update wine with id == 10
DELETE/api/wines/10Delete wine with id == 10

Implementing the API using JAX-RSJAX-RS makes it easy to implement this API in Java. You simply create a class defined as follows:
  1. package org.coenraets.cellar;

  2. @Path("/wines")
  3. public class WineResource {

  4.     WineDAO dao = new WineDAO();

  5.     @GET
  6.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  7.     public List<Wine> findAll() {
  8.         return dao.findAll();
  9.     }

  10.     @GET @Path("search/{query}")
  11.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  12.     public List<Wine> findByName(@PathParam("query") String query) {
  13.         return dao.findByName(query);
  14.     }

  15.     @GET @Path("{id}")
  16.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  17.     public Wine findById(@PathParam("id") String id) {
  18.         return dao.findById(Integer.parseInt(id));
  19.     }

  20.     @POST
  21.     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  22.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  23.     public Wine create(Wine wine) {
  24.         return dao.create(wine);
  25.     }

  26.     @PUT @Path("{id}")
  27.     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  28.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  29.     public Wine update(Wine wine) {
  30.         return dao.update(wine);
  31.     }

  32.     @DELETE @Path("{id}")
  33.     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  34.     public void remove(@PathParam("id") int id) {
  35.         dao.remove(id);
  36.     }
  37. }
复制代码
Quick look at the JAX-RS annotations used in this class:
The jQuery client below sends data to the server using JSON (addWine() and updateWine() methods).
The approach you use to actually retrieve the data is totally up to you. In this example, I use a simple DAO, but you can of course use your own data access solution.
Testing the API using cURLIf you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try:
You will only be able to test your GET services that way, and even then, it doesn’t give you full control to test all the content types your API can return.
A more versatile solution to test RESTful services is to use cURL, a command line utility for transferring data with URL syntax.
For example, using cURL, you can test the Wine Cellar API with the following commands:
The jQuery ClientAccessing your API through cURL is cool, but there is nothing like a real application to put your API to the test. So the source code (available for download at the end of this post) includes a simple jQuery client to manage your wine cellar.
Here is the jQuery code involved in calling the services:
  1. function findAll() {
  2.     $.ajax({
  3.         type: 'GET',
  4.         url: rootURL,
  5.         dataType: "json", // data type of response
  6.         success: renderList
  7.     });
  8. }

  9. function findByName(searchKey) {
  10.     $.ajax({
  11.         type: 'GET',
  12.         url: rootURL + '/search/' + searchKey,
  13.         dataType: "json",
  14.         success: renderList
  15.     });
  16. }

  17. function findById(id) {
  18.     $.ajax({
  19.         type: 'GET',
  20.         url: rootURL + '/' + id,
  21.         dataType: "json",
  22.         success: function(data){
  23.             $('#btnDelete').show();
  24.             renderDetails(data);
  25.         }
  26.     });
  27. }

  28. function addWine() {
  29.     console.log('addWine');
  30.     $.ajax({
  31.         type: 'POST',
  32.         contentType: 'application/json',
  33.         url: rootURL,
  34.         dataType: "json",
  35.         data: formToJSON(),
  36.         success: function(data, textStatus, jqXHR){
  37.             alert('Wine created successfully');
  38.             $('#btnDelete').show();
  39.             $('#wineId').val(data.id);
  40.         },
  41.         error: function(jqXHR, textStatus, errorThrown){
  42.             alert('addWine error: ' + textStatus);
  43.         }
  44.     });
  45. }

  46. function updateWine() {
  47.     $.ajax({
  48.         type: 'PUT',
  49.         contentType: 'application/json',
  50.         url: rootURL + '/' + $('#wineId').val(),
  51.         dataType: "json",
  52.         data: formToJSON(),
  53.         success: function(data, textStatus, jqXHR){
  54.             alert('Wine updated successfully');
  55.         },
  56.         error: function(jqXHR, textStatus, errorThrown){
  57.             alert('updateWine error: ' + textStatus);
  58.         }
  59.     });
  60. }

  61. function deleteWine() {
  62.     console.log('deleteWine');
  63.     $.ajax({
  64.         type: 'DELETE',
  65.         url: rootURL + '/' + $('#wineId').val(),
  66.         success: function(data, textStatus, jqXHR){
  67.             alert('Wine deleted successfully');
  68.         },
  69.         error: function(jqXHR, textStatus, errorThrown){
  70.             alert('deleteWine error');
  71.         }
  72.     });
  73. }

  74. // Helper function to serialize all the form fields into a JSON string
  75. function formToJSON() {
  76.     return JSON.stringify({
  77.         "id": $('#id').val(),
  78.         "name": $('#name').val(),
  79.         "grapes": $('#grapes').val(),
  80.         "country": $('#country').val(),
  81.         "region": $('#region').val(),
  82.         "year": $('#year').val(),
  83.         "description": $('#description').val()
  84.         });
  85. }
复制代码
Download the Source CodeThe source code for this application is hosted on GitHub here. And here is a quick link to the project download (Eclipse Dynamic Web Project). It includes both the Java and jQuery code for the application.
UPDATE (1/11/2012): A version of this application using Backbone.js at the client-side is also available on GitHub here. You can find more information on the Backbone.js of this application here.
I’m interested in your feedback. Let me know what you think and what your experience has been building RESTful-based applications using Java and jQuery.

from:http://go.cxweb.com.cn/dhsgt





欢迎光临 创星网络[分享知识 传递快乐] (http://bbs.cxweb.com.cn/) Powered by Discuz! X3