下面已具体的例子演示开发End-to-End RESTful WebService。
完整代码参考http://springsfeng.iteye.com/blog/1634753附件。
网络资源:http://suhuanzheng7784877.iteye.com/blog/1090370
1. 创建用于Request和Reponse的对象
import java.util.Collection; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Category") public class Category { private String categoryId; private String categoryName; private Collection<Book> books; //get和set方法 ...... }
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Book") public class Book { private String bookId; private String bookISBNnumber; private String bookName; private String author; //get和set方法 ...... }
2. 创建服务实现类
//JAX-RS Imports import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; /* * CategoryService class - Add/Removes category for books */ @Path("/categoryservice") @Produces({"application/json","application/xml"}) public class CategoryService { private CategoryDAO categoryDAO = new CategoryDAO(); public CategoryDAO getCategoryDAO() { return categoryDAO; } public void setCategoryDAO(CategoryDAO categoryDAO) { this.categoryDAO = categoryDAO; } @GET @Path("/category/{id}") @Produces({"application/json","application/xml"}) public Category getCategory(@PathParam("id") String id) { System.out.println("getCategory called with category id: " + id); Category cat = (Category) getCategoryDAO().getCategory(id); if (cat == null) { ResponseBuilder builder = Response.status(Status.BAD_REQUEST); builder.type("application/xml"); builder.entity("<error>Category Not Found</error>"); throw new WebApplicationException(builder.build()); } else { return cat; } } @POST @Path("/category") @Consumes({"application/json","application/xml"}) public Response addCategory(Category category) { System.out.println("addCategory called"); Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId()); if (cat != null) { return Response.status(Status.BAD_REQUEST).build(); } else { getCategoryDAO().addCategory(category); return Response.ok(category).build(); } } @DELETE @Path("/category/{id}") @Consumes({"application/json","application/xml"}) public Response deleteCategory(@PathParam("id") String id) { System.out.println("deleteCategory with category id : " + id); Category cat = (Category) getCategoryDAO().getCategory(id); if (cat == null) { return Response.status(Status.BAD_REQUEST).build(); } else { getCategoryDAO().deleteCategory(id); return Response.ok().build(); } } @PUT @Path("/category") @Consumes({"application/json","application/xml"}) public Response updateCategory(Category category) { System.out.println("updateCategory with category id : " + category.getCategoryId()); Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId()); if (cat == null) { return Response.status(Status.BAD_REQUEST).build(); } else { getCategoryDAO().updateCategory(category); return Response.ok(category).build(); } } @POST @Path("/category/book") @Consumes({"application/json","application/xml"}) public Response addBooks(Category category) { System.out.println("addBooks with category id : " + category.getCategoryId()); Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId()); if (cat == null) { return Response.status(Status.NOT_FOUND).build(); } else { getCategoryDAO().addBook(category); return Response.ok(category).build(); } } @GET @Path("/category/{id}/books") @Consumes({"application/json","application/xml"}) public Response getBooks(@PathParam("id") String id) { System.out.println("getBooks called with category id : " + id); Category cat = (Category) getCategoryDAO().getCategory(id); if (cat == null) { return Response.status(Status.NOT_FOUND).build(); } else { cat.setBooks(getCategoryDAO().getBooks(id)); return Response.ok(cat).build(); } } }
3. 创建Server端,使用内嵌的Jetty启动:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.pbdp.sample.rest.Category; import org.pbdp.sample.rest.CategoryService; import org.springframework.context.support.ClassPathXmlApplicationContext; public class CategoryServerStart { public static void main(String[] args) { ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "org/pbdp/sample/rest/restapp.xml" }); CategoryService categoryService = (CategoryService) appContext.getBean("categoryService"); // Service instance JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean(); restServer.setResourceClasses(Category.class); restServer.setServiceBean(categoryService); restServer.setAddress("http://localhost:9000/"); restServer.create(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { br.readLine(); } catch (IOException e) { } System.out.println("Server Stopped"); System.exit(0); } }
4. 创建Client端
import java.util.Iterator; import org.apache.cxf.jaxrs.client.WebClient; import org.pbdp.sample.rest.Book; import org.pbdp.sample.rest.Category; public class CategoryServiceClient { public static void main(String[] args) { // Service instance WebClient client = WebClient.create("http://localhost:9000/"); Category category = client.path("categoryservice/category/001").accept("application/xml").get(Category.class); System.out.println("Category details from REST service."); System.out.println("Category Name " + category.getCategoryName()); System.out.println("Category Id " + category.getCategoryId()); System.out.println("Book details for Category " + category.getCategoryId() + " from REST service"); WebClient clientBook = WebClient.create("http://localhost:9000/"); Category categoryBooks = clientBook.path("categoryservice/category/001/books").accept("application/xml").get(Category.class); Iterator<Book> iterator = categoryBooks.getBooks().iterator(); while (iterator.hasNext()) { Book book = iterator.next(); System.out.println("Book Name " + book.getBookName()); System.out.println("Book ISBN " + book.getBookISBNnumber()); System.out.println("Book ID " + book.getBookId()); System.out.println("Book Author " + book.getAuthor()); } } }
5. 配置REST WebService在Tomcat中启动
<jaxrs:server id="categoryRESTService" address="/"> <jaxrs:features> <cxf:logging /> </jaxrs:features> <jaxrs:serviceBeans> <ref bean="categoryService" /> </jaxrs:serviceBeans> </jaxrs:server>
6. 运行测试
(1) 运行CategoryServerStart;
(2) 运行CategoryServiceClient
Client输出:
Category details from REST service. Category Name Java Category Id 001 Book details for Category 001 from REST service Book Name Spring Series Book ISBN ISB001 Book ID 001 Book Author Naveen Balani Book Name CXF Series Book ISBN ISB002 Book ID 002 Book Author Rajeev Hathi
Server输出:
getCategory called with category id: 001 getBooks called with category id : 001
(3) 浏览器访问,如:
http://localhost:9000/categoryservice/category/001
http://localhost:9000/categoryservice/category/001/books
7. CXF RESTful WebService异常处理
JAX-RS提供了WebApplicationException(继承自RuntimeException), WebApplicationException采用HTTP状态
码或javax.ws.rs.core.Response作为给客户端的响应。如CategoryService中的代码:
ResponseBuilder builder = Response.status(Status.BAD_REQUEST); builder.type("application/xml"); builder.entity("<error>Category Not Found</error>"); throw new WebApplicationException(builder.build());