背景
使用httpClient访问需要登录授权的接口,提示失败没有权限。
登录保持HttpClient授权状态
以下方法只适用于简单的鉴权。复杂鉴权方案不适用
- doLogin() 登录
使用线程维护变量保存登录后的客户端,在本线程不结束的时候可以一直使用本客户端访问需要授权的API。
public class HttpClientUtil {
public static final String LOGIN_URL = "https://xxx/login";
// 在一个线程中维护同一个httpClient客户端
private static final ThreadLocal<CloseableHttpClient> threadLocal = new ThreadLocal<>();
public static JSONObject doLogin() throws IOException {
CloseableHttpClient httpClient = threadLocal.get();
Map<String, String> loginParam = new HashMap<>();
loginParam.put("username", "用户名");
loginParam.put("password", "密码");
if (httpClient == null) {
httpClient = HttpClients.createDefault();
String rsp = doPost(httpClient, LOGIN_URL, loginParam, null);
threadLocal.set(httpClient);
return JSONObject.parseObject(rsp);
} else {
String rsp = doPost(httpClient, LOGIN_URL, loginParam, null);
return JSONObject.parseObject(rsp);
}
}
// 不贴具体访问api的接口了:在同一个访问线程中,取到登录后存起来的同一个 http访问客户端,使用这个客户端可以访问登陆后可已访问的API(复杂鉴权的除外);
// 在线程结束后,httpclient失效,下次访问需要重新授权;
public static String otherAuthApi() {
CloseableHttpClient httpClient = threadLocal.get();
// TODO: 执行其他需要授权的 POST GET请求
return "result";
}
public static String doPost(CloseableHttpClient client, String url, Map<String, String> parameters, Map<String, String> headerMap) throws IOException {
String result = null;
HttpPost httpPost = new HttpPost(url);
if ((parameters != null) && (!(parameters.isEmpty()))) {
List<NameValuePair> nameValuePairs = new ArrayList<>();
Set<Entry<String, String>> entrySet = parameters.entrySet();
for (Entry<String, String> item : entrySet) {
nameValuePairs.add(new BasicNameValuePair(item.getKey(), item.getValue()));
}
HttpEntity reqEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
httpPost.setEntity(reqEntity);
}
// 设置请求头
if (headerMap != null && !headerMap.isEmpty()) {
Set<Entry<String, String>> entrySet = headerMap.entrySet();
for (Entry<String, String> item : entrySet) {
httpPost.addHeader(item.getKey(), item.getValue());
}
}
HttpResponse response = client.execute(httpPost);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "utf-8");
}
}
client.close();
return result;
}
private static String doGet(CloseableHttpClient client, String url, Map<String, String> parameters, Map<String, String> headerMap) throws IOException, URISyntaxException {
String result = null;
HttpGet httpGet = new HttpGet(url);
// 设置请求参数
if ((parameters != null) && (!(parameters.isEmpty()))) {
URIBuilder uriBuilder = new URIBuilder(url);
List<NameValuePair> nameValuePairs = new ArrayList<>();
Set<Entry<String, String>> entrySet = parameters.entrySet();
for (Entry<String, String> item : entrySet) {
nameValuePairs.add(new BasicNameValuePair(item.getKey(), item.getValue()));
}
uriBuilder.setCharset(StandardCharsets.UTF_8);
uriBuilder.setParameters(nameValuePairs);
}
// 设置请求头
if (headerMap != null && !headerMap.isEmpty()) {
Set<Entry<String, String>> entrySet = headerMap.entrySet();
for (Entry<String, String> item : entrySet) {
httpGet.addHeader(item.getKey(), item.getValue());
}
}
HttpResponse response = client.execute(httpGet);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "utf-8");
}
}
client.close();
return result;
}
}
- 维持登录后的Cookie
Map<String, String> headersMap = new HashMap<>();
headersMap.put("cookie", "登录后生成的cookie");
// 登录后生成的cookie记录下来,就不需要每次重新登录
// 1. 创建HttpClient客户端:client
// 2. 将headersMap设置到client
// 3. 访问API
doPost(client, ... headersMap)