简体   繁体   中英

Why @ModelAttribute does not work like @RequestBody?

My goal is to set a POJO attribute with form-data . I have a generic POJO, and when I use JSON it works as expected, so I am not sure form-data behave differently.

eg

The POJO

public class Account_Info {
  @JsonProperty("name")
  private String firstName;

  public String getFirstName() {
    return firstName;
  }
}

I wish to send a form data with "name" as key.

let formData = new FormData();

formData.append("name", "a");

My expected result is: The POJO's attribute of firstName will have a value of a .

My actual result is: The POJO's attribute of firstName is null.

What I did:

  1. I created a Account_InfoDto.
public class Account_InfoDto {
  @JsonProperty("name")
  private String firstName;

  public String getFirstName() {
    return firstName;
  }
}
  1. I created a controller

with @RequestBody

  @PostMapping(value = "/account_info")
  public Account_InfoDto postAccount_Info(@RequestBody Account_InfoDto account_info) {
    return account_info;
  }

with @ModelAttribute

  @PostMapping(value = "/account_info", consumes = "multipart/form-data")
  public Account_InfoDto postAccount_Info(@ModelAttribute Account_InfoDto account_info) {
    return account_info;
  }
  1. Send a request to POST /account_info

with JSON

{
  "name": "a"
}

The actual response is:

{
  "name": "a"
}

with form-data

let formData = new FormData();

formData.append("name", "a");

The actual result is:

{
  "name": null
}

@ModelAttribute is used with view templates such as thymeleaf, and @RequestBody is used when you expect json payload, @JsonProperty is for mapping, it is not needed for formdata. Since you are using formdata via ajax, you do not need any annotation on your payload. the following code

@PostMapping(value = "/account_info")
public Account_InfoDto postAccount_Info(@RequestBody Account_InfoDto account_info) {
return account_info;
}

should be

@PostMapping(value = "/account_info")
public Account_InfoDto postAccount_Info(Account_InfoDto account_info) {
return account_info;
}

also your request should be

let formData = new FormData();

formData.append("firstName", "a");

for your DTO also include setters and getters

public class Account_InfoDto {
@JsonProperty("name")
private String firstName;

public String getFirstName() {
   return firstName;
 }
public void setFirstName(String firstName) {
   this.firstName=firstName;
 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM