使用CXF发布REST服务现在很多大公司在用,它的主要优点在于可以精确定位目标访问资源,访问路径很短,可以返回JSON数据,不需要创建专门的客户端。缺点是访问路径 不好理解,安全性不如SOAP好。且REST的设置比较麻烦
废话不说,上代码:
- 创建JAVA项目,将CXF的jar包引入
- 创建Bean
package com.ckinghan.bean;
import javax.xml.bind.annotation.XmlRootElement;
/**
* 商品实体类
* @author Ckinghan
*/
//注解表示可以将实体类映射成xml文件,并指定了标签名为shop,这个在使用XML返回数据时,可以看到
@XmlRootElement(name="shop")
public class Shop {
private Long shopId;
private String shopName;
private Integer num;
public Long getShopId() {
return shopId;
}
public void setShopId(Long shopId) {
this.shopId = shopId;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
- 创建接口
package com.ckinghan.service;
import java.util.List;
import javax.jws.WebService;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.ckinghan.bean.Shop;
//标注此接口为WebService类
@WebService
//标注访问路径,用以精确定位
@Path("/shop")
public interface CXFResultService {
//标注访问路径,用以精确定位“{shopId}”是标示参数,如果有多个参数,可以做如下标示("/getShop/{shopId}/{shopName}/{shopNum}")
@Path("/getShop/{shopId}")
//标注返回值的类型,这里是json格式,也可以标为"MediaType.APPLICATION_XML"返回XML格式
@Produces(MediaType.APPLICATION_JSON)
//标注此方法只能通过GET方法访问,其它方法如POST方法无法访问。且GET方法访问时,如果返回值类型同时具有xml/json时,默认xml
@GET
public Shop getShopById(@PathParam("shopId")Long shopId); //@PathParam标为参数这里的shopId必须与上面的@Path中的参数对应,否则会报错。
@Path("/getShopList/{shopName}")
//当指定访问为post访问时,不能使用其它类型来访问,如果返回的数据类型同时指定了json/xml,则以json返回数据
@GET
//这里@produces指定的原本参数为"MediaType.APPLICATION_JSON",只是中文会出现乱码,所以用“application/json;charset=utf-8”指定编码将之替换了
@Produces( "application/json;charset=utf-8")
public List<Shop> getShopListByName(@PathParam("shopName")String shopName);
}
- 创建实现类
package com.ckinghan.service;
import java.util.ArrayList;
import java.util.List;
import com.ckinghan.bean.Shop;
public class CXFResultServiceImpl implements CXFResultService {
@Override
public Shop getShopById(Long shopId) {
if(shopId == 1001L){
Shop shop = new Shop();
shop.setNum(100);
shop.setShopId(1001L);
shop.setShopName("JAVA编程思想");
return shop;
}
return null;
}
@Override
public List<Shop> getShopListByName(String shopName) {
if(shopName == null || !"JAVA编程思想".equals(shopName)){
return null;
}
List<Shop> shopList = new ArrayList<Shop>();
Shop shop = new Shop();
shop.setNum(100);
shop.setShopId(1001L);
shop.setShopName("JAVA编程思想");
Shop shop1 = new Shop();
shop1.setNum(20);
shop1.setShopId(1002L);
shop1.setShopName("JAVA编程思想");
Shop shop2 = new Shop();
shop2.setNum(92);
shop2.setShopId(1003L);
shop2.setShopName("JAVA编程思想");
shopList.add(shop);
shopList.add(shop1);
shopList.add(shop2);
return shopList;
}
}
- 创建发布测试类
package com.ckinghan.test;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import com.ckinghan.service.CXFResultServiceImpl;
public class RestServiceTest {
public static void main(String[] args) {
//获取rest发布服务
JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
//设置访问地址
jaxrsServerFactoryBean.setAddress("http://127.0.0.1:12306/item");
//设置访问接口
jaxrsServerFactoryBean.setServiceClass(CXFResultServiceImpl.class);
//设置实现类
jaxrsServerFactoryBean.setServiceBean(new CXFResultServiceImpl());
//发布服务
jaxrsServerFactoryBean.create();
}
}
- 测试是否发布成功,如果出现如下页面,说明成功:
测试地址:http://127.0.0.1:12306/item/shop/getShop/1001
测试地址二:http://127.0.0.1:12306/item/shop/getShopList/JAVA%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3
- 客户端代码生成 不需要了。。。可以直接通过网页访问或HTTP访问并返回数据,直接解析数据就可以了