apache cxf 基于jax-rs规范实现的webservice(RESTFUL)

一.restful

基于jax-rs规范发布服务使用restful风格的webservice,请求使用的是http协议,可以传递xml/json数据。

REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。

1.restful与非restful

在Restful之前的操作:
http://127.0.0.1/user/query/1 GET  根据用户id查询用户数据
http://127.0.0.1/user/save POST 新增用户
http://127.0.0.1/user/update POST 修改用户信息
http://127.0.0.1/user/delete GET/POST 删除用户信息

RESTful用法:
http://127.0.0.1/user/1 GET  根据用户id查询用户数据
http://127.0.0.1/user  POST 新增用户
http://127.0.0.1/user  PUT 修改用户信息
http://127.0.0.1/user  DELETE 删除用户信息

之前的操作是没有问题的,大神认为是有问题的,有什么问题呢?你每次请求的接口或者地址,都在做描述,例如查询的时候用了query,新增的时候用了save,其实完全没有这个必要,我使用了get请求,就是查询.使用post请求,就是新增的请求,我的意图很明显,完全没有必要做描述,这就是为什么有了restful.

2.状态转化

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(StateTransfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:

GET用来获取资源,

POST用来新建资源,

PUT用来更新资源,

DELETE用来删除资源。

访问服务器资源,通过不同的http请求方式,服务器就知道对CRUD的哪个操作

JAX-RS 发布服务就是使用RESTFUL风格。

二.apache cxf 基于jax-rs规范实现的webservice-服务端

基于jax-rs规范发布服务使用restful风格的webservice,请求使用的是http协议,可以传递xml/json数据。

新建项目:jars-ws-server

1.新建pom文件

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>web-service-demo</artifactId>
        <groupId>com.meboth.bonc.ljf</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.meboth.bonc.ljf.jars.ws</groupId>
    <artifactId>jars-ws-server</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>jars-ws-server</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- jaxrs 支持包 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>3.0.1</version>
        </dependency>

        <!-- 内置的jetty服务器 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>

        <!-- 客户端调用时候使用的包(WebClient工具类调用服务端) -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.0.1</version>
        </dependency>

        <!-- 基于restful风格的webservice,客户端与服务端之间可以传递json,这个就是json支持相关包 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                        <showWarnings>true</showWarnings>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

2.定义实体类

package com.meboth.bonc.ljf.jars.ws.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "myBike")
public class Bike {
    private int id;
    private String carName;
    private float price;

    public Bike() {
    }

    public Bike(int id, String carName, float price) {
        this.id = id;
        this.carName = carName;
        this.price = price;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCarName() {
        return carName;
    }

    public void setCarName(String carName) {
        this.carName = carName;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}



package com.meboth.bonc.ljf.jars.ws.model;

import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "myPeople")
public class People {
    private int id;
    private String userName;
    private List<Bike> bikeList=new ArrayList<Bike>();

    public People() {
    }

    public People(int id, String userName, List<Bike> bikeList) {
        this.id = id;
        this.userName = userName;
        this.bikeList = bikeList;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public List<Bike> getBikeList() {
        return bikeList;
    }

    public void setBikeList(List<Bike> bikeList) {
        this.bikeList = bikeList;
    }
}



3.定义实现类

package com.meboth.bonc.ljf.jars.ws.service;

import com.meboth.bonc.ljf.jars.ws.model.People;

import javax.ws.rs.*;
import java.util.List;

@Path("/tjService")  // 路径;访问当前服务接口时候的路径。
@Produces("*/*")
public interface TianJingService {
    @POST
    @Path("/tjUser")	  // 路径; 访问当前服务接口的方法路径
    // @Consumes 服务端支持的请求的数据格式(xml、json)
    @Consumes({ "application/xml", "application/json" })
    public void saveUser(People user);

    @PUT
    @Path("/tjUser")
    @Consumes({ "application/xml", "application/json" })
    public void updateUser(People user);

    @GET
    @Path("/tjUser")
    // @Produces 服务端支持的响应的数据格式
    @Produces({ "application/xml", "application/json" })
    public List<People> findAllUsers();

