我正在尝试使用java将数据发布到此URL:
https:www.stackoverflow.com
它没有更新数据。
但是当我尝试使用curl时,它正在用这个url更新数据:
E:\curl ssl>curl -k -X POST -u"user:pass" "www.stackoverflow.com"
修改
public void authenticatePostUrl() {
HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName
+ " vs. " + session.getPeerHost());
return true;
}
};
// Now you are telling the JRE to trust any https server.
// If you know the URL that you are connecting to then this should
// not be a problem
try {
trustAllHttpsCertificates();
} catch (Exception e) {
System.out.println("Trustall" + e.getStackTrace());
}
HttpsURLConnection.setDefaultHostnameVerifier(hv);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
URL url = new URL("www.stackoverflow.com");
String credentials = "user" + ":" + "password";
String encoding = Base64Converter.encode(credentials.getBytes("UTF-8"));
HttpsURLConnection uc = (HttpsURLConnection) url.openConnection();
uc.setDoInput(true);
uc.setDoOutput(true);
uc.setRequestProperty("Authorization", String.format("Basic %s", encoding));
uc.setRequestMethod("POST");
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
uc.setRequestProperty("Accept", "application/x-www-form-urlencoded; charset=utf-8");
uc.getInputStream();
System.out.println(uc.getContentType());
InputStream content = (InputStream) uc.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(
content));
String line;
while ((line = in.readLine()) != null) {
pw.println(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
pw.println("Invalid URL");
} catch (IOException e) {
e.printStackTrace();
pw.println("Error reading URL");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(sw.toString());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CurlAuthentication au = new CurlAuthentication();
au.authenticatePostUrl();
au.authenticateUrl();
}
// Just add these two functions in your program
public static class TempTrustedManager implements
javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
private static void trustAllHttpsCertificates() throws Exception {
// Create a trust manager that does not validate certificate chains:
javax.net.ssl.TrustManager[] trustAllCerts =
new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new TempTrustedManager();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc =
javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
}
为什么它不能用Java?
(出于安全考虑,我更改了上面的网址。)
答案 0 :(得分:3)
所以你试图将do_not_disturb=no
发送到服务器?这就是为什么我在评论中问你previous question ......
通过将?do_not_disturb=No
附加到URL,这些参数会自动作为GET请求发送到服务器,要将它们作为POST发送,您必须将它们放在请求正文中,如下所示:
String postData = "do_not_disturb=No";
OutputStreamWriter outputWriter = new OutputStreamWriter(uc.getOutputStream());
outputWriter.write(postData);
outputWriter.flush();
outputWriter.close();
然后你的Accept
- 标题可能是错误的,因为它告诉服务器你期望获得某些响应数据的格式(content
)。如果您希望从服务器获取一些XML,请阅读uc.setRequestProperty("Accept", "application/xml");
。
<强>更新强>
通过将verbose-flag(-v
)添加到curl
命令,我得到了它发送的标题:
POST /api/domains/amj.nms.mixnetworks.net/subscribers/9001/ HTTP/1.1
Authorization: Basic {URL_ENCODED_AUTHENTICATION_STRING}
User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Host: 8.7.177.4
Accept: */*
Content-Length: 17
Content-Type: application/x-www-form-urlencoded
所以请尝试更改您的代码:
uc.setRequestProperty("Authorization", String.format("Basic %s", encoding));
uc.setRequestMethod("POST");
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
uc.setRequestProperty("Accept", "*/*");
uc.setRequestProperty("Content-Length", Integer.toString(postData.getBytes().length));
用户代理字符串应该没有意义,除非你的服务器做了很奇怪的事情。
如果它仍然不起作用,请查看变量encoding
是否与详细卷曲运行中Basic
之后的部分具有相同的值。
答案 1 :(得分:1)
在我的情况下,curl适用于POST调用,java中的HttpUrlConnection将不起作用,返回403禁止说我正在使用匿名登录,但该POST调用应该完成的实际工作已经完成。起初非常令人困惑。然后发现我需要禁用url重定向(这是xtend代码,但您知道了):
val conn = url.openConnection() as HttpURLConnection
conn.setInstanceFollowRedirects(false)
答案 2 :(得分:0)
这里有一些选择。一个是你可以使用Runtime()。exec。
添加一个Java类来运行bash脚本但是,我调试了我的Java连接,发现我没有使用TLSv1.2
System.setProperty("deployment.security.TLSv1.2", "true");
System.setProperty("https.protocols", "TLSv1.2");
System.setProperty("javax.net.debug", "ssl"); // "" or "ssl"
从Java 7迁移到Java 8后,Java命令工作。
curl经常工作但是Java没有工作,Java工作和卷曲不工作。我通常检查SSL配置(使用-v和-k表示curl),尝试更改http与https或在此处查看SSL证书安装程序:https://confluence.atlassian.com/download/attachments/180292346/InstallCert.java(我修改了此项以在运行时安装证书)