我在我的应用程序 android 中使用 SOAP 请求时遇到问题。 我使用 Ksoap2 库。这是我的代码:
public class WebServiceCall {
private static final String TAG = WebServiceCall.class.getSimpleName();
public static String callWSThreadSoapPrimitive(String strURL, String strSoapAction, SoapObject request) {
try {
StringBuffer result;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(strURL);
ht.debug = true;
ht.call(strSoapAction, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
result = new StringBuffer(response.toString());
Log.i(TAG, "result: " + result.toString());
return result.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
public class GetArticleTask extends AsyncTask<String, Void, String> {
private MainActivity activity;
private String soapAction;
private String methodName;
private String paramsName;
private final static String TAG = GetArticleTask.class.getSimpleName();
public GetArticleTask(MainActivity activity, String soapAction, String methodName,
String paramsName) {
this.activity = activity;
this.methodName = methodName;
this.soapAction = soapAction;
this.paramsName = paramsName;
}
@Override
protected String doInBackground(String... params) {
//create a new soap request object
SoapObject request = new SoapObject(ConstantString.NAME_SPACE, methodName);
//add properties for soap object
request.addProperty(paramsName, params[0]);
//request to server and get Soap Primitive response
return WebServiceCall.callWSThreadSoapPrimitive(ConstantString.URL, soapAction, request);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result == null) {
Log.i(TAG, "cannot get result");
} else {
//invoke call back method of Activity
activity.callBackDataFromAsyncTask(result);
}
}
}
public class ConstantString {
public final static String SOAP_ACTION = "https://xxx.xxx.xxx.xxx:1443/orawsv/USER/WSS_MWEB_CLI/";
public final static String NAME_SPACE = "https://xxx.xxx.xxx.xxx:1443/orawsv/USER/WSS_MWEB_CLI/";
public final static String URL ="https://xxx.xxx.xxx.xxx:1443/orawsv/USER/WSS_USER_CLI/GETARTICLE";
public final static String GET_ARTICLE_METHOD_NAME = "GETARTICLE";
public final static String GET_ARTICLE_SOAP_ACTION = SOAP_ACTION + GET_ARTICLE_METHOD_NAME;
}
public class MainActivity extends Activity {
private TextView textConverted;
private View btnGetArticle;
private EditText input;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnGetArticle = (View) findViewById(R.id.btn);
textConverted = (TextView) findViewById(R.id.txt_converted);
input = (EditText) findViewById(R.id.txt_temp);
// set event listeners
btnGetArticle.setOnClickListener(onFtoCClick());
}
//change Fahrenheit to Celsius degree
private OnClickListener onFtoCClick() {
return new OnClickListener() {
@Override
public void onClick(View v) {
invokeAsyncTask("Article", ConstantString.GET_ARTICLE_SOAP_ACTION,
ConstantString.GET_ARTICLE_METHOD_NAME);
}
};
}
//create and execute asynctask to get response from W3school server
private void invokeAsyncTask(String convertParams, String soapAction, String methodName) {
new GetArticleTask(this, soapAction, methodName, convertParams).execute(input.getText()
.toString().trim());
}
//call back data from background thread and set to views
public void callBackDataFromAsyncTask(String result) {
textConverted.setText(result);
}
}
当我单击按钮进行测试时,出现以下错误消息:
07-10 08:52:17.852 702-754/com.ablinfo.mweb W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 07-10 08:52:17.857 702-754/com.ablinfo.mweb W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328) at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103) at com.android.okhttp.Connection.connect(Connection.java:143) at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185) at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:342) at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:331) 07-10 08:52:17.858 702-754/com.ablinfo.mweb W/System.err: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:249) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:245) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:25) at org.ksoap2.transport.ServiceConnectionSE.openOutputStream(ServiceConnectionSE.java:130) at org.ksoap2.transport.HttpTransportSE.sendData(HttpTransportSE.java:292) at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:184) at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:118) at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:113) at com.ablinfo.mweb.service.WebServiceCall.callWSThreadSoapPrimitive(WebServiceCall.java:29) at com.ablinfo.mweb.service.GetArticleTask.doInBackground(GetArticleTask.java:36) at com.ablinfo.mweb.service.GetArticleTask.doInBackground(GetArticleTask.java:11) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
你能帮我吗?
谢谢。
最佳答案
我通过修改我的 WebServiceCall 解决了这个问题:
public class WebServiceCall {
private static final String TAG = WebServiceCall.class.getSimpleName();
private static TrustManager[] trustManagers;
public static String callWSThreadSoapPrimitive(String strURL, String strSoapAction, SoapObject request) {
try {
StringBuffer result;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
// certificat SSL
allowAllSSL();
HttpTransportSE ht = new HttpTransportSE(strURL);
List<HeaderProperty> llstHeadersProperty = new ArrayList<>();
llstHeadersProperty.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("user:password".getBytes())));
ht.debug = true;
ht.call(strSoapAction, envelope,llstHeadersProperty);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
result = new StringBuffer(response.toString());
Log.i(TAG, "result: " + result.toString());
return result.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static class _FakeX509TrustManager implements
javax.net.ssl.X509TrustManager {
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return (true);
}
public boolean isServerTrusted(X509Certificate[] chain) {
return (true);
}
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
}
}
public static void allowAllSSL() {
javax.net.ssl.HttpsURLConnection
.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
javax.net.ssl.SSLContext context = null;
if (trustManagers == null) {
trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };
}
try {
context = javax.net.ssl.SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
Log.e("allowAllSSL", e.toString());
} catch (KeyManagementException e) {
Log.e("allowAllSSL", e.toString());
}
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
关于java - Android 使用带有 HTTPS 的 Ksoap2 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51259280/