Merge MultipartFileArgumentResolver into RequestPartArgumentResolver

Also add test with Optional parameter for a RequestPart argument.

See gh-31164

Signed-off-by: Dmitrii Bocharov <bdshadow@gmail.com>
This commit is contained in:
Dmitrii Bocharov
2023-09-03 20:43:26 +02:00
committed by rstoyanchev
parent f83c609436
commit fe8e6d3d5a
5 changed files with 97 additions and 164 deletions

View File

@@ -274,7 +274,6 @@ public final class HttpServiceProxyFactory {
// Specific type
resolvers.add(new UrlArgumentResolver());
resolvers.add(new HttpMethodArgumentResolver());
resolvers.add(new MultipartFileArgumentResolver());
return resolvers;
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.service.invoker;
import java.util.Optional;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
/**
* {@link HttpServiceArgumentResolver} for arguments of type {@link MultipartFile}.
* The argument is recognized by type, and does not need to be annotated. To make
* it optional, declare the parameter with an {@link Optional} wrapper.
*
* @author Olga Maciaszek-Sharma
* @author Rossen Stoyanchev
* @since 6.1
*/
public class MultipartFileArgumentResolver extends AbstractNamedValueArgumentResolver {
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
Class<?> type = parameter.nestedIfOptional().getNestedParameterType();
return (type.equals(MultipartFile.class) ?
new NamedValueInfo("", true, null, "MultipartFile", true) : null);
}
@Override
protected void addRequestValue(
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder values) {
Assert.state(value instanceof MultipartFile, "Expected MultipartFile value");
MultipartFile file = (MultipartFile) value;
HttpHeaders headers = new HttpHeaders();
if (file.getOriginalFilename() != null) {
headers.setContentDispositionFormData(name, file.getOriginalFilename());
}
if (file.getContentType() != null) {
headers.add(HttpHeaders.CONTENT_TYPE, file.getContentType());
}
values.addRequestPart(name, new HttpEntity<>(file.getResource(), headers));
}
}

View File

@@ -23,11 +23,13 @@ import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.codec.multipart.Part;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
/**
* {@link HttpServiceArgumentResolver} for {@link RequestPart @RequestPart}
@@ -77,8 +79,18 @@ public class RequestPartArgumentResolver extends AbstractNamedValueArgumentResol
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
RequestPart annot = parameter.getParameterAnnotation(RequestPart.class);
return (annot == null ? null :
new NamedValueInfo(annot.name(), annot.required(), null, "request part", true));
boolean isMultiPartFile = parameter.nestedIfOptional().getNestedParameterType().equals(MultipartFile.class);
if (annot != null && isMultiPartFile) {
return new NamedValueInfo(annot.name(), annot.required(), null, "MultipartFile", true);
}
else if (annot != null) {
return new NamedValueInfo(annot.name(), annot.required(), null, "request part", true);
}
else if (isMultiPartFile) {
return new NamedValueInfo("", true, null, "MultipartFile", true);
}
return null;
}
@Override
@@ -106,6 +118,18 @@ public class RequestPartArgumentResolver extends AbstractNamedValueArgumentResol
return;
}
}
if (value instanceof MultipartFile file) {
HttpHeaders headers = new HttpHeaders();
if (file.getOriginalFilename() != null) {
headers.setContentDispositionFormData(name, file.getOriginalFilename());
}
if (file.getContentType() != null) {
headers.add(HttpHeaders.CONTENT_TYPE, file.getContentType());
}
requestValues.addRequestPart(name, new HttpEntity<>(file.getResource(), headers));
return;
}
requestValues.addRequestPart(name, value);
}