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();
}

 

 

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