1、准备工作
引入两个maven依赖
<!--文件上传-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
</dependency>
2、HttpClient以InputStream形式上传文件
/**
* 以流的形式文件上传
* @param host
* @param restPath
* @param auth
* @param fileName
* @param inputStream
* @return java.lang.String
* @author xyy
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo uploadFileByInputStream()
* @since V1.0
*/
public static String uploadFileByInputStream(String host, String restPath, AuthMethod auth,
String fileName, InputStream inputStream) throws WikiClientException {
String result="";
try {
//构建HttpClient对象,此处主要是为了支持https请求,如若只是请求http,可通过HttpClients.createDefault();获取httpClient对象
HttpClient client = wrapClient(host, restPath);
//CloseableHttpClient client = HttpClients.createDefault();
//构建POST请求
HttpPost httpPost = new HttpPost(host+restPath);
httpPost.setHeader("X-Atlassian-Token","nocheck");
//此处设置的是confluence的账号密码,也可根据需求修改为设置cookies
httpPost.setHeader("Authorization", auth.getAuthHeaderValue());
httpPost.setConfig(setTimeOutConfig(httpPost.getConfig()));
//处理文件后面的setMode是用来解决文件名称乱码的问题:以浏览器兼容模式运行,防止文件名乱码。
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setCharset(Charset.forName("UTF-8"));
//如果以inputStream形式上传文件,接收文件上传的接口可能会限制content-type为二进制:ContentType.DEFAULT_BINARY,否则为ContentType.MULTIPART_FORM_DATA
builder.addBinaryBody("file", inputStream, ContentType.DEFAULT_BINARY, fileName);
HttpEntity httpEntity = builder.build();
httpPost.setEntity(httpEntity);
HttpResponse httpResponse = client.execute(httpPost);
HttpEntity responseEntity = httpResponse.getEntity();
//判断响应结果
if (responseEntity != null && httpResponse.getStatusLine().getStatusCode() != 200) {
throw new WikiClientException("客户端请求失败!");
}else {
result = HttpUtils.parseString(httpResponse);
System.out.println("文件上传响应结果:"+result);
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (inputStream != null){
try {
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
return result;
}
3、HttpClient以File形式上传文件
/**
*方法说明 以file格式上传文件
* @param host
* @param restPath
* @param auth
* @param filePath
* @param fileName
* @return void
* @author xyy
* @date 2020/7/6
* @throws
* @update
* @see HttpUtils fileUpload()
* @since V1.0
*/
public static void fileUploadByFile(String host, String restPath, AuthMethod auth,
String filePath, String fileName) throws WikiClientException{
try {
//构建HttpClient对象,此处主要是为了支持https请求,如若只是请求http,可通过HttpClients.createDefault();获取httpClient对象
HttpClient client = wrapClient(host, restPath);
//CloseableHttpClient client = HttpClients.createDefault();
//构建POST请求
HttpPost httpPost = new HttpPost(host+restPath);
httpPost.setHeader("X-Atlassian-Token","nocheck");
//此处设置的是confluence的账号密码,也可根据需求修改为设置cookies
httpPost.setHeader("Authorization", auth.getAuthHeaderValue());
httpPost.setConfig(setTimeOutConfig(httpPost.getConfig()));
//要上传的文件
File file = new File(filePath);
//构建文件体
FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA, fileName);
HttpEntity httpEntity = MultipartEntityBuilder
.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addPart("file", fileBody).build();
httpPost.setEntity(httpEntity);
//发送请求
HttpResponse response = client.execute(httpPost);
httpEntity = response.getEntity();
if (httpEntity != null && response.getStatusLine().getStatusCode() != 200) {
throw new WikiClientException("客户端请求失败!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
4、根据url下载网络文件
/**
* 根据url下载网络文件
* @param downloadUrl
* @param auth
* @return java.io.InputStream
* @author xyy
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo downloadNet()
* @since V1.0
*/
public static InputStream downloadNet(String downloadUrl, AuthMethod auth) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpget = new HttpGet(downloadUrl);
//如若只是单纯的网络文件,不需要验证账号密码时,此处可不需要设置
httpget.setHeader("Authorization", auth.getAuthHeaderValue());
HttpResponse response = client.execute(httpget);
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
byte[] bytes = readInputStream(inputStream);
//文件保存位置
FileOutputStream fos = new FileOutputStream(new File("E:/tmp/aa.jpg"));
fos.write(bytes);
if (fos != null){
fos.close();
}
if (inputStream != null){
inputStream.close();
}
return inputStream;
}
/**
* 将inputStream转化为byte[]
* @param inputStream
* @return byte[]
* @author zhaoyuanyuan
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo readInputStream()
* @since V1.0
*/
public static byte[] readInputStream(InputStream inputStream)throws IOException{
byte[] buffer = new byte[1024*4];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
bos.close();
System.err.println(bos.toByteArray().length);
return bos.toByteArray();
}
5、其他相关方法或文件
5.1 相关方法
/**
* 获取 HttpClient
* @param host
* @param path
* @return org.apache.http.client.HttpClient
* @author zhaoyuanyuan
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo wrapClient()
* @since V1.0
*/
private static HttpClient wrapClient(String host, String path) {
HttpClient httpClient = HttpClientBuilder.create().build();
if (host != null && host.startsWith("https://")) {
return sslClient();
} else if (StringUtils.isBlank(host) && path != null && path.startsWith("https://")) {
return sslClient();
}
return httpClient;
}
/**
* 在调用SSL之前需要重写验证方法,取消检测SSL,创建ConnectionManager,添加Connection配置信息
* 此httpClient支持https
* @return org.apache.http.impl.client.CloseableHttpClient
* @author xyy
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo sslClient()
* @since V1.0
*/
private static CloseableHttpClient sslClient() {
try {
// 在调用SSL之前需要重写验证方法,取消检测SSL
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null, new TrustManager[]{trustManager}, null);
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
// 创建Registry
RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT)
.setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", socketFactory).build();
// 创建ConnectionManager,添加Connection配置信息
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig).build();
return closeableHttpClient;
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
/**
* 设置 连接超时、 请求超时 、 读取超时 毫秒
* @param requestConfig
* @return org.apache.http.client.config.RequestConfig
* @author zhaoyuanyuan
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo setTimeOutConfig()
* @since V1.0
*/
private static RequestConfig setTimeOutConfig(RequestConfig requestConfig) {
if (requestConfig == null) {
requestConfig = RequestConfig.DEFAULT;
}
return RequestConfig.copy(requestConfig)
.setConnectionRequestTimeout(60000)
.setConnectTimeout(60000)
.setSocketTimeout(10000)
.build();
}
5.2 相关文件(用户/tocken验证)
package com.ccbfintech.wiki.apidispatcher.auth;
/**
* This interface defines the methods required for a HTTP authentication method.
*/
public interface AuthMethod {
/**
* This method generates a value to be passed in the "Authorization" header of any HTTP requests
* using this authorization method.
*
* @return The value to set in the "Authorization" header of any requests using this authorization
* method.
*/
String getAuthHeaderValue();
}
package com.ccbfintech.wiki.apidispatcher.auth;
import java.util.Base64;
/**
* This class represents the Basic HTTP authentication scheme.
*/
public class BasicAuth implements AuthMethod {
private String username;
private String password;
/**
* This constructor creates a new instance of {@link BasicAuth} using the given username and
* password.
*
* @param username The username to use for authentication
* @param password The corresponding password for the given username
*/
public BasicAuth(String username, String password) {
this.username = username;
this.password = password;
}
/**
* This method generates a value to be passed in the "Authorization" header of any HTTP requests
* using this authorization method.
*
* @return The value to set in the "Authorization" header of any requests using this authorization
* method.
*/
public String getAuthHeaderValue() {
System.out.println("Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes()));
return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
}
}
package com.ccbfintech.wiki.apidispatcher.auth;
/**
* This class represents a token-based HTTP authentication scheme, such as JWT.
*/
public class TokenAuth implements AuthMethod {
private String token;
/**
* This constructor creates a new instance of {@link TokenAuth} using the given token.
*
* @param token The token to use for authentication
*/
public TokenAuth(String token) {
this.token = token;
}
/**
* This method generates a value to be passed in the "Authorization" header of any HTTP requests
* using this authorization method.
*
* @return The value to set in the "Authorization" header of any requests using this authorization
* method.
*/
public String getAuthHeaderValue() {
return "Bearer " + token;
}
}
5.3 测试
/**
* 此处是根据confluence附件下载和上传接口进行测试
* @param args
* @return void
* @author xyy
* @date 2020/7/6
* @throws
* @update
* @see FileUploadDemo main()
* @since V1.0
*/
public static void main(String[] args) {
//账号 密码
AuthMethod basicAuth = new BasicAuth("admin","111111");
//测试文件下载
String downloadUrl = "http://localhost:8090/download/attachments/6586376/%E5%9C%A8%E7%BA%BF%E6%96%87%E6%A1%A3%E5%BA%93%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3%281%29.pdf?version=1&modificationDate=1593939665000&api=v2";
//文件上传请求接口
String host = "http://localhost:8090";
String path = "/rest/api/content/6881281/child/attachment";
//文件名
String fileName = "test3.pdf";
try {
InputStream inputStream = downloadNet(downloadUrl, basicAuth);
uploadFileByInputStream(host, path, basicAuth, fileName, inputStream);
}catch (WikiClientException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
参考文献:https://blog.csdn.net/zknxx/article/details/72760315?fps=1&locationNum=2