在Spring Boot REST API中上传文件

4

我正在尝试使用Spring Boot @RestController上传文件:

    @RequestMapping(value = "/register", method = RequestMethod.POST)
public AppResponse registerUserFromApp(
        @RequestBody UserInfo userInfo,
        @RequestParam(value = "file", required = false) CommonsMultipartFile file,
        @RequestParam(value = "inviteCode", required = false) String inviteCode){

使用这个定义,我尝试了这个 Postman 请求:Register API,但是没有成功。
我尝试将这段代码添加到我的 RequestMapping 中:
@RequestMapping(value = "/register", method = RequestMethod.POST, consumes = "multipart/form-data")

这给我带来了同样的错误。
对于userInfo,我正在将值作为JSON发送到表单数据字段中,正如另一个SO回答建议的那样。但是不起作用,出现相同的错误。
如一些其他SO回答所建议的,我还确保在Postman中没有发送任何标题。
我也尝试在application.properties中添加以下属性:
spring.http.multipart.enabled=false

出现了相同的错误。我尝试使用MultipartFile而不是CommonsMultipartFile,但没有任何区别。

我错在哪里?我想同时在请求中发送一个图像文件和UserInfo对象。非常感谢提供Postman示例。

2个回答

2

支持自定义对象的多部分表单数据将被接受为字符串。因此,您的控制器应该如下所示。

@RequestMapping(value = "/register", method = RequestMethod.POST)
public AppResponse registerUserFromApp(
    @RequestBody String userInfo,
    @RequestParam(value = "file", required = false) CommonsMultipartFile file,
    @RequestParam(value = "inviteCode", required = false) String inviteCode){

    ObjectMapper obj=new ObjectMapper();
    UserInfo userInfo=obj.readValue(clientData, UserInfo.class);

}

您需要使用ObjectMapper将String转换为POJO。希望这会有所帮助。


否则请查看此链接 https://dev59.com/bGEi5IYBdhLWcg3wYLeT - Bhargav Patel

0

我通过在DTO-Bean中添加多部分文件并将每个字段作为字符串添加到Postman中来完成。Spring Boot将匹配文件并分配值,请参见下面的示例

这是我的账户Bean,用于接受来自Postman的请求

// done test 100%
@JsonPropertyOrder({ "email", "password", "file" })
public class AccountBean {

    @ApiModelProperty(notes = "Enter Email", name = "email", value = "nabeel.amd93@gmail.com", required = true)
    @NotNull(message = "Email contain null")
    @NotBlank(message = "Email Contain blank")
    @Email(message = "Email wrong type")
    private String email;

    @ApiModelProperty(notes = "Enter Password", name = "password", value = "ballistic", required = true)
    @NotNull(message = "Password contain null")
    @NotBlank(message = "Password contain blank")
    private String password;

    @ApiModelProperty(notes = "Enter file", name = "file", value = "xyz", required = true)
    @NotNull(message = "File contain null")
    @ValidImage(message = "File support type => \"image/jpeg\", \"image/png\", \"image/jpg\"")
    private MultipartFile file;

    public AccountBean() { }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }

    public MultipartFile getFile() { return file; }
    public void setFile(MultipartFile file) { this.file = file; }

    @Override
    public String toString() { return "AccountBean{" + "email='" + email + '\'' + ", password='" + password + '\'' + ", repository=" + file + '}'; }

}

Rest-Api
@ApiOperation(value = "File upload with object field", response = APIResponse.class)
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Success", response = String.class),
        @ApiResponse(code = 404, message = "Not Found")})
@RequestMapping(value = "/save/account/local", method = RequestMethod.POST)
public ResponseEntity<APIResponse<?>> saveAccountWithSingleFile(
        @ApiParam(name = "account", value = "Select File with Dto field", required = true)
        @Valid AccountBean accountBean, BindingResult bindingResult) throws IllegalBeanFieldException {
    long sTime = System.nanoTime();
    logger.info("save file with account process");
    if(bindingResult.hasErrors()) {
        AtomicInteger bind = new AtomicInteger();
        HashMap<String, HashMap<String, Object>> error = new HashMap<>();
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String key = "key-"+bind;
            HashMap<String, Object> value = new HashMap<>();
            value.put("objectName", fieldError.getObjectName());
            value.put("field", fieldError.getField() != null ? fieldError.getField() : "null");
            value.put("reject", fieldError.getRejectedValue() != null ? fieldError.getRejectedValue() : "null");
            value.put("message", fieldError.getDefaultMessage());
            error.put(key, value);
            bind.getAndIncrement();
        });
        throw new IllegalBeanFieldException(error.toString());
    }
    this.apiResponse = this.uploadFile(accountBean.getFile()).getBody();
    logger.debug("account file save time " + ((System.nanoTime() - sTime) / 1000000) + ".ms");

    if(this.apiResponse.getReturnCode().equals(HttpStatus.OK)) {
        // add-info to the account
        Account account = new Account();
        account.setEmail(accountBean.getEmail());
        account.setPassword(accountBean.getPassword());
        account.setFileInfo((FileInfo) this.apiResponse.getEntity());
        account = this.iAccountService.saveAccount(account);
        logger.info("account with file single file info save time :- " + ((System.nanoTime() - sTime) / 1000000) + ".ms");
        this.apiResponse = new APIResponse<Account>("File save with account", HttpStatus.OK, account);
        logger.info("account added " + this.apiResponse.toString());
        logger.info("total response time :- " + ((System.nanoTime() - sTime) / 1000000) + ".ms");
   }

    return new ResponseEntity<APIResponse<?>>(this.apiResponse, HttpStatus.OK);
}

PostMan 输入

enter image description here

https://github.com/NABEEL-AHMED-JAMIL/fserver是一个编程示例项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接