缺少java所需的请求主体,但它在那里

5lhxktic  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(437)

我有一个带有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"
});
gab6jxml

gab6jxml1#

你必须加上 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));
  }
ntjbwcob

ntjbwcob2#

你好,欢迎来到stackoverflow。
这是解决你问题的办法。应该使用具有属性的类 state 类型为userstatedto,因为您的请求是 {"state" : "ACTIVE"} 创建一个名为userstatewrapperdto的新类

public class UserStateWrapperDto {

    private UserStateDTO state;

    public UserStateDTO getState() {
        return state;
    }

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

然后更改控制器方法以获取类型为的参数 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);
}
}

使用此请求使用您的Web服务:

{
"state" : "ACTIVE"
}

谢谢

相关问题