question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Expose multipart data in ServerRequest

See original GitHub issue

We are currently developing a Spring MVC environment using functional routing like this:

router {
    POST("/user-photo/", userImageHandler::create)
}

@Component("user.Image")
class UserImageHandler : PassHandler() {
   
    fun create(serverRequest: ServerRequest) = success {
        val multipartRequest = (serverRequest.servletRequest() as? MultipartHttpServletRequest) ?:
             throw ResponseStatusException(
                 HttpStatus.NOT_ACCEPTABLE,
                 "Request is not a multipart request"
              )
        val file: MultipartFile = multipartRequest.getFile("file") ?: throw ResponseStatusException(
             HttpStatus.NOT_ACCEPTABLE,
             "Missing file with name: file"
        )
     ....
    }
}

The ServerRequest is the https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/function/ServerRequest.html interface. The only way to access files seem to be the casting method we do right now - serverRequest.servletRequest().parts is empty.

This is the integration test:

        val file = MockMultipartFile(
            "blank.jpg",
            "blank.jpg",
            "image/jpg",
            getImageBytes()
        )

        mockMvc.perform(
            MockMvcRequestBuilders.multipart("/user-photo/")
                .file(file)
                .accept(MediaType.APPLICATION_JSON)
        ).andExpect(
            MockMvcResultMatchers.status().isOk
        )

In the integration test the serverRequest.servletRequest part is of type SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@71f08480] and thus not a decendant of MultipartHttpServletRequest.

Is there a smarter way to access multipart files with the ServerRequest interface? Otherwise I would think that HttpServletRequest is missing a getFiles() method.

I found an way to access multipart files but it’s a few levels deep and would require a lot of casting: image

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
poutsmacommented, Apr 22, 2020

As it turned out, the solution was to use part (and MockPart) on the builder, instead of file. MultipartFile is a Spring abstraction introduced before Servlet offered Part. As such, the HttpServletRequest does not “know” about MultipartFile objects, only Part.

This test works for me:

@Test
fun `test create`(): Unit = runBlocking {
    val part = MockPart(
        "blank.jpg",
        "blank.jpg",
        getImageBytes()
    )

    mockMvc.perform(
        MockMvcRequestBuilders.multipart("/user-photo/")
            .part(part)
            .accept(MediaType.APPLICATION_JSON)
    ).andExpect(
        MockMvcResultMatchers.status().isOk
    )
    Unit
}

Though your initial problem is fixed, I am going to keep this issue around as a feature request to expose multipart data on WebMvn.fn’s ServerRequest directly, without resorting to HttpServletRequest.

0reactions
jonasbarkcommented, Apr 21, 2020

I tested it with a real API request as well and it works. But what I’m really trying to achieve here is to get the integration test to run with MockMvc. I posted the integration test content in the initial post.

image

 @Test
    fun `test create`(): Unit = runBlocking {
        val file = MockMultipartFile(
            "blank.jpg",
            "blank.jpg",
            "image/jpg",
            getImageBytes()
        )

        mockMvc.perform(
            MockMvcRequestBuilders.multipart("/user-photo/")
                .file(file)
                .accept(MediaType.APPLICATION_JSON)
        ).andExpect(
            MockMvcResultMatchers.status().isOk
        )
        Unit
    }

I created a fairly minimal repo here: https://github.com/jonasbark/spring-framework-24909

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring webflux proxy multipart data - java - Stack Overflow
I am proxying multipart data not as Part which MultipartHttpReader created, but as ByteArray . val builder = MultipartBodyBuilder() multipart .
Read more >
Reactive Spring: Webflux Multipart File Upload
A clear, simple example of multipart file upload using Reactive Spring Spring ... fun upload(request: ServerRequest): Mono<ServerResponse> {.
Read more >
Web on Reactive Stack - Spring
Multipart Data. Web MVC. ServerWebExchange exposes the following method for accessing multipart data: Java. Kotlin.
Read more >
Decode "multipart/form-data" with WebDev - Ignition
It uses “multipart/form-data” content type, and I am having difficulties figuring ... line 4, in doPost at org.eclipse.jetty.server.Request.
Read more >
Writing REST Services with RESTEasy Reactive - Quarkus
Each exposed endpoint method can in turn have another @Path ... Similarly, RESTEasy Reactive can produce Multipart Form data to allow users ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found