I am upgrading spring-boot-starter-parent
from version 2.5.3
to 3.0.0
I was using the org.springframework.web.multipart.commons.CommonsMultipartResolver;
(extending it) for my file upload needs
However in the new version CommonsMultipartResolver
is no longer supported.
I need help to figure out what I can use as an alternate.
Example of code:
public class MyMultipartResolver extends CommonsMultipartResolver {
private boolean resolveLazily = false;
private String supportedMimeTypes;
@Autowired
private SessionService sessionService;
@Autowired
private UserFileUploadEventService userFileUploadEventService;
@Value("${file.supportedMimeTypes}")
public void setSupportedMimeTypes(String value) {
supportedMimeTypes = value;
}
@Value("${upload.document.max.file.size}")
private int maxFileSize;
@Value("${scep.executable.path}")
private String scepExePath;
@Value("${upload.document.directory}")
private String uploadedDocumentPath;
public TamsMultipartResolver() {
super();
}
@Override
public void setResolveLazily(boolean resolveLazily) {
this.resolveLazily = resolveLazily;
}
@Override
public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
Assert.notNull(request, "Request must not be null");
if (this.resolveLazily) {
return new DefaultMultipartHttpServletRequest(request) {
@Override
protected void initializeMultipart() {
MultipartParsingResult parsingResult = parseRequest(request);
validateAttachment(parsingResult.getMultipartFiles().getFirst("file"));
setMultipartFiles(parsingResult.getMultipartFiles());
setMultipartParameters(getSanitizedMultipartparameters(parsingResult));
}
};
} else {
MultipartParsingResult parsingResult = parseRequest(request);
validateAttachment(parsingResult.getMultipartFiles().getFirst("file"));
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(), getSanitizedMultipartparameters(parsingResult),
parsingResult.getMultipartParameterContentTypes());
}
}
private Map<String, String[]> getSanitizedMultipartparameters(MultipartParsingResult parsingResult) {
Map<String, String[]> mpParams = parsingResult.getMultipartParameters();
if (mpParams != null) {
HashMap<String, String[]> encodedParams = new HashMap<String, String[]>();
for (String key : mpParams.keySet()) {
encodedParams.put(key, AntiSamyHelper.sanitizeXSS(mpParams.get(key)));
}
return encodedParams;
}
return mpParams;
}
public void validateAttachment(MultipartFile file) throws BadRequestException {
final int fileSize = new Long(file.getSize()).intValue();
final String simpleFileName = file.getOriginalFilename();
if (simpleFileName.length() > 0) {
if (isFrequecyAttack()) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_FREQUENCY_VIOLATION);
}
if (!isValidMimeType(file)) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_TYPE);
}
if (fileSize > maxFileSize) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_SIZE);
}
if (containsThreat(file)) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_MALICIOUS_FILE_DETECTED);
}
} else {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_TYPE);
}
}
I was able to use the library mentioned here: github.com/spring-projects/spring-framework/issues/29562
Here is the equivalent code from the question:
public class MyMultipartResolver extends StandardServletMultipartResolver {
private boolean resolveLazily = false;
private String supportedMimeTypes;
@Autowired
private SessionService sessionService;
@Autowired
private UserFileUploadEventService userFileUploadEventService;
@Value("${file.supportedMimeTypes}")
public void setSupportedMimeTypes(String value) {
supportedMimeTypes = value;
}
@Value("${upload.document.max.file.size}")
private int maxFileSize;
@Value("${scep.executable.path}")
private String scepExePath;
@Value("${upload.document.directory}")
private String uploadedDocumentPath;
public TamsMultipartResolver() {
super();
}
@Override
public void setResolveLazily(boolean resolveLazily) {
this.resolveLazily = resolveLazily;
}
/*
* (non-Javadoc)
* @see org.springframework.web.multipart.commons.CommonsMultipartResolver#resolveMultipart(javax.servlet.http.HttpServletRequest)
*/
@Override
public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
Assert.notNull(request, "Request must not be null");
if (this.resolveLazily) {
return new DefaultMultipartHttpServletRequest(request) {
@Override
protected void initializeMultipart() {
MultipartHttpServletRequest parsingResult = resolveMultipart(request);
validateAttachment(Objects.requireNonNull(parsingResult.getFile("file")));
setMultipartFiles(parsingResult.getMultiFileMap());
setMultipartParameters(getSanitizedMultipartparameters(parsingResult.getParameterMap()));
}
};
} else {
MultipartHttpServletRequest parsingResult = resolveMultipart(request);
validateAttachment(Objects.requireNonNull(parsingResult.getFile("file")));
/*Map<String, String> newMap = parsingResult.getFileMap().entrySet()
.stream()
.collect(HashMap::new, (map, entry) -> {
map.put(entry.getKey(), entry.getValue().getContentType());
}, HashMap::putAll);*/
Map<String, String> mpParamContentTypes = new HashMap<>();
for (Map.Entry<String, MultipartFile> entry : parsingResult.getFileMap().entrySet()) {
String key = entry.getKey();
MultipartFile value = entry.getValue();
String contentType = value.getContentType();
mpParamContentTypes.put(key, contentType);
}
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultiFileMap(), getSanitizedMultipartparameters(parsingResult.getParameterMap()),
mpParamContentTypes);
}
}
private Map<String, String[]> getSanitizedMultipartparameters(Map<String, String[]> mpParams) {
if (mpParams != null) {
HashMap<String, String[]> encodedParams = new HashMap<String, String[]>();
for (String key : mpParams.keySet()) {
encodedParams.put(key, AntiSamyHelper.sanitizeXSS(mpParams.get(key)));
}
return encodedParams;
}
return null;
}
public void validateAttachment(MultipartFile file) throws BadRequestException {
final int fileSize = new Long(file.getSize()).intValue();
final String simpleFileName = file.getOriginalFilename();
if (simpleFileName.length() > 0) {
if (isFrequecyAttack()) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_FREQUENCY_VIOLATION);
}
if (!isValidMimeType(file)) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_TYPE);
}
if (fileSize > maxFileSize) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_SIZE);
}
if (containsThreat(file)) {
throw new BadRequestException(RestConstants.FILE_UPLOAD_MALICIOUS_FILE_DETECTED);
}
} else {
throw new BadRequestException(RestConstants.FILE_UPLOAD_INVALID_FILE_TYPE);
}
}