Web服務器與客戶端三種http交互方式


近期在對接項目時用到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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM