近期,因工作需要,接触到CXF与spring集成发布Rest服务,并实现客户端与服务器端的交互,上网查阅相关资料发现CXF与spring集成发布Rest服务的相关文章较多,但涉及到客户端访问服务器的相关资料确很少,几经周折,整合前人的经验,搭建好此框架之后,觉得有必要记录一下,一方面可以巩固一下流程,另一方面,希望能帮助更多有需要的人!
1.maven 创建普通 java 工程并调整整体工程环境
2.项目目录:
1.添加maven依赖(以下没有用到的可以不添加)
<dependencies> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- 数据库相关 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.15</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.5</version> </dependency> <!-- 日志相关 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.26</version> </dependency> <!--CXF--> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-service-description</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>${cxf.version}</version> </dependency> <!--Jackdon--> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> <version>1.9.13</version> </dependency> <!-- aspectJ AOP 织入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <!-- apache lang3工具包 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> </dependencies>
2.配置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-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF --> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> </web-app>
1.在项目目录下新建bean包,在bean文件夹下创建Product类
package com.spring.rest.bean; public class Product { private long id; private String name; private int price; public Product() { } public Product(long id, String name, int price) { this.id = id; this.name = name; this.price = price; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
2.在项目目录下新建service包,在service包下新建impl包和inter包,在impl下新建ProductServiceImpl类,在inter包下新建ProductService接口(项目目录如上)
ProductServiceImpl类中内容:
package com.spring.rest.service.impl; import com.lenovo.rest.bean.Product; import com.lenovo.rest.service.inter.ProductService; import java.lang.reflect.Field; import java.util.*; public class ProductServiceImpl implements ProductService { private static final List<Product> productList = new ArrayList<Product>(); static { productList.add(new Product(1, "iphone63", 5000)); productList.add(new Product(2, "ipad mini", 2500)); } @Override public List<Product> retrieveAllProducts() { Collections.sort(productList, new Comparator<Product>() { @Override public int compare(Product p1, Product p2) { return (p1.getId() > p2.getId()) ? -1 : 1; } }); return productList; } @Override public Product retrieveProductById(long id) { Product targetProduct = null; for (Product product : productList) { if (product.getId() == id) { targetProduct = product; break; } } return targetProduct; } @Override public List<Product> retrieveProductsByName_param(String name){ List<Product> targetList = new ArrayList<Product>(); for (Product product : productList) { if (product.getName().equals(name)) { targetList.add(product); } } return targetList; } @Override public List<Product> retrieveProductsByName_form(String name) { List<Product> targetList = new ArrayList<Product>(); for (Product product : productList) { if (product.getName().equals(name)) { targetList.add(product); } } return targetList; } @Override public Product createProduct(Product product) { product.setId(new Date().getTime()); productList.add(product); return product; } @Override public Product createProduct(String name,int price){ Product product = new Product(); product.setId(new Date().getTime()); product.setName(name); product.setPrice(price); productList.add(product); return product; } @Override public Product updateProductById(long id, Map<String, Object> fieldMap) { Product product = retrieveProductById(id); if (product != null) { try { for (Map.Entry<String, Object> fieldEntry : fieldMap.entrySet()) { Field field = Product.class.getDeclaredField(fieldEntry .getKey()); field.setAccessible(true); field.set(product, fieldEntry.getValue()); } } catch (Exception e) { e.printStackTrace(); } } return product; } @Override public Product updateProduct(Product product){ if(product != null){ Product targetProduct = retrieveProductById(product.getId()); if(targetProduct != null){ targetProduct.setName(product.getName()); targetProduct.setPrice(product.getPrice()); } return targetProduct; } return null; } @Override public Product updateProduct(long id,String name,int price){ Product product = retrieveProductById(id); if(product != null){ product.setName(name); product.setPrice(price); } return product; } @Override public Product deleteProductById(long id) { Product targetProduct = null; Iterator<Product> it = productList.iterator(); while (it.hasNext()) { Product product = it.next(); if (product.getId() == id) { targetProduct = product; it.remove(); break; } } return targetProduct; } @Override public Product deleteProductById_param(long id){ Product targetProduct = null; Iterator<Product> it = productList.iterator(); while (it.hasNext()) { Product product = it.next(); if (product.getId() == id) { targetProduct = product; it.remove(); break; } } return targetProduct; } }
ProductService接口中的内容:
package com.spring.rest.service.inter; import com.spring.rest.bean.Product; import java.util.List; import java.util.Map; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; 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.QueryParam; import javax.ws.rs.core.MediaType; public interface ProductService { @GET @Path("/products") @Produces(MediaType.APPLICATION_JSON) List<Product> retrieveAllProducts(); @GET @Path("/product/{id}") @Produces(MediaType.APPLICATION_JSON) Product retrieveProductById(@PathParam("id")long id); /** * 参数查询 * @param name * @return */ @GET @Path("/products/name") @Produces(MediaType.APPLICATION_JSON) List<Product> retrieveProductsByName_param(@QueryParam("name")String name); /** * 提交表单查询 * @param name * @return */ @POST @Path("/products/form/name") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) List<Product> retrieveProductsByName_form(@FormParam("name")String name); @POST @Path("/product") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Product createProduct(Product product); @POST @Path("/product/create") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) Product createProduct(@FormParam("name")String name,@FormParam("price")int price); @PUT @Path("/product/{id}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Product updateProductById(@PathParam("id")long id,Map<String,Object> fieldMap); @PUT @Path("/product") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Product updateProduct(Product product); @PUT @Path("/product/update") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) Product updateProduct(@FormParam("id")long id,@FormParam("name")String name,@FormParam("price")int price); @DELETE @Path("/product/{id}") @Produces(MediaType.APPLICATION_JSON) Product deleteProductById(@PathParam("id")long id); @DELETE @Path("/product") @Produces(MediaType.APPLICATION_JSON) Product deleteProductById_param(@QueryParam("id")long id); }
3.配置xml文件
在main文件下新建resources文件,如下图,点击右上角,将resources文件设置成源文件
在resources文件下新建spring.xml和spring-cxf.xml
spring.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="productServiceImpl" class="com.lenovo.rest.service.impl.ProductServiceImpl"></bean> <import resource="spring-cxf.xml"/> </beans> spring-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:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <jaxrs:server address="/rest"> <jaxrs:serviceBeans> <ref bean="productServiceImpl"/> </jaxrs:serviceBeans> <jaxrs:providers> <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> </jaxrs:providers> </jaxrs:server> </beans>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Demo</title> <link href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/bootstrap/3.2.0/css/colorbox.css" rel="stylesheet" type="text/css" /> <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script> <script type="text/javascript" src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script type="text/javascript" src="https://cdn.bootcss.com/handlebars.js/4.1.0/handlebars.js"></script> </head> <body> <br> <br> <div class="container"> <form role="form" id="form_name"> <div class="form-group"> <label for="input_name">根据名称检索</label> <input type="text" class="form-control" id="input_name" placeholder="名称" name="name"/> </div> <button id="submit_name" type="button" class="btn btn-default">检索</button> </form> <form role="form" id="form_create"> <div class="form-group"> <label for="input_create_name">名称</label> <input type="text" class="form-control" id="input_create_name" placeholder="名称" name="name"/> </div> <div class="form-group"> <label for="input_create_price">价格</label> <input type="text" class="form-control" id="input_create_price" placeholder="价格" name="price"/> </div> <button id="submit_create" type="button" class="btn btn-default">添加</button> </form> <div class="panel panel-default"> <button id="all" type="button" class="btn btn-default">RetrieveAll</button> <button id="byID" type="button" class="btn btn-default">RetrieveByID</button> <button id="name" type="button" class="btn btn-default">RetrieveByName</button> </div> <div class="page-header"> <h1>Product</h1> </div> <div class="panel panel-default"> <div class="panel-heading">Product List</div> <div class="panel-body"> <div id="product"></div> </div> </div> </div> <script type="text/x-handlebars-template" id="product_table_template"> {{#if data}} <table class="table table-hover" id="product_table"> <thead> <tr> <th>ID</th> <th>Product Name</th> <th>Price</th> </tr> </thead> <tbody> {{#data}} <tr data-id="{{id}}" data-name="{{name}}"> <td>{{id}}</td> <td>{{name}}</td> <td>{{price}}</td> </tr> {{/data}} </tbody> </table> {{else}} <div class="alert alert-warning">Can not find any data!</div> {{/if}} </script> <script> $(function() { //检索所有 $("#all").click(function(){ $("#product").html(""); $.ajax({ type: 'get', url: 'http://localhost:8080/springCxfREST/ws/rest/products', dataType: 'json', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); //根据ID检索 $("#byID").click(function(){ $("#product").html(""); $.ajax({ type: 'get', url: 'http://localhost:8080/springCxfREST/ws/rest/product/1', dataType: 'json', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); //根据名称检索 $("#name").click(function(){ $("#product").html(""); $.ajax({ type: 'get', url: 'http://localhost:8080/springCxfREST/ws/rest/products/name?name=ipad mini', dataType: 'json', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); //提交表单,根据名称检索 $("#submit_name").click(function(){ $("#product").html(""); $.ajax({ type: 'post', url: 'http://localhost:8080/springCxfREST/ws/rest/products/form/name?'+$("#form_name").serialize(), dataType: 'json', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); /* 提交表单,添加数据 */ $("#submit_create").click(function(){ $("#product").html(""); $.ajax({ type: 'post', url: 'http://localhost:8080/springCxfREST/ws/rest/product/create?'+$("#form_create").serialize(), dataType: 'json', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); /*使用jQuery发送基于JSONP的AJAX请求*/ $.ajax({ type: 'get', url: 'http://localhost:8080/springCxfREST/ws/rest/products', dataType: 'jsonp', jsonp: '_jsonp', jsonpCallback: 'callback', success: function(data) { var template = $("#product_table_template").html(); var render = Handlebars.compile(template); var html = render({ data: data }); $('#product').html(html); } }); }); function goColorBox(){ $("#goOne").colorbox({ opacity:0.65,width: 500, height:500, close: "关闭", overlayClose: true}); } </script> </body> </html>
1.配置tomcat及端口(pom.xml)
<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/springCxfREST</path> <uriEncoding>UTF-8</uriEncoding> <server>tomcat7</server> </configuration> </plugin> </plugins> </build>
2.将打包的压缩文件设置为.war文件
在pom.xml文件中加入<packaging>war</packaging>
如下:
<groupId>com.spring.REST</groupId> <artifactId>REST</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging>
3.点击右上角,Maven下的install开始打包
打包成功后开始运行
重新搭建一个spring框架,环境搭建和服务器端一样
1.项目目录:
2.配置pom.xml
<!--CXF--> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-service-description</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>${cxf.version}</version> </dependency> <!--Jackdon--> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-jaxrs</artifactId> <version>1.9.13</version> </dependency>
3.将服务器端Product类和ProductService接口复制过来
新建WebClientTest类
package com.spring.rest.client; import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.codehaus.jackson.jaxrs.JacksonJsonProvider; import java.util.ArrayList; import java.util.List; public class JAXRSClient { public static void main(String[] args) { JacksonJsonProvider jsonProvider = new JacksonJsonProvider(); List<Object> providerList = new ArrayList<Object>(); providerList.add(jsonProvider); ProductService us = JAXRSClientFactory.create("http://localhost:8080/springCxfREST/ws/rest",ProductService.class,providerList); List<Product> products = us.retrieveAllProducts(); System.out.println(products.size()); Product product = us.retrieveProductById(1); System.out.println(product.toString()); } }
启动服务器端,运行客户端main方法
运行结果