Springboot文件上传 & 流量控制

53 阅读1分钟
  1. 引入依赖
<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

   <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
   </dependency>

   <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-core</artifactId>
      <version>1.8.5</version>
   </dependency>

   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
</dependencies>

2.上传接口

@RestController
@RequestMapping("/upload")
public class UploadController {

    static {
        // 初始化流控规则
        initFlowRules();
    }

    @Value("${upload.directory:/data/upload/}")
    private String uploadDirectory;

    @PostMapping
    public List<String> upload(@RequestParam("files") MultipartFile[] files){
        try(Entry entry = SphU.entry("HelloWorld")){
            List<String> fileUrls = Arrays.stream(files)
                    .filter(file -> file.getContentType().startsWith("image/")) // Filter only image files
                    .map(this::uploadFile)
                    .collect(Collectors.toList());
            return fileUrls;
        }catch (BlockException e){
            System.out.println(e);
            return new ArrayList<>();
        }
    }

    // 上传单个文件的方法
    private String uploadFile(MultipartFile file) {
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        try {
            // 检查文件名中是否包含无效字符
            if (fileName.contains("..") || !file.getContentType().startsWith("image/")) {
                throw new IllegalArgumentException("Invalid file name");
            }

            // TODO: 这里可以替换为实际的文件存储逻辑,比如存储到本地文件系统或云存储
            // 示例中使用了临时链接返回
            String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                    .path("/downloadFile/")
                    .path(fileName)
                    .toUriString();

            // 这里可以添加文件存储逻辑,比如保存到磁盘或数据库
            Path uploadPath = Paths.get(uploadDirectory);
            Path filePath = uploadPath.resolve(fileName).normalize();
            // 检查文件是否存在,如果存在则删除以便覆盖
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }
            Files.copy(file.getInputStream(), filePath);

            return fileDownloadUri;
        } catch (Exception ex) {
            throw new RuntimeException("Failed to store file " + fileName, ex);
        }
    }


    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}