近期在對接項目時用到http方式與第三方交互數據,由於中間溝通不足導致走了不少彎路,至此特意花了點時間總結服務端與客戶端數據交互的方式,本地搭建兩個項目一個作為服務端,一個作為客戶端。post可以有兩種方式:一種與get一樣,將請求參數拼接在url后面,這種服務端就以request.getParameter獲取內容;另一種以流的方式寫入到http鏈接中,服務端再從流中讀取數據,在HttpURlConnection中分別用到了GET、POST請求方式,HttpClient以及commons-httpClient均以POST請求為例。
服務端代碼:
package com.lutongnet.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Server_ccy
*/
@WebServlet("/Server_ccy")
public class Server_ccy extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Server_ccy() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
System.out.println("server-------doGet..start.");
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("server-------params:"+name+":"+password);
System.out.println("server-------doGet..end.");
PrintWriter out = response.getWriter();
out.print("{\"姓名\":\"陳昌圓\"}");
out.flush();
out.close();
//response.getWriter().append("server_get_info:").append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//doGet(request, response);
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
System.out.println("server-------doPost..start.");
System.out.println("ContentType---->"+response.getContentType());
System.out.println("queryString---->"+request.getQueryString());
String name = request.getParameter("name");
System.out.println("name---->"+name);
//String password = request.getParameter("password");
//System.out.println("server-------params:"+name+":"+password);
StringBuffer sb = new StringBuffer("");
String str;
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
if((str = br.readLine()) != null){
sb.append(str);
}
System.out.println("從客戶端獲取的參數:"+sb);
System.out.println("server-------doPost..end.");
PrintWriter out = response.getWriter();
out.print("{\"姓名\":\"陳昌圓\"}");
out.flush();
out.close();
}
}
客戶端代碼:
1.HttpURLConnection:主要詳細分析GET與POST兩種請求方式,我們項目中的api就是用的這種
package com.lutongnet.HttpURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
public class HttpURLConnectionTest {
public static void main(String[] args) {
String url = "http://localhost:7373/ccy_server/ccy";
//String params = "name=ccy&password=123";
String params = "{\"name\":\"陳昌圓\",\"password\":\"123\"}";
try {
String result = httpGetOrPost("POST", url, params);
System.out.println("client---result:"+result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String httpGetOrPost(String type, String url, String params) throws Exception{
//get請求通過url傳參(post可以通過url傳參也可以將參數寫在http正文傳參)
if("GET".equals(type)){
if(url.contains("?")){
url += "&" + params;
}else{
url += "?" + params;
}
}
System.out.println("請求地址:" + url);
System.out.println("請求參數:" + params);
URL u = new URL(url);
/*
* 查看URL API 發現 openConnection方法返回為URLConnection
* HttpURLConnection為URLConnection的子類,有其更多的實現方法,
* 通常將其轉型為HttpURLConnection
* */
HttpURLConnection httpConn = (HttpURLConnection) u.openConnection();
//設置請求方式 默認是GET
httpConn.setRequestMethod(type);
//寫 默認均為false,GET不需要向HttpURLConnection進行寫操作
if("POST".equals(type)){
httpConn.setDoOutput(true);
}
httpConn.setDoInput(true);//讀 默認均為true,HttpURLConnection主要是用來獲取服務器端數據 肯定要能讀
httpConn.setAllowUserInteraction(true);//設置是否允許用戶交互 默認為false
httpConn.setUseCaches(false);//設置是否緩存
httpConn.setConnectTimeout(5000);//設置連接超時時間 單位毫秒 ms
httpConn.setReadTimeout(5000);//設置訪問超時時間
//setRequestProperty主要設置http請求頭里面的相關屬性
httpConn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31");
httpConn.setRequestProperty("accept", "*/*");
httpConn.setRequestProperty("Content-Type", "application/json");
//開啟連接
httpConn.connect();
//post方式在建立連接后把頭文件內容從連接的輸出流中寫入
if("POST".equals(type)){
//在調用getInputStream()方法中會檢查連接是否已經建立,如果沒有建立,則會調用connect()
OutputStreamWriter out = new OutputStreamWriter(httpConn.getOutputStream(), "utf-8");
out.write(params);//將數據寫入緩沖流
out.flush();//將緩沖區數據發送到接收方
out.close();
}
System.out.println("httpcode:"+httpConn.getResponseCode());
//讀取響應,現在開始可以讀取服務器反饋的數據
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String str;
while((str = br.readLine()) != null){
sb.append(str);
}
System.out.println(new Date()+"---響應:"+sb);
br.close();
httpConn.disconnect();
return sb.toString();
}
}
get請求運行結果
客戶端:

服務端:

post請求運行結果
客戶端:

服務端:

2.DefaultHttpClient:需要導入三個包,httpclient-4.1.jar,httpcode-4.1.jar,commons-logging-1.1.1.jar,doPost方法是直接可以請求https,doPost2為的http方式,日后若有需要對接第三方接口需要https協議可以參考doPost方法
package com.lutongnet.HttpClient;
import java.security.cert.CertificateException;
public class HttpClientDemo {
public static void main(String[] args) {
HttpClientDemo hct = new HttpClientDemo();
String url = "http://localhost:7373/ccy_server/ccy";
Map<String, String> map = new HashMap<String, String>();
map.put("name", "ccy");
map.put("password", "123");
String charset = "utf-8";
String result = hct.doPost(url, map, charset);
System.out.println("1.獲取服務器端數據為:"+result);
String params = "{\"name\":\"陳昌圓\",\"password\":\"123\"}";
String result2 = hct.doPost2(url, params);
System.out.println("2.獲取服務器端數據為:"+result2);
}
public String doPost2(String url, String content) {
System.out.println("請求地址:" + url);
System.out.println("請求參數:" + content);
String charsetName = "utf-8";
DefaultHttpClient httpclient = null;
HttpPost post = null;
try {
httpclient = new DefaultHttpClient();
post = new HttpPost(url);
post.setHeader("Content-Type", "application/json;charset=" + charsetName);
post.setEntity(new StringEntity(content, charsetName));
HttpResponse response = httpclient.execute(post);
HttpEntity entity = response.getEntity();
String rsp = EntityUtils.toString(entity, charsetName);
System.out.println("返回參數: "+rsp);
return rsp;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpclient.getConnectionManager().shutdown();
} catch (Exception ignore) {}
}
}
public String doPost(String url,Map<String,String> map,String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = new SSLClient();
httpPost = new HttpPost(url);
//設置參數
List<NameValuePair> list = new ArrayList<NameValuePair>();
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Entry<String,String> elem = (Entry<String, String>) iterator.next();
list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
}
if(list.size() > 0){
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
httpPost.setEntity(entity);
}
HttpResponse response = httpClient.execute(httpPost);
if(response != null){
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
class SSLClient extends DefaultHttpClient{
public SSLClient() throws Exception{
super();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, (SchemeSocketFactory) ssf));
}
}
}
post請求運行結果
客戶端:

服務端:

3.commons-httpclient:需要導入兩個包,commons-httpclient-3.0.jar,commons-codec-1.7.jar,這種方式是最簡潔的,前后不到10行代碼就解決了,不過需要注意的是設置正文編碼,5種方式都可行,這種將參數拼接在http正文中,在服務端可以利用request.getParameter()方法獲取參數,也可以用request.getInputStream()流的方式獲取參數(這種方式如果參數中有中文的話,暫時沒有找到解決亂碼的方法)
package com.lutongnet.commonHttpclient;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class CommonHttpClient {
public static void main(String[] args) {
String url = "http://localhost:7373/ccy_server/ccy";
List<String> params = new ArrayList<String>();
params.add("陳昌圓");
params.add("123");
CommonHttpClient chc = new CommonHttpClient();
String result = chc.getPostMethod(url, params);
System.out.println("commonHttpClient---->從服務端獲取的數據:" + result);
}
private String getPostMethod(String url, List<String> params) {
String result = null;
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
//httpClient.getParams().setContentCharset("utf-8");
//httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
//postMethod.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
//postMethod.addRequestHeader("Content-Type", PostMethod.FORM_URL_ENCODED_CONTENT_TYPE
// + "; charset=utf-8");
postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
"utf-8");
postMethod.addParameter("name", params.get(0));
postMethod.addParameter("password", params.get(1));
try {
httpClient.executeMethod(postMethod);
result = postMethod.getResponseBodyAsString();
System.out.println("result:" + result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/*class ccyPostMethod extends PostMethod {
public ccyPostMethod(String url) {
super(url);
}
@Override
public String getRequestCharSet() {
return "utf-8";
}
}*/
}
post請求運行結果
客戶端:

服務端:

參考原文:https://www.cnblogs.com/ccylovehs/p/7028818.html

