繁体   English   中英

缺少所需的请求正文,但它在那里

[英]Required request body is missing, but it's there

我有一个带有 UserStateDTO 请求正文的 POST 端点。 Junit 测试工作正常; 但是,由于“缺少所需的请求正文”,我无法使其在浏览器中运行。 正如你所看到的那样,尸体在那里......这让我发疯了。 请在下面找到错误和片段。

org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public void .....UserRestController.setState(UserStateDTO)
@PostMapping(value = "/state", consumes = MediaType.APPLICATION_JSON_VALUE)
public void setState(@RequestBody UserStateDTO userStateDTO) {
    if (userStateDTO != UserStateDTO.ACTIVE && userStateDTO != UserStateDTO.DISABLED) {
        throw new BusinessException(GeneralErrors.INVALID_REQUEST);
    }
    UserDTO userDTO = userService.getUser();
    userDTO.setState(userStateDTO);
    userService.updateUser(userDTO);
}
public enum UserStateDTO {
    ACTIVE("ACTIVE"),
    DISABLED("DISABLED");

    private final String state;

    private static final Map<String, UserStateDTO> states = new HashMap<>();

    UserStateDTO(String state) {
        this.state = state;
    }

    static {
        for (UserStateDTO u : UserStateDTO.values()) {
            states.put(u.getValue(), u);
        }
    }

    @JsonValue
    public String getValue() {
        return state;
    }

    @JsonCreator
    public static UserStateDTO fromValue(String state) {
        return states.get(StringUtils.upperCase(state));
    }

}

fetch("http://localhost:4200/user/state", {
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-language": "en,hu;q=0.9,nb;q=0.8",
    "content-type": "application/json",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "x-xsrf-token": "-"
  },
  "referrer": "http://localhost:4200/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": "{\"state\":\"ACTIVE\"}",
  "method": "POST",
  "mode": "cors",
  "credentials": "include"
});

您好,欢迎来到 stackoverflow。

这是您的问题的解决方案。 您应该使用具有 UserStateDTO 类型的属性state的 class 因为您的请求是{"state": "ACTIVE"}

创建一个名为 UserStateWrapperDto 的新 class

public class UserStateWrapperDto {

    private UserStateDTO state;

    public UserStateDTO getState() {
        return state;
    }

    public void setState(UserStateDTO state) {
        this.state = state;
    }
}

然后更改您的 controller 方法以获取UserStateWrapperDto类型的参数

    @PostMapping(value = "/state", consumes = MediaType.APPLICATION_JSON_VALUE)
    public void setState(@RequestBody UserStateWrapperDto userStateWrapperDTO) {
        if (userStateWrapperDTO.getState() != UserStateDTO.ACTIVE && userStateWrapperDTO.getState()  != UserStateDTO.DISABLED) {
            throw new BusinessException(GeneralErrors.INVALID_REQUEST);
        }
       UserDTO userDTO = userService.getUser();
        userDTO.setState(userStateDTO.getState());
        userService.updateUser(userDTO);
    }
}

使用此请求使用您的网络服务:

{
    "state" : "ACTIVE"
}

谢谢

您必须在枚举中添加getState()方法。 正确代码如下:

public enum UserStateDTO {
  ACTIVE("ACTIVE"),
  DISABLED("DISABLED");

  private final String state;

  private static final Map<String, UserStateDTO> states = new HashMap<>();

  UserStateDTO (String state) {
    this.state = state;
  }

  static {
    for (UserStateDTO u : UserStateDTO.values()) {
        states.put(u.getValue(), u);
    }
  }

  public String getState() {
    return state;
  }

  @JsonValue
  public String getValue() {
    return state;
  }

  @JsonCreator
  public static UserStateDTO fromValue(String state) {
    return states.get(StringUtils.upperCase(state));
  }
}

或者您可以仅在方法fromValue()注释@JsonProperty("state")内部添加,它在没有 getter 的情况下绑定您的请求正文值。 正确方法如下:

  @JsonCreator
  public static UserStateDTO fromValue(@JsonProperty("state") String state) {
    return states.get(StringUtils.upperCase(state));
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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