Tableau使用SSL证书后的API开发

最近项目上使用了Tableau服务器的SSL证书,一系列的API开发代码都要使用https访问,带来了一些代码改写的事,记录一下。

Javascript API里面使用https方式获取Token

这里发送POST请求我写了一个类,里面增加https请求的部分(sendSSLPost),图省事,直接就整个类全复制到这了。

package com.magicdata.portal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

public class HttpRequest {
    
    /**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *  发送请求的 URL
     * @param param
     *  请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendSSLPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try 
        {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化   
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象   
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            
            // 打开和URL之间的连接
            URL realUrl = new URL(url);
            HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection();
            conn.setSSLSocketFactory(ssf);
            
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");    
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
            new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) 
            {
                result += line;
            }
        } 
        catch (Exception e) 
        {
            //System.out.println("发送 POST 请求出现异常!"+e);
            result=e.getMessage();
            e.printStackTrace();
        }
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
                result=ex.getMessage();
            }
        }
        return result;
    }
    /**
     * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
     public static String sendGet(String url, String param) {
            String result = "";
            BufferedReader in = null;
            try {                
                String urlNameString = url + "?" + param;
                if(param==null || param.equals(""))
                {
                    urlNameString = url;
                }
                
                URL realUrl = new URL(urlNameString);
                // 打开和URL之间的连接
                URLConnection connection = realUrl.openConnection();
                // 设置通用的请求属性
                connection.setRequestProperty("accept", "*/*");
                connection.setRequestProperty("connection", "Keep-Alive");
                connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 建立实际的连接
                connection.connect();
                // 获取所有响应头字段
                Map> map = connection.getHeaderFields();
                // 遍历所有的响应头字段
                for (String key : map.keySet()) {
                    System.out.println(key + "--->" + map.get(key));
                }
                // 定义 BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送GET请求出现异常!" + e);
                e.printStackTrace();
            }
            // 使用finally块来关闭输入流
            finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            return result;
        }

        /**
         * 向指定 URL 发送POST方法的请求
         * 
         * @param url
         *            发送请求的 URL
         * @param param
         *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
         * @return 所代表远程资源的响应结果
         */
        public static String sendPost(String url, String param) {
            PrintWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                URLConnection conn = realUrl.openConnection();
                // 设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 发送POST请求必须设置如下两行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                out = new PrintWriter(conn.getOutputStream());
                // 发送请求参数
                out.print(param);
                // flush输出流的缓冲
                out.flush();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送 POST 请求出现异常!"+e);
                e.printStackTrace();
            }
            //使用finally块来关闭输出流、输入流
            finally{
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }
        
        /**
         * 向指定 URL 发送POST方法的请求,参数为Json字符串
         * 
         * @param url
         *            发送请求的 URL
         * @param param
         *            请求参数
         * @return 所代表远程资源的响应结果
         */
        public static String postJSON(String url, String param) {
            OutputStreamWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                HttpURLConnection conn =(HttpURLConnection)realUrl.openConnection();
                conn.setRequestMethod("POST");
                // 设置通用的请求属性
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 发送POST请求必须设置如下两行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                conn.connect();
                out = new OutputStreamWriter(conn.getOutputStream());
                // 发送请求参数
                out.write(param);
                // flush输出流的缓冲
                out.flush();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
                //关闭连接
                conn.disconnect();
                
            } catch (Exception e) {
                System.out.println("发送 POST 请求出现异常!"+e);
                e.printStackTrace();
            }
            //使用finally块来关闭输出流、输入流
            finally{
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }
        
        /**
         * 向指定 URL 发送GET方法的请求,参数为Json字符串
         * 
         * @param url
         *            发送请求的 URL
         * @param param
         *            请求参数
         * @return 所代表远程资源的响应结果
         */
        public static String getJSON(String url, String param) {
            OutputStreamWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                HttpURLConnection conn =(HttpURLConnection)realUrl.openConnection();
                conn.setRequestMethod("GET");
                // 设置通用的请求属性
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");      
                
                // 获取URLConnection对象对应的输出流
                conn.setUseCaches(false);  
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.connect();
                out = new OutputStreamWriter(conn.getOutputStream());
                // 发送请求参数
                out.write(param);
                // flush输出流的缓冲
                out.flush();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
                //关闭连接
                conn.disconnect();                
                
            } catch (Exception e) {
                System.out.println("发送 POST 请求出现异常!"+e);
                e.printStackTrace();
            }
            //使用finally块来关闭输出流、输入流
            finally{
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }
}
引用的话,很简单,例如下面这样:

String url="https://x.xxx.com:8443/trusted";

String token=HttpRequest.sendPost(url,"username="+tUserName);

REST API为所有请求附加证书

直接在RestApiUtils(这个类从官方示例里面直接改写的)加入私有方法获取附加了证书信息的ClientConfig,然后传递给Client对象就好了

引用类:

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

然后写方法:

private ClientConfig getConfig()
    {        
        ClientConfig config = new DefaultClientConfig();
        try 
        {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化   
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, tm, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());            
            config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(new HostnameVerifier()
            {
                @Override
                public boolean verify(String s, SSLSession sslSession) {return true;}
            },sslContext));
        }
        catch (Exception ex) 
        {                
            m_logger.error("There was a problem marshalling the payload");
        }
        
        return config;
    }

将所有的需要附加证书的Client都加上证书,也就是替换

Client client = Client.create();

为下面这样:

Client client = Client.create(getConfig());

加入红色标粗的代码。

注意:

1、要把所有UriBuilder的服务器地址换为https的地址;

2、通常证书里面授信的都是域名,所以使用IP访问会报错。

你可能感兴趣的:(数据可视化,商业智能,编程开发)