1. 程式人生 > >CXF+JAX-RS搭建RESTful風格的WebService

CXF+JAX-RS搭建RESTful風格的WebService

概述

        因公司要實現兩個不同專案之間的RESTful介面訪問,技術選型是CXF和JAX-RS。接下來要解決的事情是:

        1,在兩個專案中加入CXF和JAX-RS;

        2,測試,看是否能否訪問成功。

        下面主要來說明這兩個問題,如果說清楚了,基本使用應該不成問題了,當然過程中對CXF和JAX-RS有更多的理解,通過本次搭建專案能夠理解使用和原理性的內容就非常好了。

 

專案搭建

        專案使用SpringMVC,在此基礎加上CXF和JAX-RS。使用的是Idea工具。

        專案的整體目錄如下:

        

        1,引入jar檔案。pom.xml內容如下:

 

<?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">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.me</groupId>
   <artifactId>capabilityService</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>war</packaging>

   <name>capabilityService Maven Webapp</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>
      <cxf.version>3.2.5</cxf.version>
      <logback.version>1.1.8</logback.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.11</version>
         <scope>test</scope>
      </dependency>

      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>4.2.5.RELEASE</version>
         <exclusions>
            <exclusion>
               <artifactId>commons-logging</artifactId>
               <groupId>commons-logging</groupId>
            </exclusion>
         </exclusions>
      </dependency>

      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.32</version>
      </dependency>

      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.16.12</version>
      </dependency>

      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid</artifactId>
         <version>1.1.10</version>
      </dependency>

      <dependency>
         <groupId>javax.servlet.jsp</groupId>
         <artifactId>javax.servlet.jsp-api</artifactId>
         <version>2.3.1</version>
         <scope>provided</scope>
      </dependency>

      <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.5</version>
      </dependency>

      <dependency>
         <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-transports-http</artifactId>
         <version>${cxf.version}</version>
         <exclusions>
            <exclusion>
               <artifactId>stax2-api</artifactId>
               <groupId>org.codehaus.woodstox</groupId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-frontend-jaxws</artifactId>
         <version>${cxf.version}</version>
      </dependency>
      <!--<dependency>-->
         <!--<groupId>org.apache.cxf</groupId>-->
         <!--<artifactId>cxf-bundle-jaxrs</artifactId>-->
         <!--<version>2.7.0</version>-->
      <!--</dependency>-->
      <dependency>
         <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-frontend-jaxrs</artifactId>
         <version>${cxf.version}</version>
      </dependency>
      <dependency>
         <groupId>org.codehaus.jettison</groupId>
         <artifactId>jettison</artifactId>
         <version>1.3.5</version>
      </dependency>
      <dependency>
         <!-- 如果CXF不整合到Web伺服器中,必須新增該引用 -->
         <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-transports-http-jetty</artifactId>
         <version>${cxf.version}</version>
         <exclusions>
            <exclusion>
               <artifactId>slf4j-api</artifactId>
               <groupId>org.slf4j</groupId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>axis</groupId>
         <artifactId>axis</artifactId>
         <version>1.4</version>
         <exclusions>
            <exclusion>
               <artifactId>commons-logging</artifactId>
               <groupId>commons-logging</groupId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>org.codehaus.woodstox</groupId>
         <artifactId>stax2-api</artifactId>
         <version>3.1.1</version>
      </dependency>
      <dependency>
         <groupId>org.codehaus.jackson</groupId>
         <artifactId>jackson-jaxrs</artifactId>
         <version>1.9.13</version>
      </dependency>
      <dependency>
         <groupId>com.fasterxml.jackson.jaxrs</groupId>
         <artifactId>jackson-jaxrs-json-provider</artifactId>
         <version>2.5.0</version>
      </dependency>

      <dependency>
         <groupId>javax.ws.rs</groupId>
         <artifactId>jsr311-api</artifactId>
         <version>1.1.1</version>
      </dependency>

      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
         <version>1.7.7</version>
      </dependency>
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>jcl-over-slf4j</artifactId>
         <version>1.7.25</version>
         <exclusions>
            <exclusion>
               <artifactId>slf4j-api</artifactId>
               <groupId>org.slf4j</groupId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-core</artifactId>
         <version>${logback.version}</version>
      </dependency>
      <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-access</artifactId>
         <version>${logback.version}</version>
      </dependency>
      <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
         <version>${logback.version}</version>
         <exclusions>
            <exclusion>
               <artifactId>slf4j-api</artifactId>
               <groupId>org.slf4j</groupId>
            </exclusion>
         </exclusions>
      </dependency>
   </dependencies>

   <build>
      <finalName>capabilityService</finalName>
      <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
         <plugins>
            <plugin>
               <artifactId>maven-clean-plugin</artifactId>
               <version>3.0.0</version>
            </plugin>
            <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
            <plugin>
               <artifactId>maven-resources-plugin</artifactId>
               <version>3.0.2</version>
            </plugin>
            <plugin>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>3.7.0</version>
               <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
               </configuration>
            </plugin>
            <plugin>
               <artifactId>maven-surefire-plugin</artifactId>
               <version>2.20.1</version>
            </plugin>
            <plugin>
               <artifactId>maven-war-plugin</artifactId>
               <version>3.2.0</version>
            </plugin>
            <plugin>
               <artifactId>maven-install-plugin</artifactId>
               <version>2.5.2</version>
            </plugin>
            <plugin>
               <artifactId>maven-deploy-plugin</artifactId>
               <version>2.8.2</version>
            </plugin>
         </plugins>
      </pluginManagement>
   </build>

