HttpClient通过InputStream形式上传文件以及通过File形式上传文件

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值