欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-19 13:20:37
1、准备工作引入两个maven依赖 org.apache.httpcomponentshttpclient4.5.8 ...

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

本文地址:https://blog.csdn.net/rj151YY/article/details/107159732