    @GET
    @Path("/tjUser/{id}")
    @Consumes("application/xml")
    @Produces({ "application/xml", "application/json" })
    public People finUserById(@PathParam("id") Integer id);

    @DELETE
    @Path("/tjUser/{id}")
    @Consumes({"application/xml", "application/json"})
    public void deleteUser(@PathParam("id") Integer id);
}





package com.meboth.bonc.ljf.jars.ws.service;

import com.meboth.bonc.ljf.jars.ws.model.Bike;
import com.meboth.bonc.ljf.jars.ws.model.People;

import java.util.ArrayList;
import java.util.List;

public class TianJingServiceImpl implements TianJingService {
    public void saveUser(People user) {
        System.out.println("save user:" + user.getUserName());
    }

    public void updateUser(People user) {
        System.out.println("update user:" + user);
    }

    public List<People> findAllUsers() {
        List<People> users = new ArrayList<People>();

        // 汽车
        List<Bike> carList1 = new ArrayList<Bike>();
        Bike car1 = new Bike(101,"保时捷",1000000f);
        Bike car2 = new Bike(102,"林肯",400000f);
        carList1.add(car1);
        carList1.add(car2);

        // 用户
        People user1 = new People(1,"小明",carList1);
        People user2 = new People(2,"小丽",carList1);

        // 用户集合
        users.add(user1);
        users.add(user2);

        return users;
    }

    public People finUserById(Integer id) {
        if (id == 1) {
         Bike bike=   new Bike(101,"保时捷",1000000f);
         List<Bike> bList=   new ArrayList<Bike>();
         bList.add(bike);
            return new People(1,"小明",bList);
        }
        return null;
    }

    public void deleteUser(Integer id) {
        System.out.println("delete user id :" + id);
    }
}


 

使用的注解:

@XmlRootElement

指定根元素,

作用:客户端与服务端传递对象数据时候,序列化为xml或json的根元素的名称

@Path("/userService")

路径;访问当前服务接口时候的路径、接口方法的路径。

@POST insert操作

@PUT update操作

@GET select 查询操作

@DELETE delete删除操作

@Consumes 服务端支持的请求的数据格式(xml、json)

@Produces 服务端支持的响应的数据格式

4.资源配置类:

log4j.rootLogger=INFO,console,FILE
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}[%5p]-%c(%L)-%m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.Append=true
log4j.appender.FILE.File=./web-service.log
log4j.appender.FILE.Threshold=INFO
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss}[%5p]-%c(%L)-%m%n
log4j.appender.FILE.MaxFileSize=30MB

 

5.启动类

package com.meboth.bonc.ljf.jars.ws;

import com.meboth.bonc.ljf.jars.ws.service.TianJingServiceImpl;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;

/**
 * Hello world!
 *
 */
public class JaxRsServer
{
    /**
     * 发布restful风格的webservice的服务
     */
    public static void main( String[] args ) {
            //1.创建服务工厂
            JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();

            //2.设置服务地址、
            factory.setAddress("http://localhost:8001/rs");

            //3.实例化服务类、
            factory.setServiceBean(new TianJingServiceImpl());

            // 添加日志拦截器
            factory.getInInterceptors().add(new LoggingInInterceptor());
            factory.getOutInterceptors().add(new LoggingOutInterceptor());

            //4.创建服务
            factory.create();

            System.out.println("发布服务成功.......端口:8001");
        }
}

6.启动服务

 

三.apache cxf 基于jax-rs规范实现的webservice-客户端

新建项目:jars-ws-client

1.pom文件

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>web-service-demo</artifactId>
        <groupId>com.meboth.bonc.ljf</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.meboth.bonc.ljf.jars.ws.client</groupId>
    <artifactId>jars-ws-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>jars-ws-client</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- jaxrs 支持包 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>3.0.1</version>
        </dependency>

        <!-- 内置的jetty服务器 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>

        <!-- 客户端调用时候使用的包(WebClient工具类调用服务端) -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.0.1</version>
        </dependency>

        <!-- 基于restful风格的webservice,客户端与服务端之间可以传递json,这个就是json支持相关包 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- maven的jdk编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                        <showWarnings>true</showWarnings>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

