【问题标题】:convert curl request into HttpURLConnection将 curl 请求转换为 HttpURLConnection
【发布时间】:2017-02-13 05:32:39
【问题描述】:

我正在尝试实现一个先登录并做一些工作人员的客户端。 这是我的 curl 请求:

curl -v https://api.example.com/api-token-auth/ \
   -H "Accept: application/json" \
   -d "username=myusername&password=mypassword"

我想把它转换成java代码。这是我尝试过的:

HttpURLConnection conn;
URL obj = new URL("https://api.example.com/api-token-auth/");
URL obj = new URL(quoteURL);
conn = (HttpURLConnection) obj.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String userpass = "username=myusername" + "&" + "password=mypassword";
String basicAuth =  new String(Base64.getEncoder().encode(userpass.getBytes()));
conn.setRequestProperty("Authorization", basicAuth);
conn.setRequestProperty( "Accept", "*/*" );
conn.setRequestProperty( "Accept-Encoding", "gzip, deflate" );
conn.setRequestProperty( "Accept-Language", "en;q=1, fr;q=0.9, de;q=0.8,ja;q=0.7, nl;q=0.6, it;q=0.5" );
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded; charset=utf-8" );
conn.setRequestProperty( "API-Version", "1.3.0" );
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty( "Accept", "*/*" );
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
conn.connect();
InputStreamReader inputStreamReader = new InputStreamReader(conn.getInputStream());
BufferedReader in = new BufferedReader(inputStreamReader);
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
conn.disconnect();
return response;

然后我收到此错误:

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: https://api.example.com/api-token-auth/
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1839)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)

我尝试了几种可能的解决方案,但都没有成功。我可以找到我做错了什么。

【问题讨论】:

    标签: java authentication curl https


    【解决方案1】:

    您的 curl 请求实际上并没有执行 HTTP basicAuth(这是您的示例代码尝试执行的操作) - 它只是将 -d 参数发布到服务器(作为 url 编码主体)

    所以

    1. 摆脱所有 setRequestProperty() 东西(不需要)
    2. 使用 con.setContentType("application/x-www-form-urlencoded") [可以说更简洁一些]
    3. 将 userpass 字符串写入 con.getOutputStream() [无需 base64 编码...再次,这与 http basicAuth 无关]

    例如,您的 curl 命令发出以下 HTTP 请求

    POST /api-token-auth/ HTTP/1.1
    Host: api.example.com
    User-Agent: curl/7.49.1
    Accept: application/json
    Content-Length: 39
    Content-Type: application/x-www-form-urlencoded
    
    username=myusername&password=mypassword
    

    以下 Java 程序将执行几乎完全相同的请求

    public class SO {
    public static void main(String[] args) throws Exception {
        String rsp = curl("http://axrsgpar0019:13080/api-token-auth/", "application/json", "username=myusername&password=mypassword");
    }
    public static String curl(String url, String accepts, String minusD) throws Exception {
        HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection();
        con.setDoOutput(true);
        con.setRequestProperty("Accept", accepts);
        con.setRequestProperty("Content-Type",  "application/x-www-form-urlencoded");
        con.getOutputStream().write(minusD.getBytes());
        con.getOutputStream().close();
    
        ByteArrayOutputStream rspBuff = new ByteArrayOutputStream();
        InputStream rspStream = con.getInputStream();
    
        int c;
        while ((c = rspStream.read()) > 0) {
            rspBuff.write(c);
        }
        rspStream.close();
    
        return new String(rspBuff.toByteArray());
    }
    }
    

    生成以下 HTTP 请求(唯一的区别是 User-Agent 和 keep-alive.. 这应该无关紧要)

    POST /api-token-auth/ HTTP/1.1
    Accept: application/json
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Java/1.8.0_91
    Host: api.example.com
    Connection: keep-alive
    Content-Length: 39
    
    username=myusername&password=mypassword
    

    【讨论】:

    • oh..whoops - 如果 Accept: application/json 很重要,您将不得不 setRequestProperty("Accept", "app/json") 该标头
    • 感谢您的回复,不幸的是,这不起作用。当我提交上述 curl 请求时,我会收到一个 json 格式的响应,例如 {"token":"234234234234234234234234234234234234234324"}。这应该很简单,但它不起作用。这部分 {-d "username=myusername&password=mypassword"} 有“&”和“=”符号。是不是和那个有关。我还尝试了“:”而不是“&”和“:”。
    • 我用一个完整的例子更新了我的响应 - 你的 curl 命令的 -d 参数是正确的 www-form-urlencoded (同样,curl 本身只是将 -d 参数作为 HTTP 请求的身体)
    猜你喜欢
    • 1970-01-01
    • 2017-08-03
    • 2018-04-16
    • 2021-02-06
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    相关资源
    最近更新 更多