LoginSignup
1
2

More than 5 years have passed since last update.

Spring BootでURLごとにファイルアップロードでのファイル最大サイズを制御したい

Posted at

1. やりたいこと

  • spring.servlet.multipart.max-file-size=1MBみたいなのをURL単位で制御する

2. バージョンや条件など

  • Java 12
  • Spring Boot 2.1.4.RELEASE

3. やったこと

  • 以下のようなIntercecptorを作成し、MultipartFile#sizeを判定する
MultipartFileInterceptor.java
public class MultipartFileInterceptor extends HandlerInterceptorAdapter {

    private final long maxFileSize;

    public MultipartFileInterceptor(long maxFileSize) {
        this.maxFileSize = maxFileSize;
    }

    public MultipartFileInterceptor(String maxFileSize) {
        this(ByteSizeUnit.toBytes(maxFileSize));
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        if (MultipartRequest.class.isInstance(request) && maxFileSize >= 0) {
            MultipartRequest multipartRequest = MultipartRequest.class.cast(request);

            multipartRequest.getFileMap()
                .values()
                .stream()
                .forEach(f -> {
                    if (f.getSize() > maxFileSize) {
                        throw new MaxUploadSizeExceededException(maxFileSize);
                    }
                });
        }

        return super.preHandle(request, response, handler);
    }
}
  • 以下のようなWebMvcConfigurerを作成して、Interceptorを制御したいURLに関連付ける
WebMvcConfig
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Value("${app.file.max-file-size:-1}")
    private String fileMaxFileSize;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MultipartFileInterceptor(fileMaxFileSize))
            .addPathPatterns("/file");
    }

}
  • この課題に直接関係はないが、以下のようなクラスを用意することでアプリケーションの設定に1MBのように定義することができるようにした
ByteSizeUnit.java
public enum ByteSizeUnit {

    KB {
        @Override
        long toBytes(long size) {
            return size * UNIT_SIZE;
        }
    },
    MB {
        @Override
        long toBytes(long size) {
            return size * UNIT_SIZE * UNIT_SIZE;
        }
    },
    GB {
        @Override
        long toBytes(long size) {
            return size * UNIT_SIZE * UNIT_SIZE * UNIT_SIZE;
        }
    };

    abstract long toBytes(long size);

    static final long UNIT_SIZE = 1024;

    public static long toBytes(String size) {
        if (Objects.isNull(size) || size.isEmpty()) {
            throw new IllegalArgumentException("size must not be empty");
        }

        for (ByteSizeUnit byteSizeUnit : values()) {
            if (size.toUpperCase().endsWith(byteSizeUnit.name())) {
                return byteSizeUnit.toBytes(Long.valueOf(size.substring(0, size.length() - byteSizeUnit.name().length())));
            }
        }

        return Long.valueOf(size);
    }

}

4. Example

Spring Bootの設定でできるのあったら教えてほしいです。
おわり。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2