我正在尝试运行一个发出HTTP / HTTPS POST请求的插件。在它上面声明了所需的依赖关系,即httpclient
和httpcore
。我分别使用版本4.5.3和4.4.6。尽管导入正确(我的意思是),但我在执行时遇到了这个错误:
Caused by: java.lang.NoClassDefFoundError:
org/apache/http/ssl/TrustStrategy
25.06 19:59:12 [Server] INFO at
com.b5team.postrequest.Main.onCommand(Main.java:77) ~[?:?]
25.06 19:59:12 [Server] INFO at
org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~
[Spigot.jar:git-Spigot-3fb9445-6e3cec8]
25.06 19:59:12 [Server] INFO ... 10 more
25.06 19:59:12 [Server] INFO Caused by:
java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy
这是我的代码:
package com.b5team.postrequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
public class SocketPOSTRequest {
public void sendRequest(String myurl, String hash, String args[]) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, ClientProtocolException, IOException {
HttpClientBuilder b = HttpClientBuilder.create();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
b.setSSLContext(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory)
.build();
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
b.setConnectionManager(connMgr);
HttpClient client = b.build();
HttpPost post = new HttpPost(myurl);
List<NameValuePair> params = new ArrayList<NameValuePair>(args.length);
params.add(new BasicNameValuePair("hash", hash));
for(int i = 0; i < args.length; i++) {
params.add(new BasicNameValuePair("arg"+i, args[i]));
}
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream in = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
System.out.println("[POSTRequest] Data sent successfully!");
while ((line = reader.readLine()) != null) {
System.out.println("[POSTRequest] Report: "+line);
}
}
}
}
编辑:我正在使用Ant进行构建,并且正确添加了依赖项。我也测试了Maven,添加了依赖项,但错误仍然存在。
EDIT2:切换到Maven,添加了maven-shade-plugin和maven-compile-plugin。错误消失了,但现在得到了java.lang.NoSuchMethodError: org.apache.http.impl.client.HttpClientBuilder.setSSLContext
。使用junit运行时,不要发生任何错误。它只发生在服务器上运行时,即Spigot 1.11.2 Minecraft Server。
答案 0 :(得分:6)
如果您正在使用maven项目,请在pom.xml文件中添加以下依赖项。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
答案 1 :(得分:1)
所以,我用apache httpclient和httpcore用javax sslcontext方法替换了sslcontext方法。现在,一切正常。记住,上面的代码在纯java上正常工作。真正的问题是在Minecraft服务器上运行。
无论如何,我会在新代码下面放置文档,也许可以帮助某人。
package com.b5team.postrequest;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsPOSTRequest {
public static void sendRequest(String myurl, String hash, String args[]) throws NoSuchAlgorithmException, KeyManagementException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(context);
URL url = new URL(myurl);
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0;Windows98;DigExt)");
con.setDoOutput(true);
con.setDoInput(true);
ArrayList<String> params = new ArrayList<String>(args.length + 1);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes("hash=" + hash);
for(int i = 0; i < params.size(); i++) {
output.writeBytes("&");
output.writeBytes("arg" + i + "=" + args[i]);
output.flush();
}
output.flush();
output.close();
DataInputStream input = new DataInputStream(con.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
System.out.println("[POSTRequest] Data sent successfully!");
System.out.println("[POSTRequest] Resp Code:"+con.getResponseCode());
System.out.println("[POSTRequest] Resp Message:"+con.getResponseMessage());
while ((line = reader.readLine()) != null) {
System.out.println("[POSTRequest] Report: "+line);
}
input.close();
} catch (UnsupportedEncodingException e) {
System.out.println("[POSTRequest] Encoding error. Maybe string have invalid caracters.");
e.printStackTrace();
} catch (MalformedURLException e) {
System.out.println("[POSTRequest] Invalid URL. Verify your URL and try again.");
e.printStackTrace();
} catch (IOException e) {
System.out.println("[POSTRequest] Error on HTTPS connection.");
e.printStackTrace();
}
}
private static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}