Сообщение SOAP для webservice - код ответа HTTP: 403 для URL
Я пытаюсь отправить сообщение SOAP
в файл XML
в веб-службу, а затем захватить двоичный вывод и декодировать его. Конечная точка использует протокол HTTPS
, поэтому я использовал TrustManager
в своем коде, чтобы избежать проблем с PKIX
. Здесь вы можете увидеть мой код:
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
public class Main{
public static void sendSoapRequest() throws Exception {
String SOAPUrl = "URL HERE";
String xmlFile2Send = ".\\src\\request.xml";
String responseFileName = ".\\src\\response.xml";
String inputLine;
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
// Create the connection with http
URL url = new URL(SOAPUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
FileInputStream fin = new FileInputStream(xmlFile2Send);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
copy(fin, bout);
fin.close();
byte[] b = bout.toByteArray();
StringBuffer buf=new StringBuffer();
String s=new String(b);
b=s.getBytes();
// Set the appropriate HTTP parameters.
httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction", "");
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
OutputStream out = httpConn.getOutputStream();
out.write(b);
out.close();
// Read the response.
httpConn.connect();
System.out.println("http connection status :"+ httpConn.getResponseMessage());
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
FileOutputStream fos=new FileOutputStream(responseFileName);
copy(httpConn.getInputStream(),fos);
in.close();
}
public static void copy(InputStream in, OutputStream out) throws IOException {
synchronized (in) {
synchronized (out) {
byte[] buffer = new byte[256];
while (true) {
int bytesRead = in.read(buffer);
if (bytesRead == -1)
break;
out.write(buffer, 0, bytesRead);
}
}
}
}
public static void main(String args[]) throws Exception {
sendSoapRequest();
}
}
Я получаю следующий код ошибки, когда выполняю это.
Исключение в потоке "main" java.io.IOException: сервер возвратил HTTP код ответа: 403 для URL
Ответы
Ответ 1
Ваша реализация в порядке, проблема связана с вашим заголовком Content-Type
. Фактически.
Значение text/xml; charset=utf-8
является значением по умолчанию Content-Type
SOAP 1.1, которое, вероятно, не является вашей версией. SOAP 1.2 ожидает заголовок типа application/soap+xml; charset=utf-8
, поэтому изменение вашей строки кода ниже приведено ниже:
httpConn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
В SoapUI можно проверить заголовки, вызывающие запрос, и перейти на вкладку "Заголовки" в нижней части окна:
![введите описание изображения здесь]()
Затем вы можете сравнить различия между конфигурациями приложений и SoapUI.
Ответ 2
Ошибка 403 может быть связана с заголовками запросов на мыло, отправляемыми на сервер.
Все действительные хосты позволят вашему Java-приложению доверять SSL-сертификату для URL-адреса.
Проверьте, ожидает ли ваш сервер заголовка мыла с именем пользователя/паролем. Если у вас есть доступ к этому серверу, вы можете просмотреть журналы веб-сервера, где ваш запрос терпит неудачу. Код ошибки указывает на отсутствие заголовка мыла, в частности заголовков мыла, с именем пользователя и паролем.
Ответ 3
Интересно, содержит ли ваш запрос SOAP какие-либо данные проверки подлинности в таких заголовках, как SAML. Один из вариантов - в приведенном выше коде, где вы читаете файл и отправляете данные на сервер, вместо того, чтобы отправлять его на сервер, вы выгружаете его в другой файл. Дамп, что byteoutputstream. Затем скопируйте текст из этого файла и поместите его в пользовательский интерфейс SOAP и попробуйте запустить его. Это работает?
Ответ 4
В аналогичной ситуации мы были раньше, и пока попытка TrustManager
не работает должным образом, нам удалось преодолеть эту проблему, установив сертификат с сервера на хранилище JVM (JVM, используемое для запуска выражение). Более подробную информацию о том, как это сделать, можно найти в нескольких сообщениях, например
Как импортировать сертификат .cer в хранилище java?
Я знаю, что это попытка заставить JVM принимать SSL-сертификаты, и эта функциональность будет лучше жить в контексте приложения, но пока мы создаем веб-приложение, которое запускается на определенных серверах приложений, реализовано решение было принятым.