-
Notifications
You must be signed in to change notification settings - Fork 38.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve tests and Javadoc on binding to a property of type javax.servlet.Part #27830
Improve tests and Javadoc on binding to a property of type javax.servlet.Part #27830
Conversation
@binchoo Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@binchoo Thank you for signing the Contributor License Agreement! |
In the description, you refer to scenario 7 from #15220, but that issue and those scenarios specifically were addressed with PR #370. There is a test class WebRequestDataBinderIntegrationTests for those scenarios. I'm wondering what is the difference between that and what you're running into? |
@rstoyanchev, thanks for your review and comment. Scenario 7 doesn't seem to work, specifically, when testing the controller with Please view a failing mockMVC test below. @Test
public void multipartRequestWithServletPartsForPartAttribute() throws Exception {
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8);
MockPart filePart = new MockPart("file", "orig", fileContent);
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8);
MockPart jsonPart = new MockPart("json", json);
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON);
standaloneSetup(new MultipartController()).build()
.perform(multipart("/partattr").part(filePart).part(jsonPart))
.andExpect(status().isFound()) // expect: 302, actual: 400
.andExpect(model().attribute("fileContent", fileContent))
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah")));
}
@Controller
private static class MultipartController {
@RequestMapping(value = "/partattr")
public String processPartAttribute(PartForm form,
@RequestPart(required = false) Map<String, String> json, Model model) throws IOException {
if (form != null) {
Part part = form.getFile();
if (0 != part.getSize()) {
byte[] fileContent = StreamUtils.copyToByteArray(part.getInputStream());
model.addAttribute("fileContent", fileContent);
}
}
if (json != null) {
model.addAttribute("jsonContent", json);
}
return "redirect:/index";
}
}
private static class PartForm {
private Part file;
public PartForm(Part file) {
this.file = file;
}
public Part getFile() {
return file;
}
} Due to type conversion issue described in #27830 (comment), Lines 145 to 160 in a1b2262
|
Thanks for elaborating. We do support |
@rstoyanchev As I reviewed,
when a request is a
So I concluded that
Yes I could test this by registering a multipart resolver that purposely returns false in @Bean
MyMultipartResolver multipartResolver() {
return new MyMultipartResolver();
}
class MyMultipartResolver extends StandardServletMultipartResolver {
@Override
public boolean isMultipart(HttpServletRequest request) {
return false;
}
} |
7919996 Added tests covering these behaviors.
|
Thanks for the updates. I'll process this. Note that if you're in Boot application you can use |
When a controller obtains files from multipart requests,
there is an inconsistency when
jakarta.servlet.http.Part
type is an attribute of an object or an argument of a handler method.If a method has an object argument, and expects files to be saved to attributes of that argument, the attribute type should not be
Part
, but it would rather beMultipartFile
.This is because
StandardMultipartHttpServletRequest
wraps itsPart
s, whose filename exists, withStandardMultipartFile
.StandardMultipartFile
is an private class that implementsMultipartFile
class. SoPart
type attributes generate conversion errors.In contrast, if the method has an argument type of
Part
, it can normally receive multipart files from the framework.My idea is simply modifying
StandardMultipartFile
class to implement bothMultipartFile
andPart
, so preventing conversion issues. Likewise I added newMockStandardMultipartFile
class that replacesMockMultipartFile
class.Issues: #27819