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の設定でできるのあったら教えてほしいです。
おわり。