Spring集成CXF,发布REST风格ws服务

一、相关技术简介

1、RESTFUL简介:

    REST( 英文:Representational State Transfer,简称REST)是一种软件架构风格,设计风格,而不是标准,它提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
    REST描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
    REST是REST之父Roy Thomas创造的,当时提出来了REST的6个特点:客户端-服务器的、无状态的、可缓存的、统一接口、分层系统和按需编码。其具有跨语言和跨平台的优势。 对于资源的具体操作类型,由HTTP动词表示。
    常用的HTTP动词有下面五个(括号里是对应的SQL命令) 
    GET(SELECT):从服务器取出资源(一项或多项)。
        //注意,资源的大小有限制如果要获取大文件,如图片,视频等,需以流的方式下载
    POST(CREATE):在服务器新建一个资源,即插入操作。
    PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)更改或者添加资源,与POST在使用上基本一致。
    PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性),只改变部分属性。
    DELETE(DELETE):从服务器删除资源。即删除操作,一般比较少用,毕竟没有谁会允许他人远程删除自己的资源。
 
    通过 REST 风格体系架构,请求和响应都是基于资源表示的传输来构建的。资源是通过全局 ID 来标识的,这些 ID 一般使用的是一个统一资源标识符(URI)。客户端应用使用 HTTP 方法(如,GET、POST、PUT 或 DELETE)来操作一个或多个资源。通常,GET 是用于获取或列出一个或多个资源,POST 用于创建,PUT 用于更新或替换,而 DELETE 则用于删除资源。
    例如,GET  http://host/context/employees/12345 将获取 ID 为 12345 的员工的表示。这个响应表示可以是包含详细的员工信息的 XML 或 ATOM,或者是具有更好 UI 的 JSP/HTML 页面。您看到哪种表示方式取决于服务器端实现和您的客户端请求的 MIME 类型。    
    RESTful Web Service 是一个使用 HTTP 和 REST 原理实现的 Web Service。通常,一个 RESTful Web Service 将定义基本资源 URI、它所支持的表示/响应 MIME,以及它所支持的操作。
----------------------------------------------------------------------------------------------------------------------------------------
 2、JAX-RS简介

    JAX-RS是Java提供用于开发RESTful Web服务基于注解(annotation)的API。JAX-RS旨在定义一个统一的规范,使得Java程序员可以使用一套固定的接口来开发REST应用,避免了依赖第三方框架。同时JAX-RS使用POJO编程模型和基于注解的配置并集成JAXB,可以有效缩短REST应用的开发周期。JAX-RS只定义RESTful API,具体实现由第三方提供,如Jersey、Apache CXF等。 

JAX-RS包含近五十多个接口、注解和抽象类:

javax.ws.rs包含用于创建RESTful服务资源的高层次(High-level)接口和注解。

javax.ws.rs.core包含用于创建RESTful服务资源的低层次(Low-level)接口和注解。

javax.ws.rs.ext包含用于扩展JAX-RS API支持类型的APIs。

 

JAX-RS常用注解:

@Path:标注资源类或方法的相对路径。

@GET、@PUT、@POST、@DELETE:标注方法的HTTP请求类型。

@Produces:标注返回的MIME媒体类型。

@Consumes:标注可接受请求的MIME媒体类型。

@PathParam、@QueryParam、@HeaderParam、@CookieParam、@MatrixParam、@FormParam:标注方法的参数来自于HTTP请求的位置。@PathParam来自于URL的路径,@QueryParam来自于URL的查询参数,@HeaderParam来自于HTTP请求的头信息,@CookieParam来自于HTTP请求的Cookie。


二、参考资料:     
    1)、使用 Spring 3 来创建 RESTful Web Services( http://www.ibm.com/developerworks/cn/web/wa-spring3webserv/)
    2)、Apache CXF与Spring集成实现Soap Webservice与RESTFul         WebService( http://blog.csdn.net/javacloudfei/article/details/38555803)
    3)、http://www.benchresources.net/apache-cxf-jax-rs-restful-web-service-for-uploadingdownloading-text-file-java-client/
         JAX-RS Restful web service for uploading/downloading Text file + Java client  
    

三、基于Spring+CXF+RestFul服务器的开发和客户端的使用例子

1、项目需求

    在服务器端提供一个web接口,供远程调用,以向服务器端传送图片。要求图片的数量不定,每一张图片都有相关的说明,且以二进制的形式保存。相关信息需要保存在MongoDB中。

    资源的具体结构如下:

    <GeologyInfo>

    private Long uploadTime; //上传时间

    private String tbmId;  //设备型号
    private double op_num_start;  //起始进程
    private double op_num_end;   //结束里程
    private List<ImgInfo> imgs = new ArrayList<ImgInfo>();  //图片信息集合

    private String remark;  //备注

