Springboot2.7 文件上传和下载

本文介绍了在Java中处理文件上传和下载的方法,包括如何使用`MultipartFile`处理上传文件,以及通过`@GetMapping(/download)`处理文件下载请求,对比了`outputStream.write()`和`outputStream.print()`的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、文件上传

public R<String> uploadFile(MultipartFile files){
        LocalDate now = LocalDate.now();
        int month = now.getMonthValue();
        int year = now.getYear();
        int day = now.getDayOfMonth();
        String s = UUID.randomUUID().toString().replace("-","");
        String filename = s+files.getOriginalFilename().substring(files.getOriginalFilename().lastIndexOf("."));
        String returnFilename = year+"-"+month+"-"+day+"-"+filename;
        String filePath = uploadDir+"\\"+year+"\\"+month+"\\"+"\\"+day+"\\"+filename;
        File file = new File(filePath);
        if (!file.exists()){
            file.mkdirs();
        }

        try {
            files.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return R.success(returnFilename);

    }

2、文件下载

outputStream.write()

outputStream.print()

都可以将后端的数据响应的前端,但是仔细对比是有区别的,需要根据实际使用进行区分。

@GetMapping("/download")
    public void downloadFile(String name, HttpServletResponse response) throws IOException {

        String[] filename = name.split("-");
        String filePath = uploadDir+"/"+filename[0]+"/"+filename[1]+"/"+filename[2]+"/"+filename[3];

        File file = new File(filePath);
        if (file.exists()){
            byte[] bytes = new byte[1024];
            int read = 0;
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream fis = new FileInputStream(file);
            response.setContentType("image/jpg");
            try {
                while ((read = fis.read(bytes)) != -1){
                    outputStream.write(bytes,0,read);
                    outputStream.flush();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                outputStream.close();
                fis.close();
            }

        }else{
           
            response.setContentType("text/html;charset=utf-8");
      
            response.getWriter().write("<h1>文件不存在</h1>");
      
            response.setStatus(203);
        }


    }

<think>好的,我现在需要帮助用户了解在Spring Boot 2.7中如何使用FeignClient。首先,用户之前的问题是关于Spring循环依赖的,现在转到了FeignClient的使用,可能他们在开发微服务时遇到了服务间调用的需求,而FeignClient是常用的解决方案。 首先,我应该确认用户的需求。他们可能已经知道FeignClient的基本概念,但需要具体的配置使用步骤。用户提到的是Spring Boot 2.7,所以需要确保提供的代码依赖版本与该版本兼容。 接下来,我需要回忆FeignClient在Spring Boot中的一般使用步骤。通常包括添加依赖、启用Feign、创建接口、配置参数等。可能还需要处理日志、拦截器、超时设置等高级配置。需要注意Spring Boot 2.7对应的Spring Cloud版本,因为不同版本的配置可能不同。例如,Spring Boot 2.7通常对应Spring Cloud 2021.0.3,因此需要确认依赖的正确性。 然后,用户可能需要示例代码,所以应该准备一个简单的例子,包括接口定义、启动类注解、配置文件的设置。此外,常见的注意事项错误处理也是关键,比如熔断降级、请求编码、错误解码器等。需要提醒用户添加必要的依赖,如spring-cloud-starter-openfeign,以及可能的Hystrix支持,如果用到熔断的话。 还要考虑用户可能遇到的常见问题,比如FeignClient无法注入,接口未正确实现,配置参数错误等。在回答中应该包含这些问题的解决方法,或者至少提到如何调试排查这些问题。 另外,用户可能对FeignClient的高级用法感兴趣,比如拦截器、自定义配置类、继承父接口等。需要简要介绍这些内容,但保持重点在基本使用上,避免信息过载。 最后,确保回答结构清晰,分步骤说明,让用户能够一步步跟着操作。同时,使用中文,避免术语混淆,保持口语化,但不过于随意,保持专业性。</think>### **Spring Boot 2.7 中 FeignClient 使用详解** --- #### **一、环境准备** 1. **依赖配置** 在 `pom.xml` 中添加 OpenFeign 核心依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.3</version> <!-- Spring Boot 2.7 对应版本 --> </dependency> ``` 2. **启动类注解** 添加 `@EnableFeignClients` 激活 Feign: ```java @SpringBootApplication @EnableFeignClients(basePackages = "com.example.feign") // 指定扫描包 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` --- #### **二、基础使用** ##### **1. 定义接口** ```java @FeignClient( name = "userService", // 服务标识(必填) url = "http://localhost:8080", // 直接指定URL(测试用) configuration = FeignConfig.class, // 自定义配置类 fallback = UserServiceFallback.class // 熔断降级类 ) public interface UserFeignClient { @GetMapping("/users/{id}") // 与目标服务接口一致 User getUser(@PathVariable("id") Long id); @PostMapping("/users") User createUser(@RequestBody User user); } ``` ##### **2. 熔断降级实现** ```java @Component public class UserServiceFallback implements UserFeignClient { @Override public User getUser(Long id) { return new User(-1L, "fallback-user"); // 默认返回值 } @Override public User createUser(User user) { throw new ServiceUnavailableException("服务不可用"); } } ``` --- #### **三、关键配置参数** 在 `application.yml` 中配置: ```yaml feign: client: config: default: # 全局默认配置 connectTimeout: 5000 # 连接超时(ms) readTimeout: 10000 # 读取超时(ms) loggerLevel: basic # 日志级别(none/basic/headers/full) userService: # 针对特定服务的配置 readTimeout: 30000 compression: request: enabled: true # 开启请求压缩 mime-types: text/xml,application/xml,application/json min-request-size: 2048 # 最小压缩阈值 ``` --- #### **四、高级功能** ##### **1. 自定义拦截器** ```java public class AuthInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header("Authorization", "Bearer " + getToken()); } } // 在配置类中注册 @Configuration public class FeignConfig { @Bean public AuthInterceptor authInterceptor() { return new AuthInterceptor(); } } ``` ##### **2. 继承式接口定义** ```java // 公共接口 public interface BaseUserApi { @GetMapping("/users/{id}") User getUser(@PathVariable("id") Long id); } // Feign客户端继承 @FeignClient(name = "userService", url = "${feign.client.userService.url}") public interface UserFeignClient extends BaseUserApi { // 可扩展其他方法 } ``` --- #### **五、常见问题解决** | **问题现象** | **解决方案** | |----------------------------------|-----------------------------------------------------------------------------| | 服务发现失败 (No instances available) | 检查是否添加 `spring-cloud-starter-loadbalancer` 依赖 | | 返回数据反序列化失败 | 确保DTO类有无参构造函数,字段类型与JSON匹配 | | 文件上传失败 | 使用 `@RequestPart` 注解并配置编码器: ```java @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) void upload(@RequestPart("file") MultipartFile file); ``` --- #### **六、性能优化建议** 1. **连接池配置** 替换默认HTTP客户端为 Apache HttpClient: ```xml <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> ``` 配置连接池参数: ```yaml httpclient: max-connections: 200 # 最大连接数 max-connections-per-route: 50 # 单路由最大连接数 ``` 2. **响应缓存** 在 Feign 接口方法添加 Spring Cache 注解: ```java @Cacheable(value = "users", key = "#id") @GetMapping("/users/{id}") User getUser(@PathVariable("id") Long id); ``` --- #### **七、调试技巧** 1. **日志追踪** 开启完整日志: ```yaml logging: level: org.springframework.cloud.openfeign: DEBUG ``` 2. **请求响应查看** 在拦截器中打印请求信息: ```java template.header("X-Request-ID", UUID.randomUUID().toString()); System.out.println("Feign Request: " + template.toString()); ``` --- ### **核心总结** 1. **版本匹配**:Spring Boot 2.7 对应 Spring Cloud 2021.0.x,需确保依赖版本一致 2. **熔断必配**:生产环境必须实现 `fallback` 或 `fallbackFactory` 3. **性能优先**:推荐使用连接池替代默认实现,提升吞吐量 4. **契约模式**:可通过 `contract` 属性切换为原生Feign契约(需谨慎使用)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

工作这么多年,学会了内卷

共同加油,继续努力!

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

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

打赏作者

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

抵扣说明:

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

余额充值