Java org.springframework.http.converter.HttpMessageNotReadableException 发送 POST 请求时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35534113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:47:55  来源:igfitidea点击:

org.springframework.http.converter.HttpMessageNotReadableException when sending a POST request

javaspringHymanson

提问by raptor123

I have a Spring application with the following controller:

我有一个带有以下控制器的 Spring 应用程序:

   @RestController
   @RequestMapping("/app") 
   public class RegisterRestController {
   @Autowired
    UserRepository userRepository;

   @Autowired
   PasswordEncoder passwordEncoder;

   @Autowired
   UserService userService;


   @RequestMapping( value="/loginuser", method =RequestMethod.POST,produces="application/json")
    public String loginUser(@RequestBody String requestBody) {
    System.out.println("inside");
    JSONObject responseJsonObject = new JSONObject();
    String phonenumber;
    String password;
    try{
        JSONObject object = new JSONObject(requestBody);
        phonenumber = object.getString("phonenumber");
        password = object.getString("password");
        User user = userService.findByNumber(phonenumber);
        String sha256Password = passwordEncoder.encode(password);
        if(sha256Password.equals(user.getPassword())){
            responseJsonObject.put("response", "Login Successful");
        }
        else {
            responseJsonObject.put("repsonse", "Login failed");
        }
    }
    catch (Exception e){
        e.printStackTrace();
        try {
            responseJsonObject.put("response", "Invalid Credentials");
        } catch (JSONException e1) {
            e1.printStackTrace();
        }

    }
    return responseJsonObject.toString();
}

However, when I send a POST request from Postman containing :

但是,当我从 Postman 发送包含以下内容的 POST 请求时:

    {
      "phonenumber":"9123456789",
      "password":"password"
  }

I get the following response:

我收到以下回复:

    {
   "timestamp": 1456043810789,
   "status": 400,
    "error": "Bad Request",
    "exception":      "org.springframework.http.converter.HttpMessageNotReadableException",
    "message": "Could not read JSON: Can not deserialize instance of   java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@eaa3acb; line: 1, column: 1]; nested exception is com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@eaa3acb; line: 1, column: 1]",
    "path": "/app/loginuser"
}

Also, I was experimenting with Spring Security as well. The server does not show any error and the controller does not seem to receive the request as "inside" is not being printed. I am trying to get acquainted with Spring, however I could not find the reason for such an error. I would be grateful for any help. Thanks in advance

此外,我也在试验 Spring Security。服务器没有显示任何错误,控制器似乎没有收到请求,因为“内部”没有被打印。我正在尝试熟悉 Spring,但是我找不到出现此类错误的原因。我将不胜感激任何帮助。提前致谢

采纳答案by Stefan Isele - prefabware.com

There are two problems in your code:

您的代码中有两个问题:

  1. You try to convert the JSON into an object inside the controller. This is already done by Spring. It receives the body of the request and tries to convert it into the Java class of the according parameter in the controller method.
  2. Your controller method expects a single string: @RequestBody String requestBody
  1. 您尝试将 JSON 转换为控制器内的对象。这已经由 Spring 完成了。它接收请求的主体并尝试将其转换为控制器方法中相应参数的 Java 类。
  2. 您的控制器方法需要一个字符串: @RequestBody String requestBody

And you are sending an object with two properties:

您正在发送一个具有两个属性的对象:

{
    "phonenumber": "9123456789",
    "password": "password"
}

Solution:

解决方案:

Create a class for the values you need to login :

为您需要登录的值创建一个类:

public class Login {
    public String phonenumber;
    public String password;
    // you need a zero argument constructor
    // maybe you have to add getter and setters
}

Change your controller method so it expects an object of this type

更改您的控制器方法,以便它需要这种类型的对象

@RequestBody Login requestBody

回答by uncle-tee

The Hymanson library will automatically convert to JSON using the constructors you have defined in the login User method. So you need not to convert to json. So this means that

Hymanson 库将使用您在 login User 方法中定义的构造函数自动转换为 JSON。所以你不需要转换成json。所以这意味着

{
    "phonenumber": "9123456789",
    "password": "password"
}

should be defined in your in your constructor. You should have defined an entity class that defines a loginUser.

应该在您的构造函数中定义。您应该已经定义了一个定义 loginUser 的实体类。

  public class LoginUser{
    String phonenumber;
    String password;

    // define all other variables needed.

    public LoginUser(String phonenumber, String password){
        this.phonenumber = phonenumber ;
        this.password = password;
    }

    public LoginUser() {
        //you need a default contructor. As srequired by spring
    }

    //Define the gettters and settters

}

Then

然后

 @RequestMapping( value="/loginuser", method = RequestMethod.POST,produces="application/json")
    public String loginUser(@RequestBody LoginUser requestBody) {
        System.out.println("inside");
        try{

        phonenumber = requestBody.getPhonenumber; // please define your getters and setters in the login class
        password = requestBody.getpassword;
        User user = userService.findByNumber(phonenumber);
        String sha256Password = passwordEncoder.encode(password);
        if(sha256Password.equals(user.getPassword())){
        responseJsonObject.put("response", "Login Successful");
        }
        else {
        responseJsonObject.put("repsonse", "Login failed");
        }
        }
        catch (Exception e){
        e.printStackTrace();
        try {
        responseJsonObject.put("response", "Invalid Credentials");
        } catch (JSONException e1) {
        e1.printStackTrace();
        }

        }
        return responseJsonObject.toString();
}

You can use postman to try now. Goodluck

你现在可以用邮递员试试。祝你好运

回答by Abhishek Tiwari

one of the reason apart of mentioned above could be, the type mismatch of fields. in my case, field was declared UUID and i was sending it as string. Sending it as UUID solved my problem.

上面提到的原因之一可能是字段的类型不匹配。就我而言,字段被声明为 UUID,我将它作为字符串发送。将其作为 UUID 发送解决了我的问题。