#java #xml #http
Вопрос:
У меня проблема с получением XML с этой веб-страницы. В браузере он отображается правильно, и проблем нет, но когда дело доходит до Java, все по-другому.
Я попробовал два метода, оба из которых привели к исключению.
// Method 1 - Using Java's URL
URL url = new URL(/* mentioned link */);
String rawXML = new String(url.openStream().readAllBytes(), StandardCharsets.UTF_8); // java.io.IOException: Invalid Http response
// Method 2 - Using Apache's HTTP client
HttpGet httpGet = new HttpGet(/* mentioned link */);
String rawXML = EntityUtils.toString(HttpClients.createDefault().execute(httpGet).getEntity()); // org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
Загрузка этой веб-страницы с wget
помощью аргумента --content-on-error
работает, но она ненадежна, так как wget не всегда доступен во всех системах, таких как Windows.
Ответ №1:
Ответ не содержит заголовков, поэтому java отклоняет его
wget "https://www.strava.cz/foxisapi/foxisapi.dll/istravne.istravne.process?xmljidelnickyAamp;zarizeni=3148" -O so-69226464.html
--2021-09-17 13:44:29-- https://www.strava.cz/foxisapi/foxisapi.dll/istravne.istravne.process?xmljidelnickyAamp;zarizeni=3148
Resolving www.strava.cz (www.strava.cz)... 82.99.180.77
Connecting to www.strava.cz (www.strava.cz)|82.99.180.77|:443... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Этот класс java, выполняющий необработанный HTTP-запрос GET, может получить содержимое. На основе этой страницы.
Отправленный запрос является
GET /foxisapi/foxisapi.dll/istravne.istravne.process?xmljidelnickyAamp;zarizeni=3148 HTTP/1.1rn
User-Agent: RawHttpGetrn
Host: www.strava.czrn
Accept: */*rn
Java-код:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.SSLSocketFactory;
public class RawHttpGet {
private static String hostname = "www.strava.cz";
public static void main(String[] args) throws IOException {
Socket socket = SSLSocketFactory.getDefault().createSocket(hostname, 443);
// UTF-8 encdoding
//BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
// Encoding for this request
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "Cp1250"));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuffer buff = new StringBuffer("GET /foxisapi/foxisapi.dll/istravne.istravne.process?xmljidelnickyAamp;zarizeni=3148 HTTP/1.1rn");
buff.append("User-Agent: RawHttpGetrn");
buff.append("Accept: */*rn");
buff.append("Host: " hostname "rn");
buff.append("rn");
System.out.println(" * Request");
System.out.println(buff.toString());
// send message
out.write(buff.toString());
out.flush();
// read response
System.out.println(" * Response");
// Default system encoding
//System.out.println(new String(socket.getInputStream().readAllBytes()));
// Encoding for this request
System.out.println(new String(socket.getInputStream().readAllBytes(), "Cp1250"));
out.close();
in.close();
}
}
Комментарии:
1. Работает именно так, как я и ожидал. Спасибо за ваш ответ!
2. @Mayuna исправил код для использования SSL-порта 443. Вы все еще можете использовать порт 80, соответствующим образом комментируя/раскомментируя.
3. не преобразуйте xml в символы/строки/считыватели. это отличный способ уничтожить. сохраняйте его в виде байтов и потоков ввода/вывода
4. используйте InputStream и OutputStream и byte[] для копирования байтов между ними.
5. Спасибо, я обновлю свой код.