我经历过不同的教程和本网站,但找不到合适的解决方案。另一方面,我已经看到应用程序登录到网站并请求更多信息,所以我确信有一种方法可以实现这一点,但也许我的方法都是错误的。
以下是我要做的事情:我想登录需要用户身份验证的网站,然后阅读并解析只有在用户登录后才能访问的网站。 问题:在将凭据发布到网站后,我收到一个cookie,这个cookie在我的HttpClient中似乎没有保留,即使文档建议确实应该这样做。
以下是我的一些代码:
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpost = new HttpPost(LOGIN_URL);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair(USER_FIELD, login));
nvps.add(new BasicNameValuePair(PASS_FIELD, pw));
nvps.add(new BasicNameValuePair(REMEMBERME, "on"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();
if (entity != null) {
entity.consumeContent();
}
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
当我输出“cookies”的内容时,一切似乎都很好(我收到一个会话):
- [version: 0][name: ASP.NET_SessionId][value: xxx][domain: xxx][path: /][expiry: null]
据我了解,只要我不关闭它,cookie /会话就会被保存并在我的HttpClient中使用。
阅读下一页(受限制)时,请使用以下代码:
HttpGet httpget2 = new HttpGet(RESTRICTED_URL);
response = httpclient.execute(httpget2);
entity = response.getEntity();
InputStream data = entity.getContent();
// data will be parsed here
if (entity != null) {
entity.consumeContent();
}
// connection will be closed afterwards
如果我输出GET请求的响应(使用response.getStatusLine()
),我收到“200 OK”消息,但解析返回的站点显示登录丢失(我只检索登录)形式)。
感谢任何帮助。
答案 0 :(得分:2)
在我必须登录的应用程序中。首先,我必须运行GET,然后运行POST,然后再运行GET。 First get将为我的连接实例化Jsession Id。 POST将验证我的ID,然后原始获取GET将返回真实内容。
以下代码适用于在JBoss中运行的应用
public boolean login() {
HttpGet httpGet = new HttpGet( "http://localhost:8080/gwt-console-server/rs/identity/secure/sid/");
HttpPost httpPost = new HttpPost("http://localhost:8080/gwt-console-server/rs/identity/secure/j_security_check");
HttpResponse response = null;
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair(USER_FIELD, userName));
nvps.add(new BasicNameValuePair(PASS_FIELD, password));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpClient.execute(httpGet);
EntityUtils.consume(response.getEntity());
response = httpClient.execute(httpPost);
EntityUtils.consume(response.getEntity());
response = httpClient.execute(httpGet);
String sessionId =EntityUtils.toString(response.getEntity());
String cookieId ="";
List<Cookie> cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();
for (Cookie cookie: cookies){
if (cookie.getName().equals("JSESSIONID")){
cookieId = cookie.getValue();
}
}
if(sessionId!= null && sessionId.equals(cookieId) ){
return true;
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
答案 1 :(得分:1)
假设您的httpclient
对象在两种情况下都是相同的,并且假设RESTRICTED_URL
与LOGIN_URL
位于同一个域中,那么我认为您应该有所作为。{ / p>
您可能希望使用Wireshark或代理或其他东西来检查您正在进行的HTTP请求,以查看cookie是否实际附加到请求。可能是cookie被附加,在这种情况下,还有其他错误导致您的第二个请求失败。
答案 2 :(得分:1)
你必须使用单身模式DefaultHttpClient httpclient
使sessioncookie仍然保持登录会话。
这是Mainactivity
类:
public static DefaultHttpClient httpClient;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RequestPage request = new RequestPage();
request.post("http://www.example.com/login.php");
RequestPage requestProfile =new RequestPage();
requestProfile.post("http://www.example.com/profile.php");
}
这是RequestPage
类:
private InputStream post(String url){
String paramUsername = "username";
String paramPassword = "pass";
if(MainActivity.httpClient==null){
MainActivity.httpClient = new DefaultHttpClient();
}
DefaultHttpClient httpClient = MainActivity.httpClient;
// In a POST request, we don't pass the values in the URL.
//Therefore we use only the web page URL as the parameter of the HttpPost argument
HttpPost httpPost = new HttpPost(url);
// Because we are not passing values over the URL, we should have a mechanism to pass the values that can be
//uniquely separate by the other end.
//To achieve that we use BasicNameValuePair
//Things we need to pass with the POST request
BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("username", paramUsername);
BasicNameValuePair passwordBasicNameValuePAir = new BasicNameValuePair("password", paramPassword);
// We add the content that we want to pass with the POST request to as name-value pairs
//Now we put those sending details to an ArrayList with type safe of NameValuePair
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
nameValuePairList.add(usernameBasicNameValuePair);
nameValuePairList.add(passwordBasicNameValuePAir);
try {
// UrlEncodedFormEntity is an entity composed of a list of url-encoded pairs.
//This is typically useful while sending an HTTP POST request.
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);
// setEntity() hands the entity (here it is urlEncodedFormEntity) to the request.
httpPost.setEntity(urlEncodedFormEntity);
try {
// HttpResponse is an interface just like HttpPost.
//Therefore we can't initialize them
HttpResponse httpResponse = httpClient.execute(httpPost);
// According to the JAVA API, InputStream constructor do nothing.
//So we can't initialize InputStream although it is not an interface
return httpResponse.getEntity().getContent();
} catch (ClientProtocolException cpe) {
System.out.println("First Exception caz of HttpResponese :" + cpe);
cpe.printStackTrace();
} catch (IOException ioe) {
System.out.println("Second Exception caz of HttpResponse :" + ioe);
ioe.printStackTrace();
}
} catch (UnsupportedEncodingException uee) {
System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
uee.printStackTrace();
}
return null;
}
答案 3 :(得分:0)
你可以这样做,虽然它是一种解决方法。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webv = (WebView)findViewById(R.id.MainActivity_webview);
webv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
String postData = FIELD_NAME_LOGIN + "=" + LOGIN +
"&" + FIELD_NAME_PASSWD + "=" + PASSWD;
// this line logs you in and you stay logged in
// I suppose it works this way because in this case WebView handles cookies itself
webv.postUrl(URL, EncodingUtils.getBytes(postData, "utf-8"));
}