Соединение с URL из апплета с использованием HttpClient Apache против использования URLConnection JDK - PullRequest
4 голосов
/ 01 августа 2009

В следующем коде я проверил, что подключение к URL-адресу из апплета сохраняет сеанс браузера, если используется класс JDK URLConnection. Однако это не тот случай, если используется библиотека Apache HttpClient. Кто-нибудь знает почему? В качестве альтернативы, есть ли способ установить экземпляр соединения для использования экземпляром HttpClient?

import java.applet.Applet;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;

import javax.net.ssl.SSLException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpClientTesterApplet extends Applet {
    private static final long serialVersionUID = -1599714556710568947L;

    public void testHttpClient() throws ClientProtocolException, IOException,
            URISyntaxException {
        URL url = new URL(String.format("%s://localhost:%s/%s/testHttpClient",
                getParameter("protocol"), getParameter("port"),
                getParameter("context")));

        HttpClient client = new DefaultHttpClient();

        HttpPost post = new HttpPost(url.toURI());

        System.out.println("Executing request " + post.getURI());

        try {
            System.out
                    .println(client.execute(post, new BasicResponseHandler()));
        } catch (SSLException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("Executed request " + post.getURI());

        System.out.println("Opening connection " + url);

        HttpURLConnection urlConnection = (HttpURLConnection) url
                .openConnection();

        System.out.println("Opened connection " + url);

        urlConnection.setRequestMethod("POST");

        System.out.println("Connecting");

        urlConnection.connect();

        System.out.println("Connected");

        InputStream inputStream = urlConnection.getInputStream();

        try {
            while (inputStream.read() != -1) {
                System.out.println("Reading");
            }
        } finally {
            inputStream.close();
        }
    }
}

Ответы [ 6 ]

3 голосов
/ 28 октября 2009

Это распространенная проблема библиотек, реализующих собственное URL-соединение через Socket. По-видимому, реализация JRE класса URLConnection может напрямую получать информацию о браузере. Нам пришлось использовать технику, как указано выше в oscargm, то есть на сервере приложений, записывающем файлы cookie запроса в качестве параметров для апплета и получающем файлы cookie браузера с использованием JavaScript (это для случая единого входа, когда набор файлов cookie не будет одинаковым из-за промежуточного агента - прокси-серверов). Обратите внимание, что если файлы cookie HttpOnly - код JavaScript не будет работать.

2 голосов
/ 08 августа 2009

Вы должны отправить файл cookie jsessionid или переписать свой URL, чтобы использовать jsessionid.

Так сервер знает ваш сеанс.

Если вы динамически генерируете тег applet на странице JSP, вы можете передать значение jsessionid апплету в качестве параметра и затем использовать его.

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );
1 голос
/ 08 августа 2009

Я думаю, что вы используете более старую версию HttpClient. Проверьте сайт HttpClient .

В текущем API вы можете использовать HttpState в методе execute, чтобы ваш код мог выглядеть следующим образом:

HttpClient client = new HttpClient();
HttpMethod method = new PostMethod(url.toURI());
HttpState state = new HttpState();

client.executeMethod(HttpConfiguration.ANY_HOST_CONFIGURATION, method, state);

В следующем выполнении передайте тот же объект «state», и вы получите учетные данные и файлы cookie.

0 голосов
/ 25 января 2011

Я мог бы заставить его работать, не передавая куки в качестве аргументов с веб-страницы с этим кодом:

private String retrieveCookies(URL url) throws IOException, URISyntaxException 
{ 
     String cookieValue = null;

     CookieHandler handler = CookieHandler.getDefault();
     if (handler != null)    {
          Map<String, List<String>> headers = handler.get(url.toURI(), new HashMap<String, List<String>>());

          List<String> cookiesList = headers.get("Cookie");
          if (cookiesList != null)
          {
              for (String v : cookiesList) {
                  if (cookieValue == null) 
                      cookieValue = v; 
                  else
                      cookieValue = cookieValue + ";" + v; 
              }
          }
     } 
     return cookieValue; 
}

...

httppost.addHeader("Cookie", retrieveCookies(new URL(uploadUrl)));

CookieHandler класса JDK, к счастью, может получить куки из «системного» магазина. В данном случае это магазин браузера, доступ к которому осуществляется через плагин Java.

Вроде "ручная работа", но она работает.

ПРИМЕЧАНИЕ: я нашел код здесь

0 голосов
/ 25 ноября 2010

Это важная проблема.

Стандартный класс java.net.URLConnection легко интегрируется с плагином java и веб-браузером, может наследовать сеанс, токены HTTP-аутентификации, прокси-соединители и т. Д.

Ребята из Apache Commons совершили грубую ошибку, когда решили внедрить HttpClient из Socket (то есть с нуля) вместо разработки поверх стандартных классов java.net.URL *. HttpClient не наследуется от java.net.URLConnection, поэтому он не может наследовать свои расширенные корпоративные функции.

Может быть, проекты OpenSource не так умны, как они думают.

0 голосов
/ 04 августа 2009

Возможные причины: вы не отключили () при использовании URLConnection, однако библиотека apache закроет соединение, когда вы закончите с ним.

...