springboot 中使用httpclient或RestTemplate做MultipartFile文件跨服务传输

springboot 中使用httpclient或RestTemplate做MultipartFile文件传输

大家好,因为近期做需求中遇到了文件上传这个东西,而且我这个还是跨服务去传输文件的所以我这边使用了httpclient和RestTemplate去做,但是最后还是用的httpclientfeign和RestTemplate在超大文件下会OOM所以适用于小文件传输我这边测试的在1G以下httpclient好像是无限哈哈哈。(具体多少大家有时间可以去测一下)

1.被调用服务的Controller

1.这块使用@RequestParam(“file”)或者@RequestPart(“file”)都是可以接到参数的。
2.(“file”)一定要和远程调用代码传的参数名一样 否则接不到参数。

    @RequestMapping(value = "/remoteCallUpload",method = RequestMethod.POST)
    @ApiOperation("测试远程调用上传")
    public String remoteCallUpload(@RequestParam("file") MultipartFile file){
        System.out.println(file);
        return "成功";
    }

1.RestTemplate

1.如果用RestTemplate的话首先需要把RestTemplate交给spring去管理所以先来一个配置类。
2.@SuppressWarnings(“all”) 这个注解是jdk自带的的意思是 意志所有的警告。

@Configuration
@SuppressWarnings("all")
public class RestTemplateConfig {

    @Autowired
    RestTemplateBuilder builder;

    @Bean
    public RestTemplate restTemplate() {
        return builder.build();
    }
}

2.RestTemplate远程调用文件传输

这里有几个要注意的地方

1.必须重写否则传输时报错


ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
        };

2.设置请求头因为就在模拟前端发送上传文件的请求所以请求头必须是multipart/form-data

3.第三个参数是被调用Controller的返回值类型,我的测试Controller写的是String所以我的这边第三参数就是String.Class

restTemplate.postForObject(url, files, String.class);

4.url就是被调用服务的地址 如:

http://192.168.3.7:50003/test/remoteCallUpload

以上是注意事项。

@Autowired
private RestTemplate restTemplate;

private String gettestRestTemplate(MultipartFile file, String url) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        ByteArrayResource byteArrayResource = new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }
        };
        form.add("file", byteArrayResource);
        form.add("filename", file.getOriginalFilename());
        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);

        String flag = restTemplate.postForObject(url, files, String.class);

        return flag;
    }

3.HttpClient

1.使用httpclient的话首先要引入pom文件坐标。

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

3.HttpClient远程调用文件传输

1.httpclient这段代码有要用的小伙伴直接粘过去就能用
注意一下返回值自己改一下就行execute.getEntity()

	@SneakyThrows
    private String gettesthttpclient(MultipartFile file, String url) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(url);
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        // 解决中文文件名乱码问题
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setCharset(Consts.UTF_8);
        ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8);
        entityBuilder.addBinaryBody("file", file.getInputStream(), ContentType.DEFAULT_BINARY, file.getOriginalFilename());
        httpPost.setEntity(entityBuilder.build());
        httpPost.setConfig(requestConfig);
        HttpResponse execute = httpclient.execute(httpPost);
        String flag = EntityUtils.toString(execute.getEntity());
        return flag;
    }

总结

远程调用使用了RestTemplate和httpclient也可以使用feign,但是RestTemplate和feign大文件会OOM,httpclient不会所以大家可以根据自己场景去选择。

强强强

  • 15
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
Spring Boot 3.1 使用 `RestTemplate` 和 `HttpClient 5`,你需要添加以下依赖项到你的 `pom.xml` 文件: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>5.0.4</version> </dependency> </dependencies> ``` 然后,你需要创建一个 `RestTemplate` 的 Bean,使用 `HttpClient 5` 作为底层 HTTP 客户端。以下是示例代码: ```java import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.http.protocol.HttpRequestInterceptor; import org.apache.hc.core5.http.protocol.RequestAddCookies; import org.apache.hc.core5.http.protocol.RequestDefaultHeaders; import org.apache.hc.core5.http.protocol.ResponseProcessCookies; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { // 创建 HttpClient CloseableHttpClient httpClient = HttpClients.custom() .setDefaultRequestConfig(RequestConfig.custom() .setSocketTimeout(5000) .setConnectTimeout(5000) .build()) .setConnectionManager(new PoolingHttpClientConnectionManager( RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", SSLConnectionSocketFactory.getSocketFactory()) .build())) .setDefaultSocketConfig(SocketConfig.custom() .setTcpNoDelay(true) .build()) .addInterceptorFirst((HttpRequestInterceptor) new RequestDefaultHeaders( Arrays.asList(new BasicHeader("User-Agent", "MyRestClient")))) // 设置 User-Agent .addInterceptorFirst(new RequestAddCookies()) .addInterceptorLast(new ResponseProcessCookies()) .build(); // 创建 RestTemplate HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(factory); return restTemplate; } } ``` 这里我们创建了一个 `RestTemplate` 的 Bean,使用 `HttpClient 5` 作为底层 HTTP 客户端。我们还可以设置一些默认的请求配置和拦截器,例如设置 `User-Agent`、添加 Cookie 等。 现在你可以在你的代码使用 `RestTemplate` 进行 HTTP 请求了: ```java @Autowired private RestTemplate restTemplate; public void doRequest() { String url = "http://example.com/api"; ResponseEntity<String> response = restTemplate.getForEntity(url, String.class); String body = response.getBody(); // 处理响应数据 } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值