Springboot项目 RestTemplate+httpclient实现文件的上传和下载

1.pom.xml

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

2.代码

2.1 RestTemplate配置
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

@Slf4j
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
        //使用httpclient的factory
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        // 设置链接超时 毫秒
        requestFactory.setConnectTimeout(6000);
        // 设置读取超时 毫秒
        requestFactory.setReadTimeout(60000);
        requestFactory.setHttpClient(httpClient);
        return new RestTemplate(requestFactory);
    }
}
2.2 获取bean工具类
package com.example.springbootresttemplate.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextHelper implements ApplicationContextAware {

    private static ApplicationContext appCtx;

    /**
     * 通过name获取 Bean.
     *
     * @param name bean名
     * @return 返回
     */
    public static Object getBean(String name) {
        return appCtx.getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz bean类
     * @return 返回
     */
    public static <T> T getBean(Class<T> clazz) {
        return appCtx.getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name  bean名
     * @param clazz bean类
     * @return 返回
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return appCtx.getBean(name, clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("初始化applicationContext:" + applicationContext.getBeanDefinitionNames().length);
        appCtx = applicationContext;
    }
}

2.3 RestTemplate工具类
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class RestTemplateUtils {

    /**
     * 自定义请求头
     * 简单的 Get请求
     *
     * @param headers 参数
     * @param url     参数
     * @return 返回
     */
    public static ResponseEntity<String> simpleGet(HttpHeaders headers, String url) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        //将请求头部和参数合成一个请求
        HttpEntity<?> httpEntity = new HttpEntity<>(headers);
        return restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, httpEntity, String.class);
    }

    /**
     * 表单 - Query
     * 带参数 Get请求
     *
     * @param headers 参数
     * @param url     参数
     * @param params  参数
     * @return 返回
     */
    public static ResponseEntity<String> executeGetParam(HttpHeaders headers, String url, Map<String, String> params) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        headers.set("Content-Type", "application/x-www-form-urlencoded");
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.queryParam(entry.getKey(), entry.getValue());
            }
        }
        //将请求头部和参数合成一个请求
        HttpEntity<?> httpEntity = new HttpEntity<>(headers);
        return restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, httpEntity, String.class);
    }

    /**
     * 自定义请求头
     * - Query
     * - Body
     * 简单的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @return 返回
     */
    public static ResponseEntity<String> simplePost(HttpHeaders headers, String url) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        //将请求头部和参数合成一个请求
        HttpEntity<String> httpEntity = new HttpEntity<>(null, headers);
        return restTemplate.postForEntity(url, httpEntity, String.class);
    }

    /**
     * 表单 - Query
     * 带参数的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @param params  参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostFromParam(HttpHeaders headers, String url, Map<String, String> params) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        return restTemplate.postForEntity(url, getMultiValueMap(headers, null, params), String.class);
    }

    /**
     * 表单 - Query
     * 上传单个文件的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @param file    参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostFromFile(HttpHeaders headers, String url, File file) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        List<File> files = new ArrayList<>();
        files.add(file);
        return restTemplate.postForEntity(url, getMultiValueMap(headers, files, null), String.class);
    }

    /**
     * 表单 - Query
     * 上传多个文件的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @param files   参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostFromFile(HttpHeaders headers, String url, List<File> files) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        return restTemplate.postForEntity(url, getMultiValueMap(headers, files, null), String.class);
    }

    /**
     * 表单 - Query
     * 上传单个文件且带参数的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @param file    参数
     * @param params  参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostFromFileParam(HttpHeaders headers, String url, File file, Map<String, String> params) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        List<File> files = new ArrayList<>();
        files.add(file);
        return restTemplate.postForEntity(url, getMultiValueMap(headers, files, params), String.class);
    }

    /**
     * 表单 - Query
     * 上传多个文件且带参数的 Post 请求
     *
     * @param headers 参数
     * @param url     参数
     * @param files   参数
     * @param params  参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostFromFileParam(HttpHeaders headers, String url, List<File> files, Map<String, String> params) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        return restTemplate.postForEntity(url, getMultiValueMap(headers, files, params), String.class);
    }

    private static HttpEntity<MultiValueMap<String, Object>> getMultiValueMap(HttpHeaders headers, List<File> files, Map<String, String> params) {
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        if (files != null && files.size() > 0) {
            headers.set("Content-Type", "multipart/form-data");
            for (File file : files) {
                multiValueMap.add("file", new org.springframework.core.io.FileSystemResource(file));
            }
        } else {
            headers.set("Content-Type", "application/x-www-form-urlencoded");
        }
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                multiValueMap.add(entry.getKey(), entry.getValue());
            }
        }
        return new HttpEntity<>(multiValueMap, headers);
    }

    /**
     * Body请求 - Body
     *
     * @param headers 参数
     * @param url     参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostBody(HttpHeaders headers, String url) {
        return executePostBodyParam(headers, url, null);
    }

    /**
     * Body请求 - Body
     *
     * @param headers 参数
     * @param url     参数
     * @param str     参数
     * @return 返回
     */
    public static ResponseEntity<String> executePostBodyParam(HttpHeaders headers, String url, String str) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        headers.set("Content-Type", "application/json;charset=UTF-8");
        HttpEntity<String> httpEntity = new HttpEntity<>(str, headers);
        return restTemplate.postForEntity(url, httpEntity, String.class);
    }

    /**
     * 简单的文件下载,获取字节数组
     *
     * @param url 连载链接
     * @return 返回
     */
    public static ResponseEntity<byte[]> downloadFileSmall(String url) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        return restTemplate.getForEntity(url, byte[].class);
    }

    /**
     * 大文件的下载
     *
     * @param url        下载链接
     * @param targetPath 文件保存的本地路径(全路径)
     *                   对于大文件的下载,建议使用流的方式来解决。
     *                   即每次接收到一部分数据就直接写入到文件。这里我使用使用 Files 的 copy 方法来处理流。
     */
    public static void downloadFileBig(String url, String targetPath) {
        RestTemplate restTemplate = ApplicationContextHelper.getBean(RestTemplate.class);
        //定义请求头的接收类型
        RequestCallback requestCallback = request -> request.getHeaders()
                .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
        //定义请求头的接收类型
        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
            Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
            return null;
        });
    }
}
2.4 测试
    @Test
    void RestTemplateTest() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json;charset=UTF-8");
        headers.set("token", "******************");
        ResponseEntity<String> responseEntity = RestTemplateUtils.simplePost(headers, "https://getman.cn/mock/test");
        System.out.println(responseEntity);
    }
上一篇:springBoot 实现文件提交(form表单提交)


下一篇:request框架练习