web-dev-qa-db-fra.com

org.springframework.http.converter.HttpMessageNotReadableException lors de l'envoi d'un POST demande

J'ai une application Spring avec le contrôleur suivant:

   @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();
}

Cependant, lorsque j'envoie une demande POST de Postman contenant: 

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

Je reçois la réponse suivante:

    {
   "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.jackson.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"
}

J'essayais également avec Spring Security. Le serveur ne montre aucune erreur et le contrôleur ne semble pas recevoir la demande car "l'intérieur" n'est pas en cours d'impression. J'essaie de faire connaissance avec Spring, mais je ne pouvais pas trouver la raison d'une telle erreur. Je vous serais reconnaissant pour toute l'aide apportée. Merci d'avance 

5
raptor123

Il y a deux problèmes dans votre code:

  1. Vous essayez de convertir le JSON en objet dans le contrôleur ..__ Ceci est déjà fait par Spring. Il reçoit le corps de la demande et tente de le convertir en classe Java du paramètre suivant dans la méthode du contrôleur. 
  2. Votre méthode de contrôleur attend une seule chaîne: @RequestBody String requestBody

Et vous envoyez un objet avec deux propriétés:

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

Solution:

Créez une classe pour les valeurs que vous devez vous connecter:

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

Changez la méthode de votre contrôleur pour qu'il attend un objet de ce type

@RequestBody Login requestBody

La bibliothèque Jackson sera automatiquement convertie en JSON à l'aide des constructeurs définis dans la méthode de connexion de l'utilisateur. Donc, vous n'avez pas besoin de convertir en json. Donc cela signifie que 

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

devrait être défini dans votre dans votre constructeur. Vous devez avoir défini une classe d'entité qui définit un utilisateur de connexion.

  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

}

Ensuite 

 @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();
}

Vous pouvez utiliser postman pour essayer maintenant. Bonne chance

1
TechPython

l'une des raisons mentionnées ci-dessus pourrait être, le type ne correspond pas aux champs . dans mon cas, le champ a été déclaré UUID et je l'envoyais sous forme de chaîne. L'envoyer comme UUID a résolu mon problème.

0
Abhishek Tiwari