方案
用户必须使用此应用登录服务器。稍后在应用程序中,我们需要检查他们对服务器的登录状态。我们过去通过跟踪上次使用的HttpClient
来做到这一点。最近我们切换到HttpUrlConnection
,但所谓的持久连接无效。
问题
我写了这个测试应用程序,看看连接是否持久。我从这两个URL中获取了xml,但连接的行为并不像它一致。我怎样才能让它发挥作用?
注意:如果您在浏览器中转到登录网址,然后在同一浏览器中转到GetUserInfo
网址,则一切正常。
MainActivity.java
package com.mediajackagency.test;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
public Button signInBtn = null;
public Button getUserInfoBtn = null;
public TextView xmlTextView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
this.xmlTextView = (TextView)findViewById(R.id.xmlTxtView);
this.signInBtn = (Button)findViewById(R.id.signInBtn);
this.signInBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
String xml = loadUrl("https://www.fake.site/Login?userName=test&password=pass123");
return xml;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
xmlTextView.setText(o.toString());
}
};
task.execute();
}
});
this.getUserInfoBtn = (Button)findViewById(R.id.getUserInfoBtn);
this.getUserInfoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
String xml = loadUrl("https://www.fake.site/GetCurrentUser");
return xml;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
xmlTextView.setText(o.toString());
}
};
task.execute();
}
});
}
public String loadUrl(String url) {
URI uri = MainActivity.encodeUrl(url);
Log.i("XMLParser", "Get URL: " + url);
String xml = null;
URL link;
BufferedReader reader = null;
StringBuilder stringBuilder = null;
InputStream is = null;
HttpURLConnection connection = null;
try {
link = new URL(url);
connection = (HttpURLConnection) link.openConnection();
connection.setRequestMethod("GET");
connection.connect();
is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is));
stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringBuilder.append(line + "\r");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
if(reader != null) reader.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if(is != null) is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if(connection != null) connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
try {
xml = stringBuilder.toString();
} catch(Exception e) {
e.printStackTrace();
}
return xml;
}
public static URI encodeUrl(String url) {
URL urlObject;
URI uri = null;
try {
urlObject = new URL(url);
uri = new URI(urlObject.getProtocol(), urlObject.getUserInfo(), urlObject.getHost(),
urlObject.getPort(), urlObject.getPath(), urlObject.getQuery(), urlObject.getRef());
} catch (Exception e) {
e.printStackTrace();
}
return uri;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
答案 0 :(得分:2)
经过几天/几小时的工作后,我发现与http.keepalive
的持久关联(HttpUrlConnection
)并非全部被破解为:
1)您需要确保InputStream
和HttpUrlConnection
已关闭,然后才能重复使用连接,而即使也可能无法始终重复使用。
2)开放TCP连接可能是资源占用。
找到&测试using cookies with HttpUrlConnection的想法我决定走这条路,因为它的声音从根本上说比我原来的想法更好。