前提:
1、Restful风格的WS服务端:Web Service笔记(五):CXF开发RESTful风格的Web Service
2、访问客户端的技术太多了,这边总结下本人使用过的,主要是四种:WebClient 、HttpURLConnection、HttpClient 和RestTemplate
3、服务端代码实现为 Web Service笔记(五):CXF开发RESTful风格的Web Service 中的sendXml()方法,访问地址与客户端传输的xml文件分别为:
[java] view plain copy
// 发送的报文
String mRequestXml = "27 SAM-SHO 13612345678 移动 13798765432 联通 苏州高新区 苏州园区 ";
// 服务端地址
String mUrl = "http://localhost:8080/Java_WS_Server/rest/surpolicy/sendXml";
一、WebClient
(一)WebClient 客户端
1、WebClient 是CXF自带的客户端实现,比较简单实用。
2、客户端代码如下:
[java] view plain copy
/**
* WebClient 的客户端访问
*/
private void WebClientVisit() {
// 手动创建webClient对象,注意这里的地址是发布的那个/rest地址
// String url = "http://localhost:8080/Java_WS_Server/rest/";
// WebClient client = WebClient.create(url);
// 从Spring Ioc容器中拿webClient对象,或者直接用注入
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
WebClient client = ctx.getBean("webClient", WebClient.class);
// 设置超时
ClientConfiguration config = WebClient.getConfig(client);
config.getHttpConduit().getClient().setReceiveTimeout(90000);
String tResponseMsg = client.path("surpolicy/sendXml").accept(MediaType.APPLICATION_XML).post(mRequestXml, String.class);
System.out.println("返回的信息: \r\n" + tResponseMsg);
}
(二)WebClient 详解
1、WebClient.create(String url):访问地址。
2、path(String url,Object parames):地址 和 参数 。
3、accept(String… types):接收的类型。
4、get/post(Object body, Class responseClass):发送的内容 和 返回的类型。
5、设置超时(固定用法):
[java] view plain copy
ClientConfiguration config = WebClient.getConfig(client);
config.getHttpConduit().getClient().setReceiveTimeout(90000);//设置超时
(三)WebClient 工具类封装
[java] view plain copy
package cn.rest.util;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.ClientConfiguration;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.ext.form.Form;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.Logger;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
*
*Description : 客户端发送请求共通方法
*Date : May 3, 2013
*Remark :
* @version
*/
public class HttpClient {
private static Logger logger = Logger.getLogger(HttpClient.class);
public final static String ESB_REQUEST_ID = "TP-REQUEST-ID";
public final static String ESB_SERVICE_ID = "TP-SERVICE-ID";
public final static String ESB_APP_ID = "TP-APP-ID";
public final static String ESB_ACCESS_TOKEN = "TP-ACCESS-TOKEN";
public final static String ESB_REQUEST_TIME = "TP-REQUEST-TIME";
public final static String ESB_REQUEST_HASH = "TP-REQUEST-HASH";
public final static String ESB_REQUEST_EXT = "TP-REQUEST-EXT";
private static final String ENCODING = "UTF-8";
/**
* json
*/
private static final String APPLICATION_JSON = "application/json";
/**
* xml
*/
private static final String APPLICATION_XML = "text/xml";
/**
* form
*/
private static final String APPLICATION_FORM = "application/x-www-form-urlencoded";
private static final long defaultReciveTimeout = 60000;
private static long reciveTimeout;
/**
* 设置HttpClient超时时间
*
* 注意:因为是静态变量所以修改此处,会影响整个应用程序的超时。
* 如果不想影响到其他处调用的超时,在每次调用请求方法后,
* 需要再次调用 setDefaultTimeout(),恢复成默认设置。
*
* @param timeout
*/
public static void setReciveTimeout(long timeout) {
reciveTimeout = timeout;
}
public static void setDefaultTimeout() {
reciveTimeout = defaultReciveTimeout;
System.out.println("HttpClient default reciveTimeout is: " + reciveTimeout);
}
private static WebClient createClient(String url, List
二、HttpURLConnection
(一)HttpURLConnection客户端
1、java自带的api,位于net包下,使用较为繁琐,基本功能齐全。
2、客户端代码如下:
[java] view plain copy
/**
* HttpURLConnection 的客户端访问
*/
private void connectionClientVisit() {
// 定义输入输出参数
String returnXml = ""; // 核心返回结果报文字符串
String strMessage = "";
// 发送报文
BufferedReader reader = null;
StringBuffer buffer = new StringBuffer();
// System.setProperty("http.proxyHost","10.7.9.8");//设置代理
// System.setProperty("http.proxyPort","54367");
try {
URL sendUrl = new URL(mUrl);
HttpURLConnection conn = (HttpURLConnection) sendUrl.openConnection();
conn.setRequestMethod("POST");// 设定请求方式
conn.setConnectTimeout(5000); // 设置连接超时为5秒
conn.setDoOutput(true);// 设置是否向connection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true
conn.setDoInput(true);// Read from the connection. Default is true.
conn.setAllowUserInteraction(true);
conn.setUseCaches(false); // Post 请求不能使用缓存
conn.setRequestProperty("Content-Language", "GBK");
conn.setRequestProperty("Content-Type", "text/xml");// 设置header信息,这个必不可少
// 连接,从sendUrl.openConnection()至此的配置必须要在 connect 之前完成,
// 要注意的是 conn.getOutputStream 会隐含的进行 connect。
// conn.connect();//连接,可以省略
OutputStream stream = conn.getOutputStream();
stream.write(mRequestXml.getBytes());
stream.flush();
stream.close();
// 获取返回的数据
// 无论是post还是get,http请求实际上直到HttpURLConnection.getInputStream()这个函数里面才正式发送出去。
InputStream inputStream = conn.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((strMessage = reader.readLine()) != null) {
buffer.append(strMessage);
}
returnXml = buffer.toString();
System.out.println("HttpURLConnection 的客户端接收返回值: \r\n" + returnXml);
reader.close();
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
(二)HttpURLConnection 详解:注意发送的时机
1、Get方式的访问:
[java] view plain copy
/**
* Get方式
* @throws IOException
*/
public static void readContentFromGet() throws IOException {
// 拼凑get请求的URL字串,使用URLEncoder.encode对特殊和不可见字符进行编码
String getURL = GET_URL + "?username=" + URLEncoder.encode("你好", "utf-8");
URL getUrl = new URL(getURL);
// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,
// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到服务器
connection.connect();
// 取得输入流,并使用Reader读取
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
System.out.println("=============================");
System.out.println("Contents of get request");
System.out.println("=============================");
String lines;
while ((lines = reader.readLine()) != null) {
System.out.println(lines);
}
reader.close();
// 断开连接
connection.disconnect();
System.out.println("=============================");
System.out.println("Contents of get request ends");
System.out.println("=============================");
}
2、Post方式的访问:
[java] view plain copy
/**
* Post 方式
* @throws IOException
*/
public static void readContentFromPost() throws IOException {
// Post请求的url,与get不同的是不需要带参数
URL postUrl = new URL(POST_URL);
// 打开连接
HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
// Output to the connection. Default is
// false, set to true because post
// method must write something to the
// connection
// 设置是否向connection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true
connection.setDoOutput(true);
// Read from the connection. Default is true.
connection.setDoInput(true);
// Set the post method. Default is GET
connection.setRequestMethod("POST");
// Post cannot use caches
// Post 请求不能使用缓存
connection.setUseCaches(false);
// This method takes effects to
// every instances of this class.
// URLConnection.setFollowRedirects是static函数,作用于所有的URLConnection对象。
// connection.setFollowRedirects(true);
// This methods only
// takes effacts to this
// instance.
// URLConnection.setInstanceFollowRedirects是成员函数,仅作用于当前函数
connection.setInstanceFollowRedirects(true);
// Set the content type to urlencoded,
// because we will write
// some URL-encoded content to the
// connection. Settings above must be set before connect!
// 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
// 意思是正文是urlencoded编码过的form参数,下面我们可以看到我们对正文内容使用URLEncoder.encode
// 进行编码
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
// 要注意的是connection.getOutputStream会隐含的进行connect。
connection.connect();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
// The URL-encoded contend
// 正文,正文内容其实跟get的URL中'?'后的参数字符串一致
String content = "firstname=" + URLEncoder.encode("一个大肥人", "utf-8");
// DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面
out.writeBytes(content);
out.flush();
out.close(); // flush and close
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
System.out.println("=============================");
System.out.println("Contents of post request");
System.out.println("=============================");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println("=============================");
System.out.println("Contents of post request ends");
System.out.println("=============================");
reader.close();
connection.disconnect();
}
3、利用setChunkedStreamingMode 改变发送的时机
[java] view plain copy
/**
* 利用setChunkedStreamingMode 改变发送的时机
* @throws IOException
*/
public static void readContentFromChunkedPost() throws IOException {
URL postUrl = new URL(POST_URL);
HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
/**//*
* 与readContentFromPost()最大的不同,设置了块大小为5字节
*/
connection.setChunkedStreamingMode(5);
connection.connect();
/**//*
* 注意,下面的getOutputStream函数工作方式于在readContentFromPost()里面的不同
* 在readContentFromPost()里面该函数仍在准备http request,没有向服务器发送任何数据
* 而在这里由于设置了ChunkedStreamingMode,getOutputStream函数会根据connect之前的配置
* 生成http request头,先发送到服务器。
*/
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
String content = "firstname="
+ URLEncoder.encode("一个大肥人 " + " "
+ "asdfasfdasfasdfaasdfasdfasdfdasfs", "utf-8");
out.writeBytes(content);
out.flush();
out.close(); // 到此时服务器已经收到了完整的http
// request了,而在readContentFromPost()函数里,要等到下一句服务器才能收到http请求。
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
out.flush();
out.close(); // flush and close
String line;
System.out.println("=============================");
System.out.println("Contents of post request");
System.out.println("=============================");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println("=============================");
System.out.println("Contents of post request ends");
System.out.println("=============================");
reader.close();
connection.disconnect();
}
(三)HttpURLConnection 工具类封装
[java] view plain copy
package cn.rest.util;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class OtherHttpClient {
private Map parameters = new HashMap();
private String url;
private String service;
private String sendEncode = "UTF-8";
private String receiceEncode = "UTF-8";
public void addParameter(String name, String value) {
this.parameters.put(name, value);
}
/**
* 设置代理
*
* @param host
* @param port
*/
public void setProxy(String host, String port) {
System.getProperties().put("proxySet", "true");
System.getProperties().setProperty("http.proxyHost", host);
System.getProperties().setProperty("http.proxyPort", port);
}
/**
* Post 方法
*
* @return
* @throws Exception
*/
public String post() throws Exception {
String response = "";
try {
response = send();
} catch (Exception e) {
e.printStackTrace();
throw new Exception("PostFailure,Url:" + this.url, e);
}
return response;
}
/**
* Get 方法
*
* @param httpUrl
* @param encode
* @return
* @throws Exception
*/
public String get(String httpUrl, String encode) throws Exception {
String html = "";
try {
System.out.println("Http Access Url:" + httpUrl);
URL url = new URL(httpUrl);
URLConnection c = url.openConnection();
InputStream inputs = c.getInputStream();
int all = inputs.available();
byte[] b = new byte[all];
inputs.read(b);
html = new String(b, encode);
inputs.close();
} catch (Exception e) {
e.printStackTrace();
throw new Exception("getFailure,Url:" + httpUrl);
}
String returnContent = html.toString();
System.out.println("Url return:\n" + returnContent);
return returnContent;
}
private String send() throws Exception {
URLConnection con;
URL url;
String response;
String paramStr = "";
Object[] services = this.parameters.keySet().toArray();
StringBuffer rspContent = null;
BufferedReader reader = null;
DataInputStream in = null;
for (int i = 0; i < services.length; ++i) {
if (i == 0)
paramStr = paramStr + services[i] + "=" + URLEncoder.encode(this.parameters.get(services[i]).toString(), getSendEncode());
else
paramStr = paramStr + "&" + services[i] + "=" + URLEncoder.encode(this.parameters.get(services[i]).toString(), getSendEncode());
}
try {
String aLine;
url = new URL(getUrl());
con = url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
byte[] sendParamByte = paramStr.toString().getBytes("iso8859_1");
con.setRequestProperty("Content-length", String.valueOf(sendParamByte.length));
DataOutputStream dataOut = new DataOutputStream(con.getOutputStream());
dataOut.write(sendParamByte);
dataOut.flush();
dataOut.close();
rspContent = new StringBuffer();
in = new DataInputStream(con.getInputStream());
reader = new BufferedReader(new InputStreamReader(in, getReceiceEncode()));
while ((aLine = reader.readLine()) != null) {
rspContent.append(aLine + "\n");
}
response = rspContent.toString();
in.close();
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
} finally {
if (reader != null)
reader.close();
if (in != null)
in.close();
}
return response;
}
public String sendStream(String content) throws Exception {
URLConnection con;
URL url;
String response;
String paramStr = URLEncoder.encode(content, getSendEncode());
StringBuffer rspContent = null;
BufferedReader reader = null;
DataInputStream in = null;
try {
String aLine;
url = new URL(getUrl());
con = url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
byte[] sendParamByte = paramStr.toString().getBytes("iso8859_1");
con.setRequestProperty("Content-length", String.valueOf(sendParamByte.length));
con.setRequestProperty("Keep-alive", "false");
DataOutputStream dataOut = new DataOutputStream(con.getOutputStream());
dataOut.write(sendParamByte);
dataOut.flush();
dataOut.close();
rspContent = new StringBuffer();
in = new DataInputStream(con.getInputStream());
reader = new BufferedReader(new InputStreamReader(in, getReceiceEncode()));
while ((aLine = reader.readLine()) != null) {
rspContent.append(aLine + "\n");
}
response = rspContent.toString();
in.close();
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
} finally {
if (reader != null)
reader.close();
if (in != null)
in.close();
}
return response;
}
public String sendObjStream(Object content) throws Exception {
URLConnection con;
URL url;
String response;
StringBuffer rspContent = null;
BufferedReader reader = null;
DataInputStream in = null;
try {
String aLine;
url = new URL(getUrl());
con = url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
ObjectOutputStream dataOut = new ObjectOutputStream(con.getOutputStream());
dataOut.writeObject(content);
dataOut.flush();
dataOut.close();
rspContent = new StringBuffer();
in = new DataInputStream(con.getInputStream());
reader = new BufferedReader(new InputStreamReader(in, getReceiceEncode()));
while ((aLine = reader.readLine()) != null) {
rspContent.append(aLine + "\n");
}
response = rspContent.toString();
in.close();
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
} finally {
if (reader != null)
reader.close();
if (in != null)
in.close();
}
return response;
}
public void persistentPDF(String conurl, String fileName) throws IOException {
String paramStr = "";
Object[] services = this.parameters.keySet().toArray();
DataInputStream in = null;
try {
for (int i = 0; i < services.length; ++i) {
if (i == 0)
paramStr = paramStr + services[i] + "=" + URLEncoder.encode(this.parameters.get(services[i]).toString(), getSendEncode());
else {
paramStr = paramStr + "&" + services[i] + "=" + URLEncoder.encode(this.parameters.get(services[i]).toString(), getSendEncode());
}
}
/*
* LogTool.debug(super.getClass(), "\nServiceName:" + this.service +
* "\n" + "Request URL:" + conurl);
*/
URL url = new URL(conurl);
URLConnection con = url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
byte[] sendParamByte = paramStr.toString().getBytes("ISO8859-1");
con.setRequestProperty("Content-length", String.valueOf(sendParamByte.length));
DataOutputStream dataOut = new DataOutputStream(con.getOutputStream());
dataOut.write(sendParamByte);
dataOut.flush();
dataOut.close();
in = new DataInputStream(con.getInputStream());
if (in == null)
return;
OutputStream outPDFStream = new FileOutputStream(fileName);
int readSize = 0;
int blockSize = 15360;
byte[] buffer = new byte[blockSize];
while ((readSize = in.read(buffer, 0, buffer.length)) > 0) {
outPDFStream.write(buffer, 0, readSize);
}
label384: outPDFStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null)
in.close();
}
}
public byte[] read(InputStream is) {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
byte imgdata[] = null;
try {
while ((ch = is.read()) != -1) {
bytestream.write(ch);
}
imgdata = bytestream.toByteArray();
bytestream.close();
} catch (IOException e) {
e.printStackTrace();
}
return imgdata;
}
public String getSendEncode() {
return this.sendEncode;
}
public void setSendEncode(String sendEncode) {
this.sendEncode = sendEncode;
}
public String getReceiceEncode() {
return this.receiceEncode;
}
public void setReceiceEncode(String receiceEncode) {
this.receiceEncode = receiceEncode;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public Map getParameters() {
return this.parameters;
}
public void setParameters(Map parameters) {
this.parameters = parameters;
}
public String getService() {
return this.service;
}
public void setService(String service) {
this.service = service;
}
public static void main(String[] args) throws Exception {
OtherHttpClient client = new OtherHttpClient();
client.setProxy("10.100.11.148", "909");
client.setUrl("http://www.baidu.com");
client.addParameter("test1", "1");
String returnContent = client.post();
System.out.println(returnContent);
}
}