内容类型' multipart / form-data; boundary = ----...; charset = UTF-8'不支持

时间:2018-01-01 16:07:40

标签: java spring rest spring-mvc spring-boot

我想将一个对象发送到控制器,该控制器有几个包含文件的列表和几个带有纯文本的字段。

public class ContributionNew<T extends MovieInfoDTO> {
    private List<T> elementsToAdd;
    private Map<Long, T> elementsToUpdate;
    private Set<Long> idsToDelete;
    private Set<String> sources;
    private String comment;
}

public class Photo extends MovieInfoDTO {
    private MultipartFile photo;
}

@PostMapping(value = "/{id}/contributions/photos")
@ResponseStatus(HttpStatus.CREATED)
public
ResponseEntity<Void> createPhotoContribution(
        @ApiParam(value = "The movie ID", required = true)
        @PathVariable("id") final Long id,
        @ApiParam(value = "The contribution", required = true)
        @RequestBody @Valid final ContributionNew<Photo> contribution
) {

我使用postman发送数据。然而,他抛弃了我

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundarywY7ByvgonAjDoaCT;charset=UTF-8' not supported

我应该为此控制器设置Content-type,以便发送包含纯文本字段和带文件列表的对象?

如果我在标题中设置标题

Content-type: multipart/form-data; charset=utf-8

它把我扔进了控制台

org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found

8 个答案:

答案 0 :(得分:8)

在postman中,你需要将body设置为raw类型,从下拉列表中你可以选择JSON,我有类似的问题,这解决了我的问题。view screen here

答案 1 :(得分:5)

dknight @RequestBody表示将JSON或XML数据与DTO bean映射一起使用。 如果是MultipartFile,则不能使用JSON数据,因此不能使用@RequestBody。 尝试使用@ModelAttribute批注。

工作示例:

@PostMapping("/promoters")
@Timed
public ResponseEntity<PromoterDTO> createPromoter(@ModelAttribute PromoterDTO promoterDTO) throws URISyntaxException { ... }

使用如下PromoterDTO:

    public class PromoterDTO implements Serializable {

        private Long id; 

        private String name;

        private String address;

        private MultipartFile logo;
    }

答案 2 :(得分:2)

使用@ModelAttribute而不是@ResponseBody,因为这会占用键值对中的数据,而后者则用于json之类的对象。 按下api时,只需传递对象的multipart类型和json键值对。很好!

stack overflow question on this

答案 3 :(得分:1)

import org.springframework.web.bind.annotation.ModelAttribute;

使用 @ModelAttribute 而不是 @RequestBody。它对我有用。

答案 4 :(得分:1)

produces = { "application/json" } 必须写在控制器中而不是consumes = { "application/json" }

答案 5 :(得分:0)

代替@RequestBody,使用@ModelAttribute之类的

@PostMapping(value = "/{id}/contributions/photos")
@ResponseStatus(HttpStatus.CREATED)
public
ResponseEntity<Void> createPhotoContribution(
        @ApiParam(value = "The movie ID", required = true)
        @PathVariable("id") final Long id,
        @ApiParam(value = "The contribution", required = true)
        @ModelAttribute @Valid final ContributionNew<Photo> contribution
) {

答案 6 :(得分:0)

这是使用 Spring Boot 2.1.7 用 Kotlin 编写的完整代码示例

示例使用了 ProfileRepository,您当然可以实现它。

Kotlin 很好,因为 data class 已经实现了可序列化。

请注意,您必须对模型对象属性使用 var 而不是 val,否则日志消息中的字段值将为空。

import org.springframework.web.bind.annotation.ModelAttribute
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile

@RestController
class ExampleController(private val myProfileRepository: ProfileRepository) {
    
    @PostMapping("/api/uploadFile")
    fun createProvider(@ModelAttribute request: CreateProfileRequest): Provider {
        println("received create request with photo: ${request.photo} for the following person ${request.name}")
        return myProfileRepository.save(Provider(name = request.name!!))
    }
}

data class CreateProfileRequest(
    var name: String? = null,
    var photo: MultipartFile? = null
)

答案 7 :(得分:-1)

使用@RequestParam代替@RequestBody !!!