此项目是在IDEA中创建的MAVEN的web项目
服务端:↓
步骤一:在pom.xml中添加如下依赖
<!--一部分是spring的框架包,一部分是restful自己的包-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.0.1</version>
</dependency>
<!--restful-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<!--对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>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
步骤二:创建会用到的实体类(记得给该实体类加@XmlRootElement注解)
此案例该实体类命名为:Users
package com.qf.Users;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement//实体类注解,标记当前要转换的格式。@XmlRootElement是基于restful风格的webService,客户端和服务器端之间通讯可以使用xml数据,json数据,@XmlRootElement用来指定对象序列化为xml或json数据时的根节点名称,也可以指定名字@XmlRootElement(name="")。如果指定名字,客户端和服务端的name值要相同。
public class Users {
private int userid;
private String username;
private String password;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
步骤三:创建接口。接口当中包含请求地址,返回什么数据类型
此案例该接口命名为:UsersDao
package com.qf.dao;
import com.qf.Users.Users;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
@Produces("*/*")//规定了服务器返回给客户端的数据格式。此地*/*代表格式不限制
public interface UsersDao {
@Path("/insert")
@POST//post提交(即新增)数据
public int insertUsers(Users users);
@Path("/update")
@PUT//PUT更新数据
public int updateUsers(Users users);
@Path("/delete/{uid}")//{uid}表示占位,前端请求地址中传过来的参数由uid获取。此时restful风格就体现出来了,前台传值格式为delete/1,1是传过来的参数
@DELETE//DELETE删除数据
public int deleteUsers(@PathParam("uid") int userid);//@PathParam("uid") 代表将uid和userid绑定
@Path("/getbyid/{id}")//restful这个占位符记得加{}大括号。客户端访问该方法的正确地址是:http://localhost:8080/users/getbyid/{id},即发布地址/请求地址/参数 的格式才能访问到
@GET//GET取(查询)数据
@Produces(MediaType.APPLICATION_JSON)//单独指定该方法返回值转换成json对象,表示以json格式返回给客户端。MediaType类有好几种数据格式,只需点一下就会提示。
public Users findbyid(@PathParam("id") int userid);
@Path("/getall")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Users> findall();
}
步骤四:创建UsersDao的实现类,该类写请求地址具体的处理方法
此案例该实现类命名为为:UsersDaoImpl
package com.qf.dao.impl;
import com.qf.Users.Users;
import com.qf.dao.UsersDao;
import java.util.ArrayList;
import java.util.List;
public class UsersDaoImpl implements UsersDao{
//给数据库新增一条数据
public int insertUsers(Users users) {
System.out.println("insertUsers="+users);
return 11;
}
//修改一条数据
public int updateUsers(Users users) {
System.out.println("updateUsers="+users);
return 22;
}
//给数据库删除一条数据
public int deleteUsers(int userid) {
System.out.println("deleteUsers="+userid);
return 33;
}
//从数据库中根据id查询一条数据
public Users findbyid(int userid) {
System.out.println("findbyid="+userid);
Users users=new Users();
users.setUserid(110);
users.setUsername("张三");
users.setPassword("abc");
return users;
}
//查询数据库中的所有数据
public List<Users> findall() {
List list=new ArrayList();
System.out.println("findall");
for (int i = 0; i < 5; i++) {
Users users=new Users();
users.setUserid(110);
users.setUsername("张三");
users.setPassword("abc");
list.add(users);
}
return list;
}
}
步骤五:在resources文件夹下创建xml配置文件,配置如下命名空间
xmlns:jaxrs=“http://cxf.apache.org/jaxrs”
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
案例中我将该xml文件命名为:cxf.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:p="http://www.springframework.org/schema/p"
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
">
<!--注意web项目中的配置文件(如xml文件)的加载都是在web.xml中加载的-->
<jaxrs:server id="abc" address="/testrestful"><!--id为对象名,随便取。address为请求地址-->
<jaxrs:serviceBeans>
<bean class="com.qf.dao.impl.UsersDaoImpl"></bean><!--class为实现类的路径(包名加类名),用于创建实现类的对象-->
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
步骤六:配置WEB-INF下的web.xml文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<!--文件路径走势:先走web.xml再走cxf.xml,-->
<web-app>
<!--配置xml文件路径,告诉spring我们创建的对象,到时候一个注解即可注入对象,无需用getApplication来获取xml配置文件中创建bean对象-->
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:cxf.xml</param-value><!--要加载的配置文件的路径-->
</context-param>
<!--配置监听器-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!--配置servlet-->
<servlet>
<servlet-name>aa</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aa</servlet-name>
<url-pattern>/testcxf/*</url-pattern><!--这里写了testcxf,在访问请求地址是必须加上testcxf才能找到对应的请求地址处理方法。完整的请求地址访问路径如:http://localhost:8080/testcxf/insert,也就是:网页地址/testcxf/请求地址-->
</servlet-mapping>
服务端案例结构图:
客户端:↓
该案例服务端命名为:restfulSpringClient
步骤一:在pom.xml中添加依赖
<!-- springmvc -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId><!--DispatcherServlet的关键依赖-->
<version>5.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- restful -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.1</version>
</dependency>
<!--对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>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.6</version>
</dependency>
步骤二:创建将服务端创建的实体类(即Users)复制给客户端,因为后面要用。
package com.qf.entity;
//原来的费restful的客户端的代码都是由wsimport -s等命令自动生成的,但restful风格只是公司内部应用,因此还不普及,这个实体类只能从服务端复制过来
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement//实体类注解,标记当前要转换的格式。@XmlRootElement是基于restful风格的webService,客户端和服务器端之间通讯可以使用xml数据,json数据,@XmlRootElement用来指定对象序列化为xml或json数据时的根节点名称,也可以指定名字@XmlRootElement(name="")。如果指定名字,客户端和服务端的name值要相同。
public class Users {
private int userid;
private String username;
private String password;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
步骤三:在resources下创建xml,用于创建Webclient对象,建立与服务端的联系。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="myclient" class="org.apache.cxf.jaxrs.client.WebClient" factory-method="create">
<!--localhost是电脑ip地址,因为是本地,所以用的locahost;8080是tomcat那设置的端口号;testcxf是在服务端的web.xml文件那设置的访问路径;testrestful则是我们在服务端的cxf.xml那设置的address的属性值-->
<constructor-arg type="java.lang.String" value="http:localhost:8080/testcxf/testrestful"></constructor-arg>
</bean>
</beans>
步骤四:在web.xml加载resources下创建的xml配置文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<!--读取我们在resources文件夹下定义的配置文件-->
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>aa</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:client.xml</param-value><!--加载文件-->
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>aa</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
步骤五:在controller里建立网页请求地址处理方法(注意是网页,不是服务端)
package com.qf.contller;
import com.qf.entity.Users;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
public class UsersController {
@Resource
private WebClient webClient;//这是我们在client.xml文件创建的并bean对象,用@Resources注入。
@RequestMapping("/getusers")//此方法处理网页中传来的getusers请求。也就是说最终是用http://localhost:8080/testcxf/testrestful/getusers?userid=11这种方式访问的
public String get(int userid){
//从服务端获得用户信息
Users users = webClient.path("/getbyid" + userid)//webClient.path()是在client创建的webClient的bean对象原有的基础上拼上请求地址要携带的参数,即服务端请求地址对应的处理方法的参数。
.get(Users.class);//Users是服务端查询方法 的返回值类型。
System.out.println(users);
return "success";//执行成功后要跳转去的网页
}
}
客户端案例结构图:
==注意:此案例似乎只有两个Tomcat才能成功,因为启动一方tomcat,另一方的就会被占用,即使端口号不一样