上一篇文章我们了解JAX-WS基于SOAP(面向简单对象访问协议)可以转化为XML数据格式进行远程调用,WSDL文档可以帮助我们清楚的了解到数据解析格式和要求,有兴趣的同学可以点击
一文搞懂WebService基于CXF框架实现[JAX-WS]
REST 全称是 Representational State Transfer(表述性状态转移),是一种软件架构风格,提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件,基于这个风格设置的软件可以简洁,更有层次,更易于实现。
REST 本质上是使用 URL 来访问资源的一种方式。总所周知,URL 就是我们平常使用的请求地址了,其中包括两部分:请求方式 与 请求路径,比较常见的请求方式是 GET 与 POST,但在 REST 中又提出了其它几种其它类型的请求方式,汇总起来有六种:GET、POST、PUT、DELETE、HEAD、OPTIONS。尤其是前四种,正好与 CRUD(增删改查)四种操作相对应:GET(查)、POST(增)、PUT(改)、DELETE(删),这正是 REST 的奥妙所在!
实际上,Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的,因为在任何时候都可以由客户端发出请求到服务端,最终返回自己想要的数据。也就是说,服务端将内部资源发布 REST 服务,客户端通过 URL 来访问这些资源,这不就是 SOA 所提倡的“面向服务”的思想吗?所以,REST 也被人们看做是一种轻量级的 SOA 实现技术,因此在企业级应用与互联网应用中都得到了广泛使用。
总结:
公用配置pom.xml依赖
<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.zjf</groupId>
<artifactId>jaxrs-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>jaxrs-parent</name>
<modules>
<module>rs-server</module>
<module>rs-client</module>
</modules>
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencyManagement>
<!--cxf jax-rs start -->
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.7</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.7</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.apache.cxf</groupId> -->
<!-- <artifactId>cxf-rt-transports-http-jetty</artifactId> -->
<!-- <version>3.1.1</version> -->
<!-- </dependency> -->
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.1.7</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.1.7</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.apache.axis2</groupId> -->
<!-- <artifactId>axis2-jaxws</artifactId> -->
<!-- <version>1.6.2</version> -->
<!-- <scope>runtime</scope> -->
<!-- <exclusions> -->
<!-- Causes java.lang.NoSuchMethodError: javax.ws.rs.core.Response$Status$Family.familyOf(I)Ljavax/ws/rs/core/Response$Status$Family; -->
<!-- <exclusion> -->
<!-- <groupId>javax.ws.rs</groupId> -->
<!-- <artifactId>jsr311-api</artifactId> -->
<!-- </exclusion> -->
<!-- </exclusions> -->
<!-- </dependency> -->
<!-- cxf jax-rs end -->
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.springframework</groupId> -->
<!-- <artifactId>spring-webmvc</artifactId> -->
<!-- <version>${spring.version}</version> -->
<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>org.springframework</groupId> -->
<!-- <artifactId>spring-jdbc</artifactId> -->
<!-- <version>3.2.13.RELEASE</version> -->
<!-- </dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.springframework</groupId> -->
<!-- <artifactId>spring-aspects</artifactId> -->
<!-- <version>${spring.version}</version> -->
<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>org.springframework</groupId> -->
<!-- <artifactId>spring-jms</artifactId> -->
<!-- <version>${spring.version}</version> -->
<!-- </dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- <dependency> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId>
<version>1.1.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId> <version>3.1.7</version>
</dependency> -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.3.3</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>cxfservlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxfservlet</servlet-name>
<url-pattern>/rs/*
拦截/rs的URL请求
服务端配置xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:cxf="http://cxf.apache.org/core"
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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd ">
<!--
address 发布服务地址
servicesBeans 服务实现类
-->
<jaxrs:server id="userService" address="/userService" >
<jaxrs:serviceBeans>
<bean class="com.zjf.service.impl.UserServiceImpl" />
</jaxrs:serviceBeans>
<!--日志配置 -->
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>
Rest风格服务接口
package com.zjf.service;
import java.util.List;
import javax.ws.rs.Consumes;
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 javax.ws.rs.core.MediaType;
import com.zjf.pojo.User;
@Path("/userService")
@Produces("*/*")
public interface UserService {
@Path("/add")
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public void saveUser(User user);
@Path("/update")
@PUT
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public void upUser(User user);
@Path("/get")
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public void getUser();
@Path("/find/{id}")
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public User findUser(@PathParam("id") Integer id);
@Path("/list")
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public List<User> listUser();
}
接口注解说明:
Rest风格服务接口实现类
package com.zjf.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.zjf.pojo.User;
import com.zjf.service.UserService;
@Service
public class UserServiceImpl implements UserService {
public void getUser() {
// TODO Auto-generated method stub
System.out.println("获取User成功");
}
@Override
public void saveUser(User user) {
// TODO Auto-generated method stub
System.out.println("添加User成功:" + user.getName());
}
@Override
public void upUser(User user) {
// TODO Auto-generated method stub
System.out.println("修改User成功:" + user.getName());
}
@Override
public User findUser(Integer id) {
// TODO Auto-generated method stub
System.out.println("查询User成功:" + id);
User user = new User();
user.setName("王五");
user.setAge(19);
return user;
}
@Override
public List<User> listUser() {
// TODO Auto-generated method stub
List<User> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setName("赵六" + i);
user.setAge(20);
list.add(user);
}
return list;
}
}
实体对象参数处理
@XmlRootElement(name = "User")
public class User implements Serializable {
@XmlRootElement 指定序列化(转化成xml;json)对象名字
基于spring配置
<?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"
xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client"
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
http://cxf.apache.org/jaxrs-client http://cxf.apache.org/schemas/jaxrs-client.xsd">
<jaxrs-client:client id="webClient"
address="http://localhost:8080/rs-server/rs/userService/userService/add"
serviceClass="org.apache.cxf.jaxrs.client.WebClient">
</jaxrs-client:client>
</beans>
基于CXF框架客户端webClient
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class clientTest {
//引入spring配置的CXF客户端
@Autowired
private WebClient webClient;
@Test
public void addUser() {
User user = new User();
user.setName("张三");
user.setAge(18);
Response post = WebClient.create("http://localhost:8080/rs-server/rs/userService/userService/add")
.type(MediaType.APPLICATION_JSON).post(user);
System.out.println("调用返回状态:" + post.getStatus());
}
@Test
public void addUser1() {
User user = new User();
user.setName("张三");
user.setAge(18);
Response post = webClient.type(MediaType.APPLICATION_JSON).post(user);
System.out.println("调用返回状态:" + post.getStatus());
}
@Test
public void findUser() {
User user = WebClient.create("http://localhost:8080/rs-server/rs/userService/userService/find/1")
.accept(MediaType.APPLICATION_JSON).get(User.class);
System.out.println(user);
}
@Test
public void listUser() {
Collection<? extends User> collection = WebClient
.create("http://localhost:8080/rs-server/rs/userService/userService/list")
.accept(MediaType.APPLICATION_JSON).getCollection(User.class);
System.out.println(collection);
}
}
WebClient可以通过Spring配置来创建,也可以通过create(“访问路径”)静态方法来创建,如果通过静态方法实际仍然是通过JAXRSClientFactoryBean对象进行创建。
访问URL具体层级路径
<servlet>
<servlet-name>cxfservlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxfservlet</servlet-name>
<url-pattern>/rs/*
<jaxrs:server id="userService" address="/userService" >
@Path("/userService")
@Produces("*/*")
public interface UserService {
@Path("/add")
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public void saveUser(User user);
客户端Junit测试
package com.zjf.test;
import java.util.Collection;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.zjf.pojo.User;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class clientTest {
@Autowired
private WebClient webClient;
@Test
public void addUser() {
User user = new User();
user.setName("张三");
user.setAge(18);
Response post = WebClient.create("http://localhost:8080/rs-server/rs/userService/userService/add")
.type(MediaType.APPLICATION_JSON).post(user);
System.out.println("调用返回状态:" + post.getStatus());
}
@Test
public void addUser1() {
User user = new User();
user.setName("张三");
user.setAge(18);
Response post = webClient.type(MediaType.APPLICATION_JSON).post(user);
System.out.println("调用返回状态:" + post.getStatus());
}
@Test
public void findUser() {
User user = WebClient.create("http://localhost:8080/rs-server/rs/userService/userService/find/1")
.accept(MediaType.APPLICATION_JSON).get(User.class);
System.out.println(user);
}
@Test
public void listUser() {
Collection<? extends User> collection = WebClient
.create("http://localhost:8080/rs-server/rs/userService/userService/list")
.accept(MediaType.APPLICATION_JSON).getCollection(User.class);
System.out.println(collection);
}
}
WebClient常用方法说明:
调用服务接口测试:
----------------------------
ID: 3
Address: http://localhost:8080/rs-server/rs/userService/userService/add
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/json
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[35], content-type=[application/json], host=[localhost:8080], pragma=[no-cache], user-agent=[Apache-CXF/3.1.7]}
Payload: {"User":{"age":18,"name":"å¼ ä¸‰"}}
--------------------------------------
添加User成功:张三
四月 05, 2020 4:24:14 下午 org.apache.cxf.interceptor.LoggingOutInterceptor
信息: Outbound Message
---------------------------
ID: 3
Response-Code: 204
Content-Type: */*
Headers: {Date=[Sun, 05 Apr 2020 08:24:14 GMT], Content-Length=[0]}
--------------------------------------