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

大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");
        }
    }
  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值