-----------------------------------------------------------------------------------------------

    <ImgInfo>

    private String fileName;//图片名称(带后缀名,如.jpg等)
    private String fileInstrc;//图片说明
    private String imgContent;//图片转成二进制

    private String suffix;//后缀名


2、服务端开发

1)、所需jar包

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>    
     <!-- http://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
     <!-- cxf -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>${cxf.version}</version>
</dependency>
    <!-- http://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxrs -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-frontend-jaxrs</artifactId>
  <version>${cxf.version}</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>${cxf.version}</version>  
</dependency>
<!-- 解决跨域问题 -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-security-cors</artifactId>
    <version>${cxf.version}</version>
</dependency>
<!-- CXF客户端 -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-client</artifactId>
    <version>${cxf.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/jsr311-api -->
<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>jsr311-api</artifactId>
    <version>1.1.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.ws.xmlschema/xmlschema-core -->
<dependency>
    <groupId>org.apache.ws.xmlschema</groupId>
    <artifactId>xmlschema-core</artifactId>
    <version>2.2.1</version>
</dependency>

<!-- MongoDB -->
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.2.1</version>
</dependency>

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-asm -->
<!-- <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-asm</artifactId>
    <version>3.1.4.RELEASE</version>
</dependency> -->


<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring.version}</version>
</dependency>

   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>

<!-- <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</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-expression</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.0</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
</dependency>

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant</artifactId>
    <version>1.9.7</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.3</version>
</dependency>

<dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-jaxrs</artifactId>  
            <version>1.9.13</version>  
        </dependency>  
        
        <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.36</version>
</dependency>
        
        <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
   <classifier>jdk15</classifier>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>

<!--commons-codec是Commons项目中用来处理常用的编码方法的工具类包,例如DES、SHA1、MD5、Base64,URL,Soundx等等。-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.4</version>
        </dependency>
        
          <!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-xc -->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.13</version>
</dependency>    

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</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>
<!-- 配置文件地址 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/conf/applicationContext*.xml</param-value>
</context-param>


<!--spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


