簡體   English   中英

Spring無法處理“多部分/表單數據” POST請求(錯誤400“錯誤請求”)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM