feign、RestTemplate及(httpclient基于https协议)文件上传、下载到文件服务器

功能描述:上传文件到文件服务器,返回文件在服务器地址,下载(获取)文件直接可以在浏览器拼接地址(ip:端口/返回文件在服务器地址)

 

一、feign上传下载

引入maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

1、上传接口

@FeignClient(name = "fileUploadAPI", url = "${file.uploadPath}")
public interface FileUploadAPI {
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String uploadImage(@RequestPart(value = "img") MultipartFile img);
}

2、下载接口

@FeignClient(name = "FileDownAPI",url = "${file.downPath}")
public interface FileDownAPI {

    @GetMapping(value = "{path}")
    Response getImage(@PathVariable("path") String path);
}

下载文件api调用 

private void downImage(String path, String parentFile) {
        Response response = fileDownAPI.getImage(path);
        Response.Body body = response.body();
        try {
            InputStream inputStream = body.asInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

            //路劲类似格式:/images/20220719/6204bc93415ec044c50f60ad5bcc132c.png
            String[] split = path.split("\\/");
            if (split.length == 4) {
                File img = new File(parentFile + "/" + split[3]);
                if (!img.exists()) {
                    img.createNewFile();
                }
                FileOutputStream fileOutputStream = new FileOutputStream(img);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                int length = 0;
                byte[] bytes = new byte[1024 * 10];
                while ((length = bufferedInputStream.read(bytes)) != -1) {
                    bufferedOutputStream.write(bytes, 0, length);
                }
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
                bufferedInputStream.close();
                inputStream.close();
            } else {
                throw new RuntimeException("图片路径格式不对,必须为:/***/***/**.jpg 格式");
            }
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw new RuntimeException("获取文件失败", e);
        }
    }

这里之所以写两个接口是因为如果上传地址和下载地址不一致(端口开始就不一样)的情况

二、httpclient上传

引入依赖:

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

1、http协议文件上传

private static String inputFileByHttp(String uploadUrl) throws IOException {

//        uploadUrl = "http://192.168.0.1:8080/images";
        String localFile = "docs/test.txt";
        File file = new File(localFile);
        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost post = new HttpPost(uploadUrl);

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
        //这两个都可以
//        multipartEntityBuilder.addBinaryBody("img",fileInputStream,ContentType.MULTIPART_FORM_DATA,"test.txt");
        multipartEntityBuilder.addBinaryBody("img", file);
        HttpEntity httpEntity = multipartEntityBuilder.build();
        post.setEntity(httpEntity);

        CloseableHttpResponse response = httpClient.execute(post);
        String result = "无数据返回";
        if (200 == response.getStatusLine().getStatusCode()) {
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
            System.out.println(result);
        }
        return result;
    }

2、https协议文件上传

 private static String inputFileByHttps(String uploadUrl) throws IOException {
//        uploadUrl = "https://baidu.xx.com:10000/images";
        String localFile = "docs/test.txt";
        File file = new File(localFile);
        FileInputStream fileInputStream = new FileInputStream(file);

        CloseableHttpClient httpClient = createSSLClient();
        HttpPost post = new HttpPost(uploadUrl);

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
        //这两个都可以
        multipartEntityBuilder.addBinaryBody("img",fileInputStream,ContentType.MULTIPART_FORM_DATA,"test.txt");
//        multipartEntityBuilder.addBinaryBody("img", file);
        HttpEntity httpEntity = multipartEntityBuilder.build();
        post.setEntity(httpEntity);

        CloseableHttpResponse response = httpClient.execute(post);
        String result = "无数据返回";
        if (200 == response.getStatusLine().getStatusCode()) {
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
            System.out.println(result);
        }
        return result;
    }

private static CloseableHttpClient createSSLClient() {
        SSLContext sslContext;
        try {
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                @Override
                public boolean isTrusted(X509Certificate[] xcs, String string) {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyStoreException ex) {
            ex.printStackTrace();
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (KeyManagementException ex) {
            ex.printStackTrace();
        }

        return HttpClients.createDefault();
    }

http和https综上代码可以看到在获取httpclient的时候有区别,https需要设置ssl信任

三、postman上面测试https协议文件上传设置

 文件key必须要正确

关闭settings设置里面的ssl证书验证,一般默认是开启的 

 

 开启settings设置里面的CA证书,默认是关闭的

四、RestTemplate 通过https协议文件下载
1、引入依赖:或者feign的依赖包也可以,里面包含这个依赖

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

2、创建bean,这里由于spring没有创建该实例,所以手动将该RestTemplate实例配置到sping容器。这里如果是http协议的话,直接return new RestTemplate(); 就可以,里面的代码实际就是配置https协议做准备

    @Bean
    public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyStoreException, 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();
        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        return new RestTemplate(requestFactory);
    }

3、调用下载

public void downFile(){
        try {
            String url=String.format("https://xxxx/20220801/9213b8102bd447b17b4da19174a20916.xlsx");
            ResponseEntity<byte[]> exchange = restTemplate.exchange(new URI(url), HttpMethod.GET, new HttpEntity<>(new HttpHeaders()), byte[].class);
            byte[] bytes = exchange.getBody();
            File file = new File("exaple.xlsx");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(bytes, 0, bytes.length);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

实际上,如果不是要求多高的项目,就直接用RestTemplate远程调用最方便,属于spring-web jar包,而且还可以加上负载均衡注解@LoadBalance做负载

五、文件下载请求。下载文件到本地,以及文件名称为中文时出现下划线或者乱码情况

@RequestMapping(value = "getImgZip", method = RequestMethod.GET)
    @ResponseBody
    public void getImgZip(HttpServletResponse servletResponse) {
        File file = new File("D://test-张三-2022-08-30.zip");
        try {
            String encode = URLEncoder.encode(file.getName(), "UTF-8");
            servletResponse.setHeader("Content-disposition", "attachment;filename="+encode+";"+"filename*=utf-8''"+encode);
            servletResponse.setContentType("application/octet-stream");
            if (!(file.exists() && file.canRead())) {
                throw new RuntimeException("zip文件不存在");
            }
            FileInputStream inputStream = null;
            inputStream = new FileInputStream(file);
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
            OutputStream stream = servletResponse.getOutputStream();
            stream.write(data);
            stream.flush();
            stream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
String encode = URLEncoder.encode(file.getName(), "UTF-8");
servletResponse.setHeader("Content-disposition", "attachment;filename="+encode+";"+"filename*=utf-8''"+encode);
主要是这两句:
String encode = URLEncoder.encode(file.getName(), "UTF-8");
编码为utf-8,
设置头部信息格式为:"Content-disposition", "attachment;filename=" + encode + ";" + "filename*=utf-8''" + encode
但是注意这里的encode后面补加的 +";"+"filename*=utf-8''"+encode 是关键
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱墩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值