<!--cxf的Servlet -->
<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>/cxf/*</url-pattern>
</servlet-mapping>


<!-- 编码格式 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<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)、相关文件配置

----------------Spring applicationContext.xml配置--------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"  
    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-4.0.xsd   
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-4.0.xsd ">  
    
     <!-- http://www.springframework.org/schema/aop  
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   
xmlns:aop="http://www.springframework.org/schema/aop"  -->
    <!-- 注解配置 -->
<!-- 使用 annotation -->
<context:annotation-config />
<!-- 自动扫描所有注解该路径 -->
<context:component-scan base-package="tbmcloud_ws.server,tbmcloud_ws.dao"/>       
<!-- <aop:aspectj-autoproxy /> -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!--引入cxf的配置文件-->
    <import resource="classpath:conf/cxf_*.xml"/>    
<!-- 数据源配置,在生产环境使用应用服务器的数据库连接池 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath*:/conf/*.properties</value>
</property>
</bean>
<bean name="mongoClientsBean" class="tbmcloud_ws.dao.bean.MongoClientsBean" init-method="init" destroy-method="destroy">
<property name="url" value="${mongoUrl}" />

</bean>

    以下为MongoDB、MySql、MyBatis、定时器等的配置,略。


------------------CXF拦截器,暴露的服务类等设置----------------------------------------------------------------------------

cxf_server.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
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-4.0.xsd   
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">  
<jaxrs:server id="webService" address="/restFul">
<!--输入拦截器设置 -->
<jaxrs:inInterceptors>
<!-- 自定义的拦截器,用于对接收到的请求认证过虑 -->
<bean class="tbmcloud_ws.interceptors.AuthInterceptor"></bean>
<!-- 压缩过虑 -->
<bean class="org.apache.cxf.transport.common.gzip.GZIPInInterceptor"></bean>
</jaxrs:inInterceptors>
<!--输出拦截器设置 -->
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.transport.common.gzip.GZIPOutInterceptor"></bean>
</jaxrs:outInterceptors>
<!--serviceBeans:暴露的WebService服务类 -->
<jaxrs:serviceBeans>
<ref bean="geoServer"/>
</jaxrs:serviceBeans>
<!--支持的协议 -->
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
<!--编码格式 -->
<jaxrs:languageMappings>
</jaxrs:languageMappings>
<!--对象转换 -->
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<bean id="geoServer" class="tbmcloud_ws.server.impl.GeologyInfoServerImpl"></bean>
</beans>

4)、定义server接口

import java.util.Map;
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 javax.ws.rs.core.Response;
import org.bson.Document;

@Path("/geologyWs")
public interface GeologyInfoServer {
@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Path("/getTestDemo/{tbmId}/{op_num_start}/{op_num_end}")
public Map<String,Object> getTestDemo(@PathParam("tbmId")String tbmId,@PathParam("op_num_start")Double op_num_start,@PathParam("op_num_end")Double op_num_end);

@POST
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Path("/addGeologyInfo")
public boolean addGeologyInfo(Document gfo);

@PUT
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Path("/putGeologyInfo")
public Response putGeologyInfo(Document gfo);

}

5)、编写server的实现类

import java.util.*;
import javax.annotation.Resource;
import javax.ws.rs.core.Response;
import org.bson.Document;
import tbmcloud_ws.dao.mapper.GeologyInfoMapper;
import tbmcloud_ws.dao.mongo.MongoDao;
import tbmcloud_ws.server.GeologyInfoServer;
public class GeologyInfoServerImpl implements GeologyInfoServer {
private static final String collName = "tbm_geology_forecast";
@Resource 
private GeologyInfoMapper geologyInfoMapper;
@Resource
private MongoDao mdao;
//用于测试
public Map<String,Object> getTestDemo(String tbmId, Double op_num_start, Double op_num_end) {
Map<String,Object> map = new HashMap<String,Object>();
map.put("tbmId", tbmId);
map.put("success", true);
return map;
}

        //将接收到的信息保存至MongoDB
public boolean addGeologyInfo(Document gfo) {
try {
mdao.addCommonDoc(collName, gfo);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;

}

        //将接收到的信息保存至MongoDB

public Response putGeologyInfo(Document gfo) {
try {
mdao.addCommonDoc(collName, gfo);
return Response.ok().build();
} catch (Exception e) {
e.printStackTrace();
return Response.serverError().build();
}
}

}

6)、拦截器的编写

目的在于对接收到的请求的用户认证,URL过滤等,此例只做用户认证

import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import tbmcloud_ws.dao.bean.JdbcBean;
import tbmcloud_ws.utils.EncryptionUtil;
public class AuthInterceptor extends AbstractPhaseInterceptor<Message> {
@Resource
private JdbcBean jdao;
public AuthInterceptor(String phase){
super(phase);
}
public AuthInterceptor() {
super(Phase.RECEIVE); //当接收到请求时拦截
}


public void handleMessage(Message mess) throws Fault {
//在请求信息的头文档中获取用户名和密码
RuntimeException ex = null;
Map m1 = (Map)mess.get("org.apache.cxf.message.Message.PROTOCOL_HEADERS");
System.out.println(m1);
List usernames = (List)m1.get("username");
List pwds = (List)m1.get("pwd");
if(usernames.size()>0 && pwds.size()>0){
String username = usernames.get(0).toString();
String npwd = pwds.get(0).toString();
npwd = EncryptionUtil.getShaHash(npwd);
//查询数据库,用户名和密码是否存在
String sql = "SELECT * FROM `sys_user_ws` where username='lihuawei' ";
List<Map<String, Object>> list = jdao.select(sql);
if(list==null || list.size()==0){
ex = new RuntimeException("用户不存在");
throw new Fault(ex);
}
else{
Map<String,Object> m = list.get(0);
String pwd = m.get("pwd").toString();
if(!pwd.equalsIgnoreCase(pwd)){
ex = new RuntimeException("用户名或者密码错误");
throw new Fault(ex);
}
}
}
else{
ex = new RuntimeException("请输入用户名和密码");
throw new Fault(ex);
}
}

}

7)、项目发布,启动服务,测试接口(略)

3、客户端的编写

项目架构图:


1)、相关jar包

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>${cxf.version}</version>
</dependency>
    <!-- http://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxrs -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-frontend-jaxrs</artifactId>
  <version>${cxf.version}</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>${cxf.version}</version>  
</dependency>
<!-- 解决跨域问题 -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-security-cors</artifactId>
    <version>${cxf.version}</version>
</dependency>
<!-- CXF客户端 -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-client</artifactId>
    <version>${cxf.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/jsr311-api -->
<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>jsr311-api</artifactId>
    <version>1.1.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.ws.xmlschema/xmlschema-core -->
<dependency>
    <groupId>org.apache.ws.xmlschema</groupId>
    <artifactId>xmlschema-core</artifactId>
    <version>2.2.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</dependency>
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
   <classifier>jdk15</classifier>
</dependency>

  </dependencies>

2)、对服服输器端的链接地址、用户信息等进行封装

import java.net.URI;
import org.apache.http.client.methods.HttpPost;
import com.creg973.tbmcloud_ws_client.authorize.AuthorizeInfo;
public class MyHttpPost extends HttpPost  implements AuthorizeInfo{
private final String url = baseUrl + "/geologyWs/addGeologyInfo";
public MyHttpPost(){
this.setURI(URI.create(url));
this.addHeader("content-type","application/json");
this.setUserName(USERNAME);
this.setPwd(PWD);
}
public void setUserName(String userName){
this.addHeader("username",userName);
}
public void setPwd(String pwd){
this.addHeader("pwd",pwd);
}

}

3)、编写客户端应用方法

import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.creg973.tbmcloud_ws_client.entity.GeologyInfo;
import com.creg973.tbmcloud_ws_client.entity.ImgInfo;
import com.creg973.tbmcloud_ws_client.method.MyHttpGet;
import com.creg973.tbmcloud_ws_client.method.MyHttpPost;
import com.creg973.tbmcloud_ws_client.method.MyHttpPut;
import com.creg973.tbmcloud_ws_client.utils.ImgFileUtil;
import net.sf.json.JSONObject;
public class GeologyInfoClient {
public static void main(String[] args) {
try {
GeologyInfo gfo = new GeologyInfo();
gfo.setUploadTime(System.currentTimeMillis());
gfo.setTbmId("CREC305");
gfo.setOp_num_start(123.5);
gfo.setOp_num_end(456.7);
gfo.setRemark("初次保存");


String fileName = "D:\\002.jpg";
String content1 = ImgFileUtil.decodeImgFile(fileName);//将图片转化成二进制字符串
ImgInfo img1 = new ImgInfo(new File(fileName).getName(), "描述1", content1);
gfo.getImgs().add(img1);
try {
String flag = httpMethodAdd(gfo);
System.out.println(flag);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// @Get
private static void httpGetGeologyInfo(String tbmId, Double op_num_start, Double op_num_end) throws Exception {
if (op_num_start > op_num_end) {
System.out.println("开始桩号需小于等于结束桩号");
return;
}
CloseableHttpClient client = HttpClients.createDefault();
MyHttpGet httpGet = new MyHttpGet();
httpGet.setParams(new Object[] { tbmId, op_num_start, op_num_end });
CloseableHttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
System.out.println(result);
}
// @put
private static void httpMethodPut(GeologyInfo obj) throws Exception {
CloseableHttpClient client = HttpClients.createDefault();
HttpPut putGo = new MyHttpPut();
JSONObject c = JSONObject.fromObject(obj);
String ms = c.toString();
StringEntity entity = new StringEntity(ms, "UTF-8");
putGo.setEntity(entity);
CloseableHttpResponse response2 = client.execute(putGo);
System.out.println(response2.getStatusLine());
}


// @POST
private static String httpMethodAdd(GeologyInfo gfo) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
MyHttpPost httpMethod = new MyHttpPost();
JSONObject c = JSONObject.fromObject(gfo);
String ms = c.toString();
StringEntity entity = new StringEntity(ms, "UTF-8");
httpMethod.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httpMethod);
String rst = EntityUtils.toString(response.getEntity());
return rst;
}

}

4)、具体的测试,略。

补充说明:

    如果要将以上应用嵌套至WEB应用中,可使用org.apache.cxf.jaxrs.client.WebClient类进行处理。具体使用方法在这里不作详细说明。仅提供一个封装类供参考

import javax.ws.rs.core.MediaType;
import org.apache.cxf.jaxrs.client.WebClient;
import com.creg973.tbmcloud_ws_client.authorize.AuthorizeInfo;
public class MyBaseHttp implements AuthorizeInfo{
protected WebClient client;
public MyBaseHttp(){
client = WebClient.create(baseUrl);
client.accept(MediaType.APPLICATION_JSON);//客户端要接收的类型
    client.type(MediaType.APPLICATION_JSON);//发出去的数据类型,java对象会转换为该类型
    client.header("username",USERNAME);
    client.header("pwd",PWD);
}
public WebClient getClient() {
return client;
}
public void setClient(WebClient client) {
this.client = client;
}

}


import java.util.Collection;public class MyHttpGet2 extends MyBaseHttp{private String serverUrl = "/geologyWs";private String methodName = "/getGeologyInfo";public MyHttpGet2(){client.path(serverUrl);client.path(methodName);}public MyHttpGet2(String serverUrl,String methodName){client.path(serverUrl);client.path(methodName);}public void setParams(Object[] ary){if(ary.length>0){for(int i=0;i<ary.length;i++){client.path("/"+ary[i]);}}}public  <T>Collection<? extends T> getCollection(Class<T> param){Collection<? extends T> colls = client.getCollection(param);return colls;}public  <T>T getEntity(Class<T> param){System.out.println(client.get());T  t = client.get(param);return t;}}