Java 使用Apache的HttpClient和使用JDK的URLConnection从小程序中连接到URL

Java 使用Apache的HttpClient和使用JDK的URLConnection从小程序中连接到URL,java,session,applet,httpclient,urlconnection,Java,Session,Applet,Httpclient,Urlconnection,在下面的代码中,我验证了如果使用JDK的URLConnection类,则从小程序中连接到URL会保留浏览器的会话。但是,如果使用Apache的HttpClient库,则情况并非如此。有人知道为什么吗?或者,是否有一种方法可以设置HttpClient实例要使用的连接实例 import java.applet.Applet; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnectio

在下面的代码中,我验证了如果使用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();
        }
    }
}

可能的原因是,您在使用URLConnection时没有断开连接,但是,使用完后,apache库将关闭连接。

我认为您使用的是较旧版本的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。

您必须发送JSSessionID cookie或重写URL以使用JSSessionID

这就是服务器了解会话的方式

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

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

这是库通过套接字实现自己的URL连接的常见问题。显然,URLConnection类的JRE实现可以直接访问浏览器信息。我们必须采用上面oscargm提到的技术,即在appserver上,将请求cookie作为参数写入小程序,并使用JavaScript访问浏览器的文档cookie。这是针对SSO的情况,因为中间代理-代理服务器,cookie集可能不相同。请注意,如果Cookie是HttpOnly,javascript代码将失败。

这是一个重要问题

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

ApacheCommons的家伙们犯了一个严重的错误,他们决定从头开始从Socket ie实现HttpClient,而不是仅仅在标准的java.net.URL*类之上开发。HttpClient不从java.net.URLConnection继承,因此无法继承其高级企业功能


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

我可以让它工作,而不必通过以下代码从网页上传递cookies作为参数:

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插件访问的浏览器存储

有点像手工工作,但它可以工作


注意:我发现代码不明白。URLConnection正在按预期运行。您似乎觉得我在使用它时遇到了问题,我的意思是Apache HTTPClient断开了连接,因此您丢失了会话信息。之后建立的连接将完全是一个新的连接,带有新的会话信息。测试代码清楚地表明我只使用了一次HttpClient。我可能应该提供服务器端测试代码以及显示我如何得出单一使用HttpClient失败的结论的输出。是的,这将是有用的信息。从您发布的内容来看,还不清楚失败是什么意思。如果您必须继续使用您的HttpClient版本,请告诉我它是什么-也许您的版本中有一个等效版本。我已经尝试过了,我的小程序不会隐式共享浏览器的会话。这在2012年有效吗?我已经求助于将会话ID作为一个参数来传递,并显式地设置一个具有该值的cookie。不要对一个有用的答案做出真正的贡献。