Conexão a um URL de dentro de um applet usando HttpClient vs usando URLConnection do JDK do Apache

StackOverflow https://stackoverflow.com/questions/1216165

Pergunta

No código a seguir, tenho verificado que a ligação a um URL de dentro de um applet preserva a sessão do navegador se a classe URLConnection do JDK é usado. No entanto, este não é o caso, se a biblioteca de HttpClient Apache é usado. Alguem sabe por quê? Como alternativa, há uma maneira para mim para definir a instância de conexão para ser usado por uma instância 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();
        }
    }
}
Foi útil?

Solução

Este é um problema comum com bibliotecas aplicação da sua própria conexão URL via Socket. Aparentemente, a implementação JRE da classe URLConnection pode obter as informações do navegador diretamente. Tivemos a empregar a técnica como mencionado por oscargm acima, ou seja, no appserver escrever os biscoitos pedido para ser os parâmetros para o applet e começar a biscoitos de documentos do navegador usando JavaScript (isso é para o caso de SSO, onde o conjunto de cookies pode não ser o mesmo, porque o agente de intermédia - servidores de proxy). Note-se que se os cookies estiverem HttpOnly -. O código javascript falhará

Outras dicas

Você deve enviar o cookie jsessionid ou reescrever seu URL para usar o jsessionid.

Essa é a forma como o servidor sabe sua sessão.

Se você gerar a tag applet em uma página JSP dinamicamente você pode passar o jsessionidvalue para o applet como um parâmetro e, em seguida, usá-lo.

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );

Eu acho que você está usando uma versão antiga do HttpClient. Confira de HttpClient website .

Na API atual, você pode usar HttpState no método de execução, de modo que o código poderia ser assim:

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

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

Na próxima execução, passar o mesmo objeto "estado", e você vai ter as credenciais e biscoitos preservada.

As causas possíveis, é que você não tenha feito uma desconexão () ao usar URLConnection, no entanto, a biblioteca Apache irá fechar a conexão quando você está feito com ele.

Thi é uma questão importante.

Os integra classe java.net.URLConnection padrão perfeitamente com o plugin Java e navegador da web, pode herdar sessão, autenticação HTTP fichas, conectores de proxy, etc.

Os caras do Apache Commons cometeu um erro grave quando decidiram implementar HttpClient da tomada (ou seja, a partir do zero) em vez de apenas desenvolver em cima do java.net.URL padrão * classes. não HttpClient não herdar de java.net.URLConnection por isso não pode herdar suas características avançadas da empresa.

Talvez projetos OpenSource não são tão inteligentes quanto eles pensam.

Eu poderia fazê-lo funcionar sem passar cookies como argumentos a partir da página Web com este código:

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 classe do JDK pode felizmente obter os biscoitos da loja de "sistema". Neste caso, é a loja navegador, accesed através do Java Plug-in.

Uma espécie de "trabalho manual", mas funciona.

NOTA: Eu encontrei o código aqui

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top