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,在最下方能看到。
如下圖所示,測試成功!!