Java 将curl请求转换为HttpURLConnection

Java 将curl请求转换为HttpURLConnection,java,authentication,curl,https,Java,Authentication,Curl,Https,我正在尝试实现一个客户机,首先登录,并做一些工作人员。 这是我的要求: 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://a

我正在尝试实现一个客户机,首先登录,并做一些工作人员。 这是我的要求:

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)

我试过几种可能的解决办法,但没有成功。我找不到我做错了什么

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

所以

  • 去掉所有setRequestProperty()内容(不需要)
  • 使用con.setContentType(“application/x-www-form-urlencoded”)[可以说这有点干净]
  • 将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..,这应该是无关紧要的)


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

    所以

  • 去掉所有setRequestProperty()内容(不需要)
  • 使用con.setContentType(“application/x-www-form-urlencoded”)[可以说这有点干净]
  • 将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..,这应该是无关紧要的)


    哦..哎哟-如果Accept:application/json很重要,那么您必须设置headerThanks请求响应的requestproperty(“Accept”,“app/json”),不幸的是,这不起作用。当我提交上面的curl请求时,我收到一个json格式的响应,如{“token”:“23424324”}。这应该很简单,但不起作用。这部分{-d“username=myusername&password=mypassword”}有“&”和“=”符号。是关于那件事吗。我还尝试了“:”而不是“&”和“:”。我用一个完整的示例更新了我的响应-curl命令的-d参数是正确的www-form-urlencoded(同样,curl本身只是将-d参数作为HTTP请求的主体传入)哦..哇哦-如果Accept:application/json很重要,那么您必须设置requestproperty(“Accept”,“app/json”)标题感谢响应,不幸的是,这不起作用。当我提交上述curl请求时,我收到一个json格式的响应,如{“token”:“23424324”}。这应该很简单,但不起作用。这部分{-d“username=myusername&password=mypassword”}有“&”和=“标志。是关于那件事吗。我还尝试了“:”而不是“&”和“:”。我用一个完整的示例更新了我的响应-curl命令的-d参数是正确的www-form-urlencoded(同样,curl本身只是将-d参数作为HTTP请求的主体传入)