user962206
user962206

Reputation: 16117

Error 400 Spring Json @RequestBody when doing post

Here are the classes involve.

public class UserAuthDto {

    private String username;

    private String password;

    private List<String> roles;

    private String tenantCode;

    public UserAuthDto(String username,
                           String password,
                           List<String> roles,
                           String tenantCode){
        this.username=username;
        this.password=password;
        this.roles=roles;
        this.tenantCode=tenantCode;
    }

    public void setUsername(String username) {
        this.username = username;
    }

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

    public void setRoles(List<String> roles) {
        this.roles = roles;
    }

    public void setTenantCode(String tenantCode) {
        this.tenantCode = tenantCode;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public List<String> getRoles() {
        return roles;
    }

    public String getTenantCode() {
        return tenantCode;
    }
}

Another DTO

public class UserAuthRequest {

    private UserAuthDto userAuthDto;

    public UserAuthRequest(UserAuthDto authDto){
        if(authDto == null){
            throw new IllegalArgumentException("User Authentication DTO Should Not be null");
        }
        this.userAuthDto = authDto;
    }
    public String getUsername(){
        return userAuthDto.getUsername();
    }

    public String getPassword(){
        return userAuthDto.getPassword();
    }

    public List<String> getRoles(){
        return  userAuthDto.getRoles();
    }

    public String getTenantCode(){
        return  userAuthDto.getTenantCode();
    }

    public void setUsername(String username) {
        this.userAuthDto.setUsername(username);
    }

    public void setPassword(String password) {
        this.userAuthDto.setPassword(password);
    }

    public void setRoles(List<String> roles) {
        this.userAuthDto.setRoles(roles);
    }

    public void setTenantCode(String tenantCode) {
        this.userAuthDto.setTenantCode(tenantCode);
    }
}

And here's the Controller that was processing the request.

@RequestMapping(value = "authenticate", method = RequestMethod.POST,consumes = "application/json",produces = "application/json")
    public UserAuthResponse authenticate(@RequestBody UserAuthRequest authRequest){
       //.
    }

However when I send this data

{"username": "test","password":"test","roles":null,"tenantCode":"test"}

I receive a 400 bad request. any idea why?

Upvotes: 5

Views: 10566

Answers (2)

JACH
JACH

Reputation: 1048

I struggled this morning with a similar problem. I got a 400 even when the object I was sending was correct. My class was something like this:

class myClass {
   AnalysisResult average; //AnalysisResult is a List<double>
   AnalysisResult worstCase;
   public MyClass(AnalysisResult average, AnalysisResult worstCase) {
      //initializations
   }
}

It was solved by adding a default constructor:

class myClass {
   AnalysisResult average; //AnotherClass is a List<double>
   AnalysisResult worstCase;
   public MyClass(AnalysisResult average, AnalysisResult worstCase) {
      //initializations
   }
   public MyClass() {}
}

It seems that, for some classes, jackson requires a default constructor

Upvotes: 3

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279960

Spring uses Jackson to map the JSON in the request to Java objects to pass as arguments to your handler method.

Here are the JSON types. Here's how Jackson does JSON mappings:

  1. JSON objects map to Java Map or custom class objects
    • The keys of JSON object key-value pairs map to class instance fields
  2. JSON arrays map to Java arrays or Collection types (List, Set, etc.)
  3. JSON numbers map to Java numerical types (int, double, Long, etc. Both primitive and reference types)
  4. JSON strings map to Java String objects (or fields if the JSON string is a key)
  5. JSON null maps to Java null
  6. JSON false and true map to Java false and true.

You've provided the following JSON

{"username": "test","password":"test","roles":null,"tenantCode":"test"}

This is a JSON object, with 4 key-value pairs, where the keys are username, password, roles, and tenantCode. So you need a Java class with fields (or properties) with those names. You have such a class, UserAuthDto. That's what you should use as your parameter type.


You can enable logging by providing the appropriate slf4j and logback or log4j libraries on the classpath with an appropriate configuration for Spring's loggers.

Upvotes: 6

Related Questions