2.实体类:

 

package com.meboth.bonc.ljf.jars.ws.client.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "myBike")
public class Bike {
    private int id;
    private String carName;
    private float price;

    public Bike() {
    }

    public Bike(int id, String carName, float price) {
        this.id = id;
        this.carName = carName;
        this.price = price;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCarName() {
        return carName;
    }

    public void setCarName(String carName) {
        this.carName = carName;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}


package com.meboth.bonc.ljf.jars.ws.client.model;

import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;

@XmlRootElement(name = "myPeople")
public class People {
    private int id;
    private String userName;
    private List<Bike> bikeList=new ArrayList<Bike>();

    public People() {
    }

    public People(int id, String userName, List<Bike> bikeList) {
        this.id = id;
        this.userName = userName;
        this.bikeList = bikeList;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public List<Bike> getBikeList() {
        return bikeList;
    }

    public void setBikeList(List<Bike> bikeList) {
        this.bikeList = bikeList;
    }
}







3.启动类:

package com.meboth.bonc.ljf.jars.ws.client;

import com.meboth.bonc.ljf.jars.ws.client.model.Bike;
import com.meboth.bonc.ljf.jars.ws.client.model.People;
import org.apache.cxf.jaxrs.client.WebClient;

import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class JarWsClient {
    /**
     *  .create()     指定服务端地址

     .type()      指定请求数据格式(xml、json)

     .accept()    指定响应数据格式

     .post()/put()/delete()/get()  指定请求类型
     */
    public static void main(String args[])throws Exception{
        //save();
        //update();
        //findOne();
        findAll();
    }

    /**
     * 添加
     * @throws Exception
     */
    public static  void save() throws Exception {
        // 基于restful风格的webservice开发的客户端调用,直接通过一个类:WebClient类完成
        Bike bike=   new Bike(101,"haval h6",1000000f);
        List<Bike> bList=   new ArrayList<Bike>();
        bList.add(bike);
        bList.add(new Bike(101,"linken",3000000f));
        WebClient.create("http://localhost:8001/rs/tjService/tjUser")  // 地址
                .type(MediaType.APPLICATION_JSON)                     // 请求数据格式是json
                .post(new People(100,"Kobe",bList));                  // 发送请求的类型
    }

    /**
     * 修改
     * @throws Exception
     */
    public static  void update() throws Exception {
        WebClient.create("http://localhost:8001/rs/tjService/tjUser")  // 地址
                .type(MediaType.APPLICATION_JSON)                     // 请求数据格式是json
                .put(new People(100,"Kobe",null));                   // 发送请求的类型
    }

    /**
     * 通过id查找
     * @throws Exception
     */
    public static void findOne() throws Exception {
        People user =
                WebClient
                        .create("http://localhost:8001/rs/tjService/tjUser/1")  // 地址
                        .accept(MediaType.APPLICATION_JSON)  // 响应的数据格式
                        .get(People.class);
        System.out.println(user);
    }

    /**
     * 查询全部
     * @throws Exception
     */
    public static void findAll() throws Exception {
        Collection<? extends People> collection =
                WebClient
                        .create("http://localhost:8001/rs/tjService/tjUser/")
                        .accept(MediaType.APPLICATION_JSON)
                        .getCollection(People.class);
        System.out.println(collection);
    }

}

 

5.log4j日志:

log4j.rootLogger=INFO,console,FILE
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}[%5p]-%c(%L)-%m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.Append=true
log4j.appender.FILE.File=./web-service.log
log4j.appender.FILE.Threshold=INFO
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss}[%5p]-%c(%L)-%m%n
log4j.appender.FILE.MaxFileSize=30MB

 

6.调试访问:

执行findAll()方法

public static void main(String args[])throws Exception{
    //save();
    //update();
    //findOne();
    findAll();
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章