4

在下面的代码中,我已经验证如果使用 JDK 的 URLConnection 类,从小程序中连接到 URL 会保留浏览器的会话。但是,如果使用 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();
        }
    }
}
4

6 回答 6

3

这是通过 Socket 实现自己的 URL 连接的库的常见问题。显然,URLConnection 类的JRE 实现可以直接获取浏览器信息。我们必须使用上面 oscargm 提到的技术,即在应用服务器上将请求 cookie 写入小程序的参数并使用 JavaScript 获取浏览器的文档 cookie(这是 SSO 的情况,其中 cookie 集可能由于中间代理 - 代理服务器而不同)。请注意,如果 cookie 是 HttpOnly - javascript 代码将失败。

于 2009-10-28T16:58:06.077 回答
2

您必须发送jsessionidcookie 或重写您的 URL 才能使用jsessionid.

这就是服务器知道您的会话的方式。

如果您applet在 JSP 页面中动态生成标记,则可以将该jsessionid值作为参数传递给小程序,然后使用它。

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );
于 2009-08-08T19:09:49.243 回答
1

我认为您使用的是旧版本的 HttpClient。查看HttpClient 的网站

在当前的 API 中,您可以在 execute 方法中使用 HttpState,这样您的代码可以如下所示:

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

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

在下一次执行中,传递相同的“状态”对象,您将获得保留的凭据和 cookie。

于 2009-08-08T15:06:19.193 回答
0

可能的原因是您在使用 URLConnection 时没有执行 disconnect(),但是,当您完成连接时,apache 库将关闭连接。

于 2009-08-04T05:35:51.307 回答
0

这是一个重要的问题。

标准的 java.net.URLConnection 类与 java 插件和 web 浏览器无缝集成,可以继承 session、HTTP 身份验证令牌、代理连接器等。

当 Apache Commons 的人决定从 Socket 实现 HttpClient(即从头开始)而不是仅仅在标准 java.net.URL* 类之上进行开发时,他们犯了一个严重的错误。HttpClient 不继承自 java.net.URLConnection,因此它不能继承其高级企业特性。

也许开源项目并没有他们想象的那么聪明。

于 2010-11-25T20:31:05.647 回答
0

我可以在不使用以下代码从网页传递 cookie 作为参数的情况下使其工作:

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)));

JDK 的类 CookieHandler 可以幸运地从“系统”存储中获取 cookie。在这种情况下,它是通过 Java 插件访问的浏览器商店。

有点“手动工作”,但它有效。

注意:我在这里找到了代码

于 2011-01-25T09:04:34.140 回答