CXF发布restful WebService的入门例子(服务器端)

文章来源:http://www.cnblogs.com/ggjucheng/p/3352477.html

研究了两天CXF对restful的支持。 
  现在,想实现一个以 
http://localhost:9999/roomservice 为入口, 
http://localhost:9999/roomservice/room为房间列表, 
http://localhost:9999/roomservice/room/001/ 为001号房间的信息, 
http://localhost:9999/roomservice/room/001/person 为在001号房间主的人的列表 

实现用HTTP请求对以上资源的CRUD。 

首先建立room,person的POJO,这里只有一点需要注意:

复制代码
package com.DAO;  
  
import javax.xml.bind.annotation.XmlRootElement;  
  
@XmlRootElement(name="Person")  
public class Person {  
    private String name;  
    private String sex;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getSex() {  
        return sex;  
    }  
    public void setSex(String sex) {  
        this.sex = sex;  
    }  
      
}  
复制代码

一定要在类的前边加上annotation ,这样才能让这个person的信息在POJO和XML之间转换。Room同理: 

复制代码
import java.util.Map;  
  
import javax.xml.bind.annotation.XmlRootElement;  
  
@XmlRootElement(name="Room")  
public class Room {  
    public Room()  
    {  
        persons=new HashMap<String,Person>();  
    }  
    String id;  
    Map<String,Person> persons;  
      
    public String getId() {  
        return id;  
    }  
    public void setId(String id) {  
        this.id = id;  
    }  
    public Map<String, Person> getPersons() {  
        return persons;  
    }  
    public void setPersons(Map<String, Person> persons) {  
        this.persons = persons;  
    }  
}  
复制代码

POJO有了,接下来要写DAO,由于主要是为了学习restful,为了方便,不必要将数据持久化到数据库,而是存在一个静态的HashMap中: 

复制代码
package com.DAO;  
  
import java.util.HashMap;  
import java.util.Map;  
  
public class RoomDAO {  
    private static Map<String, Room> rooms;  
    static {  
        rooms = new HashMap<String, Room>();  
          
        Person p1=new Person();  
        p1.setName("Boris");  
        p1.setSex("male");  
          
          
          
        Room r=new Room();  
        r.setId("001");  
        r.getPersons().put(p1.getName(), p1);  
        rooms.put("001", r);  
    }  
  
    public static void addRoom(Room room) {  
        rooms.put(room.getId(), room);  
    }  
  
    public static void deleteRoom(String id) {  
        if (rooms.containsKey(id)) {  
            rooms.remove(id);  
        }  
  
    }  
  
    public static void updateRoom(String id,Room room) {  
        rooms.remove(id);  
        rooms.put(room.getId(), room);  
    }  
  
    public static Room getRoom(String id) {  
        if (rooms.containsKey(id)) {  
            return rooms.get(id);  
        } else {  
            return null;  
        }  
    }  
    /*operations to persons*/  
    public static void addPerson(String id_room,Person person) {  
        if(rooms.containsKey(id_room))  
        {  
            Room room=rooms.get(id_room);  
            room.getPersons().put(person.getName(), person);  
        }  
    }  
      
    public static Rooms getRooms()  
    {  
        return new Rooms();  
    }  
      
    public static void deletePerson(String id_room,String name)  
    {  
        if(rooms.containsKey(id_room))  
        {  
            Room room=rooms.get(id_room);  
            room.getPersons().remove(name);  
        }  
    }  
      
    public static Map<String, Room> getMapOfRooms()  
    {  
        return rooms;  
    }  
}  
复制代码

接下来是重点,如果想发布restful webservice,要通过一个叫JAXRSServerFactoryBean的类来发布。这个类有几个方法是要了解的: 

public void setResourceClasses(Class... classes); 
那一系列的Class类型的参数,是告诉这个类,发布服务时,会用到的POJO(就像上边写的Room,Person)。 