</project>

        2,配置web.xml檔案。檔案內容如下: 

        其中, cxf的訪問路徑是/itil/*,這樣在訪問的時候輸入的路徑就是http:localhost:port/itil/了,當然現在還訪問,但是先確定的基本訪問的URL,後面則在此基礎上進行補充。

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
       version="3.1">

   <display-name>Archetype Created Web Application</display-name>
   <context-param>
      <param-name>webAppRootKey</param-name>
      <param-value>com.woxing.root</param-value>
   </context-param>
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
   </context-param>

   <!-- spring context listener -->
   <listener>
      <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
   </listener>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <!-- SpringMVC -->
   <servlet>
      <servlet-name>spring</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:spring-mvc.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>spring</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>

   <!--webservice-->
   <servlet>
      <servlet-name>CXFService</servlet-name>
      <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
      <init-param>
         <param-name>hide-service-list-page</param-name>
         <param-value>false</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>CXFService</servlet-name>
      <url-pattern>/itil/*</url-pattern>
   </servlet-mapping>

   <!-- 避免亂碼 -->
   <filter>
      <filter-name>encodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <async-supported>true</async-supported>
      <init-param>
         <param-name>encoding</param-name>
         <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
         <param-name>forceEncoding</param-name>
         <param-value>true</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>encodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

</web-app>

        3,配置springMVC

        

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

   <!-- 配置包掃描器 -->
   <context:component-scan base-package="com.woxing.capability.interfaces.impl,
         com.woxing.capability.engine,com.woxing.capability.execute" />

   <!-- 配置註解驅動 -->
   <mvc:annotation-driven/>

   <!-- 檢視解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/view/"/>
      <property name="suffix" value=".jsp"/>
   </bean>

   <mvc:resources location="/js/" mapping="/js/**"/>
   <mvc:resources location="/css/" mapping="/css/**"/>
   <mvc:resources location="/plugins/bootstrap3.3.5/" mapping="/bootstrap3.3.5/**"/>
   <mvc:resources location="/plugins/assets/" mapping="/assets/**"/>
   <mvc:resources location="/plugins/ztree/" mapping="/ztree/**"/>
   <!--<mvc:resources location="/json/" mapping="/json/**"/>-->

   <import resource="classpath:spring-ws.xml" />

</beans>

        4,配置cxf和JAX-RS

        配置的地址是/capabilityWs,訪問的時候就需要加上這個地址。注意address不能配置為/或者“”,否則會訪問不了。

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxrs="http://cxf.apache.org/jaxrs"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

   <import resource="classpath:META-INF/cxf/cxf.xml" />

   <jaxrs:server id="capabilityWs" address="/capabilityWs">
      <jaxrs:serviceBeans>
         <ref bean="capabilityServiceInterface"/>
      </jaxrs:serviceBeans>
      <jaxrs:providers>
         <!--<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>-->
         <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
      </jaxrs:providers>
      <jaxrs:extensionMappings>
         <entry key="json" value="application/json"/>
         <entry key="xml" value="application/xml"/>
      </jaxrs:extensionMappings>
      <!--<jaxrs:languageMappings>-->
         <!--<entry key="en" value="en-gb"/>-->
      <!--</jaxrs:languageMappings>-->
   </jaxrs:server>


   <!--Http client Factory-->
   <bean id="httpClientFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory">
      <!-- 連線超時時間,ms -->
      <property name="connectTimeout" value="4000"/>
      <!-- 讀寫超時時間,ms -->
      <property name="readTimeout" value="9000"/>
   </bean>

   <bean id="fastJsonHttpMessageConverter"
        class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
      <property name="supportedMediaTypes">
         <list>
            <value>application/json;charset=UTF-8</value>
            <value>text/html;charset=utf-8</value>
         </list>
      </property>
      <!-- 定義輸出時的格式轉換 -->
      <property name="features">
         <list>
            <value>WriteMapNullValue</value>
            <!-- 空值是否輸出 -->
            <value>QuoteFieldNames</value>
            <!-- 序列化輸出欄位,使用引號 -->
            <value>WriteNullStringAsEmpty</value>
            <!-- 字元型別欄位如果為null,輸出為"" -->
         </list>
      </property>
   </bean>

   <!-- 配置RestTemplate -->
   <!--RestTemplate-->
   <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
      <constructor-arg ref="httpClientFactory"/>
      <property name="messageConverters">
         <list>
            <ref bean="fastJsonHttpMessageConverter"/>
            <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
               <constructor-arg value="UTF-8"/>
            </bean>
            <bean id="formHttpMessageConverter" class="org.springframework.http.converter.FormHttpMessageConverter"/>
         </list>
      </property>
      <!-- 攔截器 -->
      <!--<property name="interceptors">-->

      <!--</property>-->
   </bean>

   <!--RestTemplate-->
   <bean id="asyncRestTemplate" class="org.springframework.web.client.AsyncRestTemplate">
      <constructor-arg ref="httpClientFactory"/>
      <property name="messageConverters">
         <list>
            <ref bean="fastJsonHttpMessageConverter"/>
         </list>
      </property>
   </bean>

</beans>

        5,編寫程式碼。與CXF和JAX-RS相關的程式碼結構如下圖:

        

        具體程式碼如下:

 

<strong>CapabilityServiceInterface.java</strong>
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * @Author: Qinc
 * @Description:
 * @Date: Created
 * @Modified By:
 */


//@Path("")
@Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8", MediaType.APPLICATION_XML})
public interface CapabilityServiceInterface {

    @GET
    @Path(value = "/getTest")
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    String test();

}

 

<strong>CapabilityServiceInterfaceImpl.java</strong>
import com.alibaba.druid.support.json.JSONUtils;
import com.woxing.capability.interfaces.CapabilityServiceInterface;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * @Author: Qinciwen
 * @Description:
 * @Date: Created in 17:47 2018/7/12
 * @Modified By:
 */

@Service("capabilityServiceInterface")
public class CapabilityServiceInterfaceImpl implements CapabilityServiceInterface{


    @Override
    public String test(){
        System.out.print("00000");
        HashMap<String, String> map = new HashMap<>();
        map.put("name", "小明");
        map.put("sex", "男");
        return JSONUtils.toJSONString(map);
    }

}

        這裡的程式碼寫的很簡單,主要是為了測試。下面開始測試。

 

測試

        Idea自帶的有測試工具,所以測試很方便。點選Tools——>Test RESTful Web Service,在最下方能看到。

        

        如下圖所示,測試成功!!