Home > OS >  com.fasterxml.jackson.databind.JsonMappingException: app is marked non-null but is null
com.fasterxml.jackson.databind.JsonMappingException: app is marked non-null but is null

Time:02-24

I am write a login rest api in Spring Boot using java 11, this is the login api server side code:

@PostMapping("/plugin/login")
Response<LoginResponse> pluginLogin(@RequestBody UserLoginRequest request);

and this is the UserLoginRequest define:

package biz.user;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import misc.enumn.DeviceType;
import misc.enumn.app.AppName;
import misc.enumn.user.LoginType;

import java.io.Serializable;

/**
 * @author dolphin
 */
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserLoginRequest implements Serializable {

    /**
     * user.phone
     *
     * @mbggenerated
     */
    @NonNull
    private String phone;

    /**
     * user.password
     *
     * @mbggenerated
     */
    @NonNull
    private String password;

    @NonNull
    private LoginType loginType;

    /**
     * user.phone_region
     *
     * @mbggenerated
     */
    @ApiModelProperty(value = "phone region")
    private String phoneRegion;


    @ApiModelProperty(value = "app")
    @NonNull
    private AppName app;

    @ApiModelProperty(value = "device type")
    private DeviceType deviceType;

    @ApiModelProperty(value = "device type")
    private String deviceId;

    @ApiModelProperty(value = "nick name")
    private String nickname;

    @ApiModelProperty(value = "avatar url")
    private String avatarUrl;
}

when I invoke this api like this:

curl 'https://dict.example.top/dict/user/plugin/login' \
  -H 'Connection: keep-alive' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4753.0 Safari/537.36' \
  -H 'Content-type: application/json' \
  -H 'Accept: */*' \
  -H 'Origin: chrome-extension://alepiijaddmmflnaibdpolcgglgmkpdm' \
  -H 'Sec-Fetch-Site: none' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  --data-raw '{"phone":"","password":"","deviceId":"xxxx","app":7,"deviceType":7,"loginType":1}' \
  --compressed

the server shows error:

Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: app is marked non-null but is null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: app is marked non-null but is null
 at [Source: (PushbackInputStream); line: 1, column: 51] (through reference chain: biz.user.UserLoginRequest["app"])

why did this happen? what should I do to fix it? This is the AppName define:

@Getter
public enum AppName implements BaseEnum {
    CRUISE(1, "cruise"),
    BACK(2, "back"),
    REDDWARF_MUSIC(4, "长歌"),
    REDDWARF_DICT(5, "红矮星词典"),
    REDDWARF_ADMIN(6, "红矮星后台管理系统"),
    ;

    @JsonValue
    private Integer key;
    private String value;

    AppName(Integer key, String value) {
        this.key = key;
        this.value = value;
    }

    private static final Map<Integer, AppName> mappings;

    static {
        Map<Integer, AppName> temp = new HashMap<>();
        for (AppName courseType : values()) {
            temp.put(courseType.key, courseType);
        }
        mappings = Collections.unmodifiableMap(temp);
    }

    /**
     * @param key
     * @return
     */
    @EnumConvertMethod
    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static AppName resolve(Integer key) {
        return mappings.get(key);
    }

    public void setKey(Integer key) {
        this.key = key;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public static AppName getAppMarkByValue(String value) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.name().equals(value)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }

    public static AppName getAppMarkByKey(Short key) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.key.equals(key)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }
}

CodePudding user response:

You are using enum to receive the app parameter, on the client you tell server your app is 7, but in your AppName enum you did not define which app is 7. so when parse the 7 did not map any app, it get null. but your lombok validate the app could not be null, that's why you get the error. Fix your problem, you should add the 7 app define in your AppName like this:

CRUISE(1, "cruise"),
BACK(2, "back"),
REDDWARF_MUSIC(4, "长歌"),
REDDWARF_DICT(5, "红矮星词典"),
REDDWARF_ADMIN(6, "红矮星后台管理系统"),
MY_NEW_APP(7, "the new app name"),

replace the MY_NEW_APP to whatever you want to named.

  • Related