2024/4/11 实现验证码验证的逻辑中,后端使用@RequestBody注解解决了后端接收不到前端传来的json串的bug

目录

  • 一、前端代码
  • 二、后端代码(获取不到json)
  • 三、bug失败原因
    • 1.请求体格式不匹配:
    • 2.请求参数名称不匹配:
    • 3.请求方法不匹配:
    • 四、发现
      • 结论
      • 五、解决方案
        • 解释
        • 六、后端代码(成功获取json)

          大bug:

          一、前端代码

           method: "POST",
                      headers: { "Content-Type": "application/json"
                      },
                      body: JSON.stringify({ captchaKey: captchaKey,
                          captcha: captcha
                      })
          

          二、后端代码(获取不到json)

          @Operation(summary = "验证用户输入的验证码")
              @PostMapping(value = "/verify")
              public ResponseVo verifyCaptcha(HttpServletRequest request) {String captchaKey = request.getParameter("captchaKey"); // 获取请求中的验证码键
          		String userInputCaptcha = request.getParameter("captcha"); // 获取用户输入的验证码
                  // 打印用户输入的验证码和验证码键
                  System.out.println("User Input Captcha: " + userInputCaptcha);
                  System.out.println("Captcha Key: " + captchaKey);
                  // 检查是否缺少验证码数据
                  if (captchaKey == null || userInputCaptcha == null) { return ResponseBuilder.buildErrorResponse("Invalid captcha data");
                  }
                  // 创建 CaptchaVerifier 的实例
                  CaptchaVerifier captchaVerifier = new CaptchaVerifier();
                  // 调用验证码验证器进行验证,使用 verifyCaptcha 方法
                  boolean isValid = captchaVerifier.verifyCaptcha(userInputCaptcha, captchaKey);
                  // 根据验证结果返回相应的响应
                  if (isValid) { return ResponseBuilder.buildSuccessResponse("Verification successful");
                  } else { return ResponseBuilder.buildErrorResponse("Verification failed");
                  }
              }
          

          现在是前端能够成功打印出验证码的值和键,但后端却无法正确获取,可能有几个可能的原因:

          三、bug失败原因

          1.请求体格式不匹配:

          后端代码中的 verifyCaptcha 方法接受的是 HttpServletRequest 对象作为参数,并不直接从请求体中解析数据,而是从请求参数中获取。如果前端发送的数据没有按照预期的方式传递到后端,后端就无法正确获取。确保前端使用正确的方式将数据传递给后端,例如通过 JSON 格式的请求体。

          2.请求参数名称不匹配:

          后端代码中使用 request.getParameter(“captchaKey”) 和 request.getParameter(“captcha”) 来获取请求参数,如果前端发送的参数名称与后端不匹配,后端也会无法正确获取。确保前端发送的请求参数名称与后端代码中使用的名称一致。

          3.请求方法不匹配:

          如果前端发送的请求方法不是 POST 方法,或者后端代码中的 @PostMapping 注解有误,也可能导致后端无法正确获取请求参数。确保前端发送的请求方法是 POST,并且后端的方法也正确地使用了 @PostMapping 注解。

          四、发现

          结论

          但是我的前后端代码都是一一对应的,但后端就是无法获取json串。

          所以我想了想,可能是verifyCaptcha的传参有问题:

          在我的前端代码中,我使用了 JSON.stringify() 将数据转换为 JSON 字符串,并设置了请求头的 Content-Type 为 application/json。这意味着请求体中包含的是 JSON 格式的数据。

          到这里都还没问题

          然而,我发现我的的后端代码中使用的是 request.getParameter() 方法来获取请求参数,但这个方法通常用于从 URL 查询参数中获取值,而不是从请求体中获取值。

          所以,为了正确地从请求体中获取值,我需要在后端代码中使用其他方法来解析 JSON 格式的请求体,例如使用 Spring MVC 中的 @RequestBody 注解来映射请求体中的 JSON 数据到一个 Java 对象中,然后从该对象中获取相应的值。

          五、解决方案

          创建一个CaptchaVerificationRequest类

          public class CaptchaVerificationRequest { @JsonProperty("captchaKey")
              private String captchaKey;
              @JsonProperty("captcha")
              private String captcha;
              public String getCaptchaKey() { return captchaKey;
              }
              public void setCaptchaKey(String captchaKey) { this.captchaKey = captchaKey;
              }
              public String getCaptcha() { return captcha;
              }
              public void setCaptcha(String captcha) { this.captcha = captcha;
              }
          }
          

          解释

          这个类使用了 @JsonProperty注解,它的作用是指定JSON属性的名称,以便在JSON序列化和反序列化过程中正确地映射Java对象的属性。

          也就是说:

          @JsonProperty(“captchaKey”) 告诉JSON序列化/反序列化器,将Java对象中的captchaKey属性映射到JSON中的"captchaKey"字段。

          @JsonProperty(“captcha”) 告诉JSON序列化/反序列化器,将Java对象中的captcha属性映射到JSON中的"captcha"字段。

          六、后端代码(成功获取json)

          这里方法的参数就是,使用了@RequestBody注解。这个注解表明这个方法参数应该通过请求的主体(body)来获取数据,并将请求主体中的JSON数据反序列化为CaptchaVerificationRequest对象。

           @Operation(summary = "验证用户输入的验证码")
              @PostMapping(value = "/verify")
              public ResponseVo verifyCaptcha(@RequestBody CaptchaVerificationRequest request) { String captchaKey = request.getCaptchaKey();
                  String userInputCaptcha = request.getCaptcha();
                  // 打印用户输入的验证码和验证码键
                  System.out.println("111User Input Captcha: " + userInputCaptcha);
                  System.out.println("Captcha Key: " + captchaKey);
                  // 检查是否缺少验证码数据
                  if (captchaKey == null || userInputCaptcha == null) { return ResponseBuilder.buildErrorResponse("Invalid captcha data");
                  }
                  // 创建 CaptchaVerifier 的实例
                  CaptchaVerifier captchaVerifier = new CaptchaVerifier();
                  // 调用验证码验证器进行验证,使用 verifyCaptcha 方法
                  boolean isValid = captchaVerifier.verifyCaptcha(userInputCaptcha, captchaKey);
                  // 根据验证结果返回相应的响应
                  if (isValid) { return ResponseBuilder.buildSuccessResponse("Verification successful");
                  } else { return ResponseBuilder.buildErrorResponse("Verification failed");
                  }
              }