![](/img/trans.png)
[英]Spring POST multipart/form-data, request parts always empty
[英]Spring cannot process “multipart/form-data” POST request (error 400 “Bad request”)
当我向此服务器代码发布请求时-一切正常:
@RequestMapping(method = RequestMethod.POST, consumes = { "application/json" })
public ResponseEntity<String> addQuestion(@RequestBody String dtoObject) { ... }
但是,如果我将请求更改为“ multipart / form-data”,则Spring返回错误400“ Bad request”:
@RequestMapping(method = RequestMethod.POST, consumes = { "multipart/form-data" })
public ResponseEntity<String> addQuestion(@RequestBody String dtoObject) { ... }
为什么? 可能我应该创建一些额外的bean?
PS:我需要“ multipart / form-data”与json对象一起发送文件。
我认为您无法将文件反序列化到请求正文中的dtoObject。 您将需要使用@RequestPart来执行此操作。
@RequestMapping(method = RequestMethod.POST, consumes = { "multipart/form-data" })
public ResponseEntity<String> addQuestion2(@RequestPart("question") QuestionPostDto dtoObject, @RequestPart("file") MultiPartFile file) { ... }
您的请求必须是formdata:要上传的文件和json格式的文件question.json
这是我邮递员的有效载荷示例
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="QLbLFIR.gif"
Content-Type: image/gif
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="question"; filename="question.json"
Content-Type: application/json
------WebKitFormBoundary7MA4YWxkTrZu0gW--
或者如果您不想传递json格式的文件,则可以使用普通字符串传递它
@RequestMapping(method = RequestMethod.POST, consumes = { "multipart/form-data" })
public ResponseEntity<String> addQuestion2(String question, @RequestPart("file") MultiPartFile file) {
QuestionPostDto dtoObject = new ObjectMapper().readValue(request, QuestionPostDto.class);
// do sth
}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="QLbLFIR.gif"
Content-Type: image/gif
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="request"
{
"key": "value"
}
------WebKitFormBoundary7MA4YWxkTrZu0gW--
请参阅此线程以获取更多详细信息: 带有JSON的Spring MVC多重请求
我解决了这个问题。
1)我创建了HttpMessageConverter,将json转换为我的自定义类型QuestionPostDto:
public class QuestionPostDtoHttpMessageConverter implements HttpMessageConverter<QuestionPostDto> {
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return QuestionPostDto.class == clazz;
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return QuestionPostDto.class == clazz;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
List<MediaType> list = new ArrayList<MediaType>();
list.add(MediaType.MULTIPART_FORM_DATA);
return list;
}
@Override
public QuestionPostDto read(Class<? extends QuestionPostDto> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
InputStream istream = inputMessage.getBody();
String requestString = IOUtils.toString(istream, "UTF-8");
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(requestString, QuestionPostDto.class);
}
@Override
public void write(QuestionPostDto t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
}
}
2)我为此类型的HttpMessageConverter创建bean(我们在项目中使用Spring Boot):
@Configuration
public class HttpConfiguration {
...
@Bean
public QuestionPostDtoHttpMessageConverter commonsMultipartResolver() {
return new QuestionPostDtoHttpMessageConverter();
}
}
3)现在我在RestController中的代码可以正常工作:
@RestController
@RequestMapping("/api/question")
@ConfigurationProperties(prefix = "question")
@RequiredArgsConstructor
@Slf4j
public class QuestionController {
...
@PostMapping
ResponseEntity<String> addQuestion(@RequestPart("dtoObject") QuestionPostDto dtoObject, @RequestPart("file") MultipartFile file) { ... }
感谢大家,尤其是Chi Dov
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.