根据上篇博客,我们知道WebService有两种实现规范,实现了JAX-RS这种规范的技术有CXF、RESTLET、JERSEY。这篇博客简单地介绍以CXF来实现WebService的实例。
JAX-RS规范定义了创建RESTful服务的语法。JAX-RS使用annotations注解实现RESTful的服务,使用annotations注解POJO将它暴露为RESTful资源。
0.创建一个Web项目,引入jar包:
包结构如图:
1.使用@XmlRootElement注解POJO类
package entity;
import java.util.Set;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Categorys")
public class Category {
private String categoryId;
private String categoryName;
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
}
在POJO类Category中,注解@XmlRootElement指定Category为XML的根元素。Category类的属性默认指定映射为@XmlElement。@XmlElement用来定义XML中的子元素。@XmlRootElement和@XmlElement允许自定义命名空间和XML中元素的名称。如果没有定义的话,JAXB在运行的时候默认的使用同样的属性名和类名来定义XML元素。
该POJO类可以对应XML文件为:
005
Fiction Series
2、dao代码,未使用数据库存储数据,采用map容器存储数据。下面代码中有对Category增删改查四个方法。
package dao;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import entity.Category;
public class CategoryDao {
private static Map categoryMap = new HashMap();
static{
Category c1 = new Category();
c1.setCategoryId("001");
c1.setCategoryName("java");
categoryMap.put(c1.getCategoryId(), c1);
}
public void addCategory(Category category){
categoryMap.put(category.getCategoryId(), category);
}
public Category getCategory(String id){
Category cat = null;
if(categoryMap.get(id) != null){
cat = new Category();
cat.setCategoryId(categoryMap.get(id).getCategoryId());
cat.setCategoryName(categoryMap.get(id).getCategoryName());
}
return cat;
}
public void deleteCategory(String id) {
categoryMap.remove(id);
// Remove association of books
bookMap.remove(id);
}
public void updateCategory(Category category) {
categoryMap.put(category.getCategoryId(), category);
}
}
3.Service层
package service;
import javax.websocket.server.PathParam;
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.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import dao.CategoryDao;
import entity.Category;
@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")
@Produces(MediaType.APPLICATION_XML)
public Category getCategory(@QueryParam("id") String id){
System.out.println("获取的ID为"+id);
Category category = categorydao.getCategory(id);
if(category == null){
ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
builder.type("application/xml");
builder.entity("Category Not Found ");
throw new WebApplicationException(builder.build());
}else{
return category;
}
}
/*@GET
@Path("/category/{idno}")
@Produces({"application/json","application/xml"})
public Category getCategory(@PathParam("idno") String id){
System.out.println("获取的ID为"+id);
Category category = categorydao.getCategory(id);
if(category == null){
ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
builder.type("application/xml");
builder.entity("Category Not Found ");
throw new WebApplicationException(builder.build());
}else{
return category;
}
}*/
@POST
@Path("/category")
@Consumes({"application/json","application/xml"})
public Response addCategory(Category category){
Category cat = (Category) categorydao.getCategory(
category.getCategoryId());
if (cat != null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
categorydao.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) categorydao.getCategory(id);
if (cat == null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
categorydao.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) categorydao.getCategory(
category.getCategoryId());
if (cat == null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
categorydao.updateCategory(category);
return Response.ok(category).build();
}
}
}
服务类注解:CategoryService的类声明上定义了@Path 和@Produces注解。@Path定义了URI路径,客户端可以通过这个路径访问到CategoryService对象。如@Path("/categoryservice"),那么URI请求,就可以是http://localhost:9000/categoryservice/。@Produces定义了服务类和方法生产内容的类型。如@Produces("application/xml"),那么CategoryService只会生产application/xml。方法注解:每个方法都和@Produces相关,它决定了这个方法生产什么样的响应。每个方法都有和HTTP方法映射的的注解,例如@GET 和@POST。方法中的@Path注解指定了该方法的URI。例如getCategory()方法上的@Path("/category/{id}"),可以使用http://localhost:9000/categoryservice/category/001,访问到category id 为001的分类。{id}就好比参数。接着,让我们看看@PathParam注解。@PathParam注解是用来给URI 路径一个模板变量,方法的输入参数。@PathParam("id") 就是URI中的 @Path ("/category/{id}")。
4.启动RESTFUL服务
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import entity.Category;
import service.CategoryService;
public class CategoryServerStart {
public static void main(String[] args) {
// Service instance
CategoryService categoryService = new CategoryService();
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);
}
}
5.现在我们可以简单地测试一个查询方法。直接在浏览器中地址栏输入地址。采用@PathParam使用如下地址:http://localhost:9000/categoryservice/category/001,
采用@QueryParam使用如下地址http://localhost:9000/categoryservice/category?id=001
看到的效果如下: