zoukankan      html  css  js  c++  java
  • 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方法是直接可以请求httpsdoPost2为的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请求运行结果

    客户端:

    服务端:

  • 相关阅读:
    linux下光标定位和清屏函数
    使用NHibernate的时候出现“指定的转换无效”的错误
    UI 界面:技术决定一切
    BeamTarget红外线的末尾
    Chicken的代码解剖:6 PlayerController
    kismet模块创建
    Projectile重构
    关卡设计师优化关卡
    一些主类的继承关系
    EA iOS平台《质量效应》《死亡空间》的界面
  • 原文地址:https://www.cnblogs.com/ccylovehs/p/7028818.html
Copyright © 2011-2022 走看看