public void setAddress(String address); 
这个方法是告诉这个类,服务的地址,比如"http://localhost:9999" 

public void setServiceBeans(Object... beans) 
这里是重点,这个方法,要给这个用来发布服务的类一个Service bean.这个Bean是我们要手动编写的,作用是告诉服务,收到什么样的请求,应该怎么样处理。 

现在,先来编写这个Service bean: 

复制代码
package com.server;  
  
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 com.DAO.Person;  
import com.DAO.Room;  
import com.DAO.RoomDAO;  
import com.DAO.Rooms;  
  
@Path("/roomservice")  
@Produces("application/xml")  
public class RoomService {  
      
    @GET  
    @Path("/room/{id}")  
    @Consumes("application/xml")  
    public Room getRoom(@PathParam("id")String id )  
    {  
        System.out.println("get room by id= "+id);  
        Room room=RoomDAO.getRoom(id);  
        return room;  
    }  
    @GET  
    @Path("/room")  
    @Consumes("application/xml")  
    public Rooms getAllRoom()  
    {  
        System.out.println("get all room");  
        Rooms rooms=RoomDAO.getRooms();  
        return rooms;  
    }  
      
    @POST  
    @Path("/room")  
    @Consumes("application/xml")  
    public void addRoom(Room room)  
    {  
        System.out.println("add room which id is:"+room.getId());  
        RoomDAO.addRoom(room);  
    }  
    @PUT  
    @Path("/room/{id}")  
    @Consumes("application/xml")  
    public void updateRoom(@PathParam("id")String id,Room room)  
    {  
        System.out.println("update room which original id is:"+room.getId());  
        RoomDAO.updateRoom(id,room);  
    }  
    @DELETE  
    @Path("/room/{id}")  
    @Consumes("application/xml")  
    public void deleteRoom(@PathParam("id")String id)  
    {  
        System.out.println("remove room by id= "+id);  
        RoomDAO.deleteRoom(id);  
    }  
    @POST  
    @Path("/room/{id}")  
    @Consumes("application/xml")  
    public void addPerson(@PathParam("id") String id,Person person)  
    {  
        System.out.println("add person who's name is:"+person.getName());  
        RoomDAO.addPerson(id, person);  
    }  
    @DELETE  
    @Path("/room/{id}/{name}")  
    @Consumes("application/xml")  
    public void deletePerson(@PathParam("id")String id,@PathParam("name")String name)  
    {  
        System.out.println("remove person who's name is: "+name);  
        RoomDAO.deletePerson(id, name);  
    }  
}  
复制代码

需要注意:每个方法之前,要用annotation声明http请求的method类型,比如GET,DELETE,POST, PUT. 
@Produces("application/xml")我还没弄清楚到底是声明的接受格式还是返回格式,还是其他。 

@Path("/room/{id}")中的id是一个参数,应该在方法的参数列表中声明: 
public void deletePerson(@PathParam("id")String id,@PathParam("name")String name) 
这样就能得到URL中的id了。 

现在,这些房间被资源化了,id为001的房间被资源化为一个URL,那地址应该是 
http:{服务器地址}:{端口}/roomservice/rrom/001   

现在,创建一个Server: 

复制代码
package com.server;  
  
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;  
  
import com.DAO.Person;  
import com.DAO.Room;  
import com.DAO.Rooms;  
  
public class Server {  
  
    public static void main(String[] args) {  
        RoomService service = new RoomService();  
  
        // Service instance  
        JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean();  
        restServer.setResourceClasses(Room.class,Person.class,Rooms.class);  
        restServer.setServiceBeans(service);  
        restServer.setAddress("http://localhost:9999/");  
        restServer.create();  
    }  
}  
复制代码

现在,服务已经发布成功了,在浏览器输入http://localhost:9999/roomservice/room/001  得到结果: 

复制代码
<room>  
<id>001</id><persons><entry>  
<key>Boris</key><value>  
<name>Boris</name>  
<sex>male</sex>  
</value>  
</entry>  
</persons>  
</room>  
复制代码

如果用浏览器去访问,发送的http请求只能所GET,因此如果想对数据进行操作,必须写一个客户端。 
在写客户端之前,有一个问题: 
在浏览器输入http://localhost:9999/roomservice/room/ 
什么都看不到,可是,我想要得到房间列表。但是,cxf发布restful只认你给他的类的class。所以你想让服务器返回一个room的列表给客户端,是不行的。所以,必须想别的办法,我是又写了一个POJO,这个POJO里只有一个属性,就是一个存放所有room的Map: 
package com.DAO; 

复制代码
import java.util.Map;  
  
import javax.xml.bind.annotation.XmlRootElement;  
@XmlRootElement(name="rooms")  
public class Rooms {  
    Map<String,Room> rooms;  
    public Rooms()  
    {  
        rooms=RoomDAO.getMapOfRooms();  
    }  
    public Map<String, Room> getRooms() {  
        return rooms;  
    }  
    public void setRooms(Map<String, Room> rooms) {  
        this.rooms = rooms;  
    }  
}  
复制代码

这样,然后再把DAO的方法加上: 

复制代码
@GET  
    @Path("/room")  
    @Consumes("application/xml")  
    public Rooms getAllRoom()  
    {  
        System.out.println("get all room");  
        Rooms rooms=RoomDAO.getRooms();  
        return rooms;  
    }  
复制代码

这样就能以list的形式显示出所有room了。 
访问http://localhost:9999/roomservice/room/ 
结果如下: 

复制代码
<rooms><rooms><entry>  
<key>006</key><value>  
<id>006</id>  
<persons/>  
</value>  
</entry><entry>  
<key>001</key><value>  
<id>001</id><persons><entry>  
<key>Boris</key><value>  
<name>Boris</name>  
<sex>male</sex>  
</value>  
</entry>  
</persons>  
</value>  
</entry>  
</rooms>  
</rooms>  
复制代码















  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
restserver是一个小巧、高效、低耗的C技术栈的RESTful应用服务平台。 小巧是因为链接出来的可执行程序只有300多KB,应用接口库80KB,本体源码都在一个目录中,手写的大概一千行左右,用预置好的makefile一条命令就能完成源码编译安装。 高效是因为她完全用C编写而成,采用多进程+多路复用模型,参考Nginx。 低耗是因为空载运行只占了几MB内存,特别适合买不起高配云服务器的个人开发者。对于企业来说,现在动不动就要求8、16、32GB内存配置,如果软件能低耗运行,节省下来的硬件支出也是相当可观,或者说相同配置的硬件上能对外提供更大容量的应用服务。restserver功能特性HTTP核心功能:如侦听IP、PORT、域名匹配、超时控制。 HTTP安全控制:防御巨量HTTP头选项、防御巨大HTTP头、防御巨大HTTP体。 平台封装至RESTful层:与Apache、Tomcat封装HTTP层相比,封装层次更高,应用无需处理HTTP层的众多细节,自带RESTful控制器直接分派到RESTful服务入口,应用接口直接提供RESTful编程接口。你也可以编写自己的控制器替换自带控制器。 多进程+多路复用模型:充分利用多核环境,防御慢速TCP,支持巨量TCP连接和同时收发,且性能卓越。 可执行程序+动态库模式:restserver是应用服务平台(可执行程序),启动后装载应用(动态库),外来请求被平台接收和解析,转交给应用动态库处理,处理完后返回平台,发送响应回去,平台和应用的部署运行边界解耦清晰。 运行模式:以前给公司研发的多款平台框架沉淀下来的优秀设计思想,测试模式即时装卸应用,重构应用后无需重启平台,生产模式预装载应用,性能无损耗,谁说鱼与熊掌不可兼得?那是教条! 平台自有日志设施:可配置日志文件名、日志等级,同时应用也能使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值