Reputation: 2534
I am trying to upload a file using 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){
With this definition, I tried this Postman request:
This doesn't work.
I tried adding this to my RequestMapping
:
@RequestMapping(value = "/register", method = RequestMethod.POST, consumes = "multipart/form-data")
This gives me the same error.
For userInfo
, I am sending the values as JSON in form-data fields itself as suggested by another SO answer. Doesn't work, same error.
As suggested in some other SO answers, I also made sure that I wasn't sending any headers in Postman.
I tried adding the following property in application.properties
as well:
spring.http.multipart.enabled=false
Same error. I also tried MultipartFile
instead of CommonsMultipartFile
, no difference at all.
What am I doing wrong? I want to send an image as a File and UserInfo
object in the request as well. Postman examples will be really appreciated.
Upvotes: 4
Views: 6611
Reputation: 267
I done by adding the Multiple part file in DTO-Bean and adding each field in postman as string. spring boot will match the file and assign the value see the below example
This is my Account Bean for accept the request from the postman
// done test 100%
@JsonPropertyOrder({ "email", "password", "file" })
public class AccountBean {
@ApiModelProperty(notes = "Enter Email", name = "email", value = "[email protected]", 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 Input
https://github.com/NABEEL-AHMED-JAMIL/fserver project for example
Upvotes: 0
Reputation: 1128
Multipart form data with custom object will be accepted as string. so your controller would be like as follows.
@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);
}
you will have to convert String to pojo by using ObjectMapper. Hope this will help.
Upvotes: 2