java - Convert HttpServletRequest into a MultipartHttpServletRequest - Stack Overflow

admin2025-04-18  3

I started studying Java a little bit ago and i'm working on a web-api using Spring Boot. I want to log all request by using a filter that saves the logs into the database.

It's for a school project but the idea is that it's suppossed to be like google drive or dropbox. You can create maps and put files in the maps, you can also put maps inside maps. But when i try to log when a user uploads a file i need the filter to recognize the requestbody as a multipartfile so i can change the content so the log doesn't upload the actual content of the file, rather than some info about the file. This is my filter.

@Component
@RequiredArgsConstructor
public class ActivityLogFilter extends OncePerRequestFilter {



    private final ActivityLogRepository activityLogRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
        

        filterChain.doFilter(wrappedRequest, wrappedResponse);

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = (authentication != null && authentication.isAuthenticated()) ? authentication.getName() : "Anonymous";
        String method = request.getMethod();
        String endpoint = request.getRequestURI();
        int statusCode = response.getStatus();

        String requestBody = processRequestBody(wrappedRequest);
        String responseBody = processResponseBody(wrappedResponse);
        ActivityLog log = new ActivityLog();
        log.setUsername(username);
        log.setMethod(method);
        log.setEndpoint(endpoint);
        log.setStatusCode(statusCode);
        //log.setRequestBody(requestBody);
        //log.setResponseBody(responseBody);
        activityLogRepository.save(log);

        wrappedResponse.copyBodyToResponse();
    }

    private String processRequestBody(HttpServletRequest request) {
        ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
        byte[] buf = wrapper.getContentAsByteArray();
        String body = (buf.length > 0) ? new String(buf, StandardCharsets.UTF_8) : "";
        return maskSensitiveData(body);
    }

    private String processResponseBody(ContentCachingResponseWrapper response) {
        byte[] buf = response.getContentAsByteArray();
        return (buf.length > 0) ? new String(buf, StandardCharsets.UTF_8) : "";
    }

    private String maskSensitiveData(String requestBody) {
        if (requestBody.contains("password")) {
            requestBody = requestBody.replaceAll("\"password\":\"[^\"]+\"", "\"password\":\"****\"");
        }
        if (requestBody.contains("token")) {
            requestBody = requestBody.replaceAll("\"token\":\"[^\"]+\"", "\"token\":\"****\"");
        }
        return requestBody;
    }
}

This code currently isn't trying to cnvert the request because i never got it to work but how can i convert the HttpServletRequest into a MultipartHttpServletRequest? When i try to cast it, it casts an exception saying

class org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper cannot be cast to class org.springframework.web.multipart.MultipartHttpServletRequest (org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper and org.springframework.web.multipart.MultipartHttpServletRequest are in unnamed module of loader 'app').

I also tried

if (request instanceof MultipartHttpServletRequest multipartRequest) {
        return extractFileMetadata(multipartRequest);
}

But that doesn't work either. Anyone know how i can fix this issue?

Tried casting the request to a MultipartHttpServletRequest so i can extract the file content but got an exception instead.

I started studying Java a little bit ago and i'm working on a web-api using Spring Boot. I want to log all request by using a filter that saves the logs into the database.

It's for a school project but the idea is that it's suppossed to be like google drive or dropbox. You can create maps and put files in the maps, you can also put maps inside maps. But when i try to log when a user uploads a file i need the filter to recognize the requestbody as a multipartfile so i can change the content so the log doesn't upload the actual content of the file, rather than some info about the file. This is my filter.

@Component
@RequiredArgsConstructor
public class ActivityLogFilter extends OncePerRequestFilter {



    private final ActivityLogRepository activityLogRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
        

        filterChain.doFilter(wrappedRequest, wrappedResponse);

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = (authentication != null && authentication.isAuthenticated()) ? authentication.getName() : "Anonymous";
        String method = request.getMethod();
        String endpoint = request.getRequestURI();
        int statusCode = response.getStatus();

        String requestBody = processRequestBody(wrappedRequest);
        String responseBody = processResponseBody(wrappedResponse);
        ActivityLog log = new ActivityLog();
        log.setUsername(username);
        log.setMethod(method);
        log.setEndpoint(endpoint);
        log.setStatusCode(statusCode);
        //log.setRequestBody(requestBody);
        //log.setResponseBody(responseBody);
        activityLogRepository.save(log);

        wrappedResponse.copyBodyToResponse();
    }

    private String processRequestBody(HttpServletRequest request) {
        ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
        byte[] buf = wrapper.getContentAsByteArray();
        String body = (buf.length > 0) ? new String(buf, StandardCharsets.UTF_8) : "";
        return maskSensitiveData(body);
    }

    private String processResponseBody(ContentCachingResponseWrapper response) {
        byte[] buf = response.getContentAsByteArray();
        return (buf.length > 0) ? new String(buf, StandardCharsets.UTF_8) : "";
    }

    private String maskSensitiveData(String requestBody) {
        if (requestBody.contains("password")) {
            requestBody = requestBody.replaceAll("\"password\":\"[^\"]+\"", "\"password\":\"****\"");
        }
        if (requestBody.contains("token")) {
            requestBody = requestBody.replaceAll("\"token\":\"[^\"]+\"", "\"token\":\"****\"");
        }
        return requestBody;
    }
}

This code currently isn't trying to cnvert the request because i never got it to work but how can i convert the HttpServletRequest into a MultipartHttpServletRequest? When i try to cast it, it casts an exception saying

class org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper cannot be cast to class org.springframework.web.multipart.MultipartHttpServletRequest (org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper and org.springframework.web.multipart.MultipartHttpServletRequest are in unnamed module of loader 'app').

I also tried

if (request instanceof MultipartHttpServletRequest multipartRequest) {
        return extractFileMetadata(multipartRequest);
}

But that doesn't work either. Anyone know how i can fix this issue?

Tried casting the request to a MultipartHttpServletRequest so i can extract the file content but got an exception instead.

Share Improve this question edited Jan 30 at 18:43 zarruq 2,4652 gold badges11 silver badges20 bronze badges asked Jan 30 at 16:21 Basti797Basti797 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

It's really not clear what you want to achieve OR what your actual problem is, but if you just want to get the parts, you don't need to cast it.

You can use below.

Collection<Parts> parts = request.getParts();

OR as a List:

List<Part> partsList = request.getParts().stream.toList();

You can then inspect List to look for your desired data

EXAMPLE: A post request Body has below parts in the same order as below. You can perform additional checks by calling getName() etc. as well:

  1. file: ${PATH_TO_A_FILE/FILE_NAME}
  2. metadata: ANY_STRING

In that case, partsList will have 2 items. If you want to get metadata, you can get the inputStream() as below

String metadata = new BufferedReader(new InputStreamReader(partsList.get(1)
                      .getInputStream()
                      .lines()
                      .collect(Collectors.joining("\n"));
转载请注明原文地址:http://anycun.com/QandA/1744906223a89294.html