版权声明:本文为博主原创文章,转载请附上原文链接。 https://blog.csdn.net/Jayszxs/article/details/82980037
在工作中遇到过在一个服务器应用(A)上去请求另一个服务器应用(B)上的资源,然后在A中去二次处理该资源的问题,其实追根到底,就是一次cp的操作。
因为B应用是一个第三方的应用,只能通过使用http请求的方式去获取其上的资源。
做个简单的示意图:
接下来上代码:
首先,模拟登陆记录 :
public CloseableHttpClient login(String loginUrl, String id, String pw) {
CloseableHttpClient httpClient = HttpClients.createDefault();
// 使用的是post请求方法
HttpPost httPost = new HttpPost(loginUrl);
// 设置请求参数
List<NameValuePair> nvp = new ArrayList<>();
// 用户名
nvp.add(new BasicNameValuePair("id", id);
// 密码
nvp.add(new BasicNameValuePair("pw", pw));
/**
* 以及其他参数 。。。
*/
try {
// 将请求参数放入到post entity中
httPost.setEntity(new UrlEncodedFormEntity(nvp, Constants.sCharSet));
String html = httpClient.execute(httPost, responseHandler);
if("".equals(html)) {
logger.info("登录成功!");
} else {
logger.warn("登录失败!");
}
} catch (UnsupportedEncodingException e) {
logger.error("设置post请求参数出错!", e);
} catch (ClientProtocolException e) {
logger.error("ClientProtocolException 登录请求出错!", e);
} catch (IOException e) {
logger.error("IOException 登录请求出错!", e);
} finally {
httPost.abort();
}
return httpClient;
}
登陆成功后,会返回一个CloseableHttpClient 对象。并终止这次请求
httPost.abort();
接下来就是请求资源了,可根据应用B的接口类型,选择相应的请求类型[get/post]
/**
* 下载并复制文件
*/
pubic JSONObject copyFile(CloseableHttpClient httpClient, String fileId, String getUrl, String name, String bApplicationUrl) {
HttpPost httPostDownload = new HttpPost(getUrl);
// 下载文件流
InputStream inputStream = null;
// copy文件流
OutputStream outputStream = null;
// 返回对象
JSONObject fileJson = new JSONObject();
try {
List<NameValuePair> nvpDownload = new ArrayList<>();
nvpDownload.add(new BasicNameValuePair("action", "query"));
nvpDownload.add(new BasicNameValuePair("id", fileId));
// 其他参数 。。。
httPostDownload.setEntity(new UrlEncodedFormEntity(nvpDownload, Constants.sCharSet));
// 发送查询文件信息 -》 返回 文件路径和下载地址
HttpResponse httpResponseQuery = httpClient.execute(httPostDownload);
HttpEntity httpEntityQuery = httpResponseQuery.getEntity();
if (httpEntityQuery != null) {
// 获取返回的文件信息
JSONObject jsonObject = this.getFileInfo(httpEntityQuery);
String fileDownloadUrl = jsonObject.getString("fileDownloadUrl");
//下载文件
String url = bApplicationUrl + "/" + fileDownloadUrl;
HttpGet httpGetDownload = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGetDownload);
HttpEntity httpEntityDownload = httpResponse.getEntity();
inputStream = httpEntityDownload.getContent();
//copy 文件到A所在服务器
// 文件路径和后缀
String cpFilePath = Constants.COPY_FILE_PATH + "/" + name + Constants.FILE_SUFFIX;
outputStream = new FileOutputStream(new File(cpFilePath));
StreamUtils.copy(inputStream, outputStream);
// 记录文件信息
fileJson.put("name",reportName);
fileJson.put("path",cpFilePath);
}
} catch (UnsupportedEncodingException e) {
logger.error("设置post请求参数出错!", e);
} catch (ClientProtocolException e) {
logger.error("连接失败!", e);
} catch (FileNotFoundException e) {
logger.error("目标文件未找到!", e);
} catch (IOException e) {
logger.error("获取文件流失败!", e);
} finally {
try {
if(outputStream != null) {
outputStream.close();
}
if(inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
logger.error("关闭流失败!", e);
}
httPostDownload.abort();
}
return fileJson;
}
请求之后的返回信息到将封装在entity中,要获取响应数据
// 获取httpentity
HttpEntity httpEntityDownload = httpResponse.getEntity();
// 从httpentity中获取输入流
inputStream = httpEntityDownload.getContent();
这样就会获取到一个json对象,每个json对象得到的是一个资源在应用A服务器上的具体位置和名字,再进行二次加工即可。不过最后记得要关闭httpclient对象。
httpClient.close();
记录一下~