使用路标发送由OAuth验证的POST请求时出错

时间:2016-06-21 16:34:50

标签: java http post oauth httpurlconnection

我正在尝试发送POSTHTTP POST请求,以便使用其API(创建新的“订阅者”)将联系人信息发送到邮件交换服务器。我正在使用Java和java.util.HttpURLConnection

当我尝试签名连接时,我得到一个空引用异常。如果我在添加setRequestProperty标头之前尝试对连接进行签名,我将从服务器获得无效签名响应。

使用具有相同通用程序的GET请求 - 这意味着,据我所知,我的签名方法(和键值等)是正常的。

我正在尝试使用的服务有一些可用的“SDK”,用.NET编写。我没有尝试使用它,但我相信它可以工作(他们宣布如此)。

我试图复制他们的程序。您可以在下面找到我的代码,按照他们的代码:

private static HttpURLConnection createAndSendOAuthPostRequestWithParams () throws MalformedURLException, IOException, Exception {

    String url = "http://apisdomain/v1.0/lists/354467/subscribers";

    // Here I set up the values given by the provider (API's admin) which I removed from the example
    String clientKey = "";
    String clientSecret = "";
    String userKey = "";
    String userSecret = "";

    String postData = "NAME=TestSubscriber&EMAIL=test@gmail.com
    byte[] postBody = postData.getBytes("UTF-8");  

    URL apiUrl = new URL(url);
    HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();       

    connection.setRequestMethod("POST");
    connection.setRequestProperty("content-length", String.valueOf(postBody.length));
    connection.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=UTF-8");

    //OAuth
    OAuthConsumer consumer = new DefaultOAuthConsumer (clientKey, clientSecret);
    //consumer.setAdditionalParameters(parameters);
    consumer.setTokenWithSecret(userKey, userSecret);
    HttpRequest httpReq = consumer.sign(connection);    //Where the exception occurs

    if (!postBody.toString().isEmpty()) {
        connection.setDoOutput(true);

        try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
            outputStream.write(postBody);
            outputStream.flush();
        }
    }

    return connection;
}

从他们的SDK:

using System.Text;

namespace ResponderSDK
{

    using OAuth;
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.IO;

    class ResponderOAuth
    {

        /* Contains the last HTTP status code returned. */
        public HttpStatusCode http_code;
        /* Contains the last API call. */
        public string url;
        /* Set up the API root URL. */
        public string host = "http://api.responder.co.il/v1.0/";
        /* Set timeout default. */
        public int timeout = 3000;
        /* Set connect timeout. */
        public int connect_timeout = 30;
        /* Verify SSL Cert. */
        public bool ssl_verifypeer = false;
        /* Response format. */
        public string format = "json";
        /* Contains the last HTTP headers returned. */
        public string http_info;
        /* Set the useragent. */
        public string useragent = "ResponderOAuth v0.1-beta";

        /*debug info*/
        public string headers_string;
        public string base_string;
        public string post_string;

        /* Signature */
        private OAuthSignatureMethod_HMAC_SHA1 signature;
        /* OAuthConsumer */
        private OAuthConsumer consumer;
        /* Token */
        private OAuthToken token;


        public ResponderOAuth(string consumer_key, string consumer_secret, string oauth_token = null, string oauth_token_secret = null)
        {
            this.signature = new OAuthSignatureMethod_HMAC_SHA1();
            this.consumer = new OAuthConsumer(consumer_key, consumer_secret);
            if (!String.IsNullOrEmpty(oauth_token) && !String.IsNullOrEmpty(oauth_token_secret))
            {
                this.token = new OAuthToken(oauth_token, oauth_token_secret);
            }
            else
            {
                this.token = null;
            }
        }

        public string http_request(string url, string method = "GET", ParametersArray parameters = null)
        {
            method = method.ToUpper();
            if (url.LastIndexOf("https://") != 0 && url.LastIndexOf("http://") != 0)
            {
                url = String.Format("{0}{1}", this.host, url);
            }

            if (method.Equals("GET"))
                parameters = null;

            OAuthRequest request = OAuthRequest.from_consumer_and_token(this.consumer, this.token, method, url, parameters);
            request.sign_request(this.signature, this.consumer, this.token);
            this.base_string = request.base_string;

            if (method.Equals("GET"))
                return this.http(request.to_url(), "GET", request.to_header(), null);
            else
                return this.http(request.get_normalized_http_url(), method, request.to_header(), request.to_postdata());
        }

        private string http(string url, string method, WebHeaderCollection headers, string data = null)
        {
            List<string> new_http_info = new List<string>();
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
            HttpWebRequest request = null;
            if (!method.Equals("DELETE"))
                request = (HttpWebRequest)WebRequest.Create(url);
            else
            {
                if (!String.IsNullOrEmpty(data))
                {
                    url = String.Format("{0}?{1}", url, data);
                }
                request = (HttpWebRequest)WebRequest.Create(url);
            }

            /* WebRequest settings */
            ((HttpWebRequest)request).ProtocolVersion = System.Net.HttpVersion.Version10;
            ((HttpWebRequest)request).UserAgent = this.useragent;
            ((HttpWebRequest)request).ContinueTimeout = this.connect_timeout;
            ((HttpWebRequest)request).Timeout = this.timeout;
            ((HttpWebRequest)request).Headers = headers;
            ((HttpWebRequest)request).UseDefaultCredentials = true;
            ((HttpWebRequest)request).PreAuthenticate = true;
            ((HttpWebRequest)request).Credentials = CredentialCache.DefaultCredentials;

            this.headers_string = headers.ToString();
            this.post_string = data;

            byte[] dataByteArray = null;

            if ((!String.IsNullOrEmpty(data) && method.Equals("POST")) || method.Equals("PUT"))
            {
                ((HttpWebRequest)request).ContentType = "application/x-www-form-urlencoded";
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                dataByteArray = encoding.GetBytes(data);
                ((HttpWebRequest)request).ContentLength = dataByteArray.Length;
                ((HttpWebRequest)request).Expect = "";
            }

            switch (method)
            {
                case "POST":
                    ((HttpWebRequest)request).Method = "POST";
                    if (!String.IsNullOrEmpty(data))
                    {
                        Stream dataPost = request.GetRequestStream();
                        dataPost.Write(dataByteArray, 0, dataByteArray.Length);
                        dataPost.Close();
                    }
                    break;
                case "PUT":
                    ((HttpWebRequest)request).Method = "PUT";
                    if (!String.IsNullOrEmpty(data))
                    {
                        Stream dataPost = request.GetRequestStream();
                        dataPost.Write(dataByteArray, 0, dataByteArray.Length);
                        dataPost.Close();
                    }
                    break;
                case "DELETE":
                    ((HttpWebRequest)request).Method = "DELETE";
                    break;
            }

            WebResponse response = request.GetResponse();

            this.http_code = ((HttpWebResponse)response).StatusCode;

            // Get the stream containing content returned by the server.
            Stream dataStream = response.GetResponseStream();

            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);

            // Read the content.
            return reader.ReadToEnd();

        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果输入的String格式为json,则可以将content-type更改为“application / json”,并在添加setRequestProperty标题后尝试登录。