Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Ошибка 302 в ответ, а через браузер работает


Автор: i_SweP 25.6.2011, 18:01
На сайте ajax'ится панель навигации отсюда http://maps.2gis.ru/spb/rubric-list/. Пытаюсь её сграбить
Когда отрываю в браузее, всё ОК. Обмен заголовков такой:

Код

GET http://maps.2gis.ru/spb/rubric-list/ HTTP/1.1
Host: maps.2gis.ru
Proxy-Connection: keep-alive
Referer: http://maps.2gis.ru/spb/
X-Http-Request: DGAjax
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Ubuntu/11.04 Chromium/12.0.742.91 Chrome/12.0.742.91
Accept: */*
Accept-Encoding: sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

---------------И ответ:

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Jun 2011 14:44:19 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=30
X-Powered-By: PHP/5.2.9-1


Но когда отсылаю тоже самое (из NetTool 4.7.2) приходит странный ответ:
Код

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Sat, 25 Jun 2011 14:47:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=30
X-Powered-By: PHP/5.2.9-1
Location: /cityselect/


Причём при попытке обратится к http://maps.2gis.ru/cityselect/ приходит такой же ответ.

Java прога вовсе зависает на считывании ответа из потока. Через минуту выкидвает java.net.SocketException: Connection reset
На всякий случай код:
Код

byte buf[] = new byte[64 * 1024];
Socket s = openSocket( request );
s.getOutputStream().write( request.getBytes() );

InputStream is = s.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int len = 1;
while ( len > 0 )
{
    len = is.read( buf );
    if ( len > 0 )
    {
        baos.write( buf, 0, len );
    }
}
 

Что делать, как скачать эту страницу, и почему только браузер нормально открывает её сразу?

Автор: inmate 27.6.2011, 00:26
Обязательно через сокеты??

Можно так:
Код

public static void main(String[] args) throws IOException {
        URL url = new URL("http://maps.2gis.ru/spb/rubric-list/");
        URLConnection connection = url.openConnection();

        Scanner scanner = new Scanner(connection.getInputStream());
        StringBuilder builder = new StringBuilder();
        while (scanner.hasNext()) {
            builder.append(scanner.next());
        }
        scanner.close();
}

Автор: LSD 27.6.2011, 09:46
302 это не ошибка, это редирект. Судя по адресу куда тебя редиректят: Location: /cityselect/ тебя нужно выбрать город. Когда ты открываешь страницу браузером, он либо по кукам определяет ранее выбранный город, или отправляет на страницу выбора города.

Реализация HTTP протокола руками, нудное и муторное занятие, возьми готовую реализацию, тот же http://hc.apache.org/httpcomponents-client-ga/.

Автор: i_SweP 27.6.2011, 11:33
Цитата(inmate @  27.6.2011,  00:26 Найти цитируемый пост)
Обязательно через сокеты??

Не smile Я уже переписал под url, оно заработало, но всё-равно вопрос остаётся по http части.. Оно может и выбирается по кукам, я пробовал их передавать, пробовал в браузере отключать куки. В первом случае такой же результат, во-втором, в браузере всё-равно нормально работает без кук. 

Цитата(LSD @  27.6.2011,  09:46 Найти цитируемый пост)
 Судя по адресу куда тебя редиректят: Location: /cityselect/ тебя нужно выбрать город.

Он меня даже с этого адреса туда же опять редиректит

Цитата(LSD @  27.6.2011,  09:46 Найти цитируемый пост)
Реализация HTTP протокола руками, нудное и муторное занятие, возьми готовую реализацию, тот же HttpClient. 

Была мысль, что где-то есть готовая реализация, но я не знал, как она называется. И ещё на пороге обнаружилось, что через url вполне нормально работает. Но теперь буду знать, что есть HttpClient, спасибо.

Вопрос остаётся с теоретической точки зрения - почему браузер и HttpURLConnection нормально обрабатывают страницу, а в ручную посланный такой же запрос получает левый редирект

Для тех, кто столкнётся  с этой маленькой бедой, такой код заработал у меня:

Код

BufferedReader reader = null;
StringBuilder stringBuilder;

try
{
    URL url = new URL( urlString );
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod( "GET" );
    connection.setReadTimeout( 15 * 1000 );
    connection.connect();

    reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
    stringBuilder = new StringBuilder();

    String line = null;
    while ( (line = reader.readLine()) != null )
    {
        stringBuilder.append( line + "\n" );
    }
    return stringBuilder.toString();

} catch (IOException e)
{
    System.err.println( "Error opening socket" );
    throw new RuntimeException( e );
} finally
{
    try
    {
        if ( reader != null )    reader.close();
    } catch (IOException ioe)
    {
        ioe.printStackTrace();
    }
}


inmate
Воистину, библиотека io в java огромна. Твой код тоже попробую (он наглядней smile )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)