HttpURLConnection - 使用基本身份验证的重复请求
HttpURLConnection - repeated request with basic authentication
我的应用程序需要向同一域发出大量请求,以获得具有基本身份验证的 REST API。
下面的代码有效,但每次都需要用户名和密码。有没有办法像在浏览器中一样只进行一次身份验证? (我在桌面版的c#中遇到了同样的问题)
public class RestRequest {
public enum RestMethod {GET, POST}
private String mUrl, mParams;
private RestMethod mMethod;
public RestRequest(RestMethod method, String url) {
this(method, url, "");
}
public RestRequest(RestMethod method, String url, String params) {
mUrl = url;
mParams = (params != null) ? params : "";
mMethod = method;
}
public RestResponse sendRequest(String authorization) throws IOException {
HttpURLConnection connection = openConnection(authorization);
if (mMethod == RestMethod.POST) {
postParams(connection);
}
InputStream is = null;
boolean error = false;
int statusCode = HttpURLConnection.HTTP_ACCEPTED;
try {
is = connection.getInputStream();
} catch (IOException e) {
statusCode = getErrorCode(connection);
is = connection.getErrorStream();
}
return new RestResponse(readStream(is), error, statusCode);
}
public RestRequest addParam(String name, String value) {
if (mMethod == RestMethod.GET) {
try {
String encoded = URLEncoder.encode(value, StandardCharsets.UTF_8.name());
mParams += name + "=" + encoded + "&";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return this;
}
//authorization is username:password
private HttpURLConnection openConnection(String authorization) throws IOException {
URLConnection connection;
URL url;
if (mMethod == RestMethod.GET)
url = new URL(mUrl + "?" + mParams);
else
url = new URL(mUrl);
connection = url.openConnection();
String authStringEnc = Base64.encodeToString(authorization.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
return (HttpsURLConnection) connection;
}
private void postParams(URLConnection connection) throws IOException {
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
OutputStream output = connection.getOutputStream();
output.write(mParams.getBytes());
}
private static int getErrorCode(HttpURLConnection conn) {
int httpStatus;
try {
return conn.getResponseCode();
} catch (IOException e) {
return -1;
}
}
private String readStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
if (is != null) {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
谢谢。
这部分在这里是因为我的问题是 "mostly code" 否则。
浏览器使用 Cookie。为此,您需要拦截登录响应中的 cookie,保存它们,稍后您可以在请求中发送它们。 Look at the answer on this Whosebug answer on how to achieve it
我的应用程序需要向同一域发出大量请求,以获得具有基本身份验证的 REST API。
下面的代码有效,但每次都需要用户名和密码。有没有办法像在浏览器中一样只进行一次身份验证? (我在桌面版的c#中遇到了同样的问题)
public class RestRequest {
public enum RestMethod {GET, POST}
private String mUrl, mParams;
private RestMethod mMethod;
public RestRequest(RestMethod method, String url) {
this(method, url, "");
}
public RestRequest(RestMethod method, String url, String params) {
mUrl = url;
mParams = (params != null) ? params : "";
mMethod = method;
}
public RestResponse sendRequest(String authorization) throws IOException {
HttpURLConnection connection = openConnection(authorization);
if (mMethod == RestMethod.POST) {
postParams(connection);
}
InputStream is = null;
boolean error = false;
int statusCode = HttpURLConnection.HTTP_ACCEPTED;
try {
is = connection.getInputStream();
} catch (IOException e) {
statusCode = getErrorCode(connection);
is = connection.getErrorStream();
}
return new RestResponse(readStream(is), error, statusCode);
}
public RestRequest addParam(String name, String value) {
if (mMethod == RestMethod.GET) {
try {
String encoded = URLEncoder.encode(value, StandardCharsets.UTF_8.name());
mParams += name + "=" + encoded + "&";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return this;
}
//authorization is username:password
private HttpURLConnection openConnection(String authorization) throws IOException {
URLConnection connection;
URL url;
if (mMethod == RestMethod.GET)
url = new URL(mUrl + "?" + mParams);
else
url = new URL(mUrl);
connection = url.openConnection();
String authStringEnc = Base64.encodeToString(authorization.getBytes(), Base64.NO_WRAP);
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
return (HttpsURLConnection) connection;
}
private void postParams(URLConnection connection) throws IOException {
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
OutputStream output = connection.getOutputStream();
output.write(mParams.getBytes());
}
private static int getErrorCode(HttpURLConnection conn) {
int httpStatus;
try {
return conn.getResponseCode();
} catch (IOException e) {
return -1;
}
}
private String readStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
if (is != null) {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
谢谢。
这部分在这里是因为我的问题是 "mostly code" 否则。
浏览器使用 Cookie。为此,您需要拦截登录响应中的 cookie,保存它们,稍后您可以在请求中发送它们。 Look at the answer on this Whosebug answer on how to achieve it