What is the alternate to org.springframework.web.multipart.MultipartResolver;

1.7k Views Asked by At

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

  • setting sizes of max uploads.
  • Getting file params
  • validating attachments etc

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);
        }
    }
1

There are 1 best solutions below

1
On BEST ANSWER

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);
    }
}