You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring无法正确读取JavaScript传递的JSON数据问题排查

问题:Spring Boot接收前端JSON参数时DTO属性始终为空/默认值

环境与代码

Spring Controller

@PostMapping("/updateStaff")
@ResponseBody
public ResponseEntity<String> updateStaff(
        @RequestBody UpdateStaffDto nhanVien
) {
    try {
        NhanVien existedNhanVien = nhanVienRepository.findById(nhanVien.getIdCode()).orElse(null);
        log.warn("Id:" + nhanVien.getIdCode());
        if (existedNhanVien != null) {
            log.warn("nhanVien found");
            String newMatKhau = (nhanVien.getMatKhau()!=null && !nhanVien.getMatKhau().isBlank())
                    ? Common.sha256Hash(nhanVien.getMatKhau()) : "";
            String newVaiTro = (nhanVien.getVaiTro()!=null && !nhanVien.getVaiTro().isBlank())
                    ? nhanVien.getVaiTro() : "";
            if(!newMatKhau.equals(existedNhanVien.getMatKhau())) {
                existedNhanVien.setMatKhau(newMatKhau);
            }
            if(!newVaiTro.equals(existedNhanVien.getVaiTro())) {
                existedNhanVien.setVaiTro(newVaiTro);
            }
            existedNhanVien.setDateUpdated(new Date());
            nhanVienRepository.save(existedNhanVien);
            return ResponseEntity.ok().build();
        }
    } catch (DataIntegrityViolationException e) {
        log.error("Error: " + e);
    } catch (NullPointerException e) {
        log.error("System error: " + e);
    }
    log.warn("nhanVien not found");
    return ResponseEntity.badRequest().build();
}

DTO类

package com.springdemo.library.model.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UpdateStaffDto {
    private int IdCode;
    private String matKhau;
    private String vaiTro;
}

前端jQuery代码

$('#update-staff-form').on('submit', function (e) {
     e.preventDefault();
     let matKhau = $("#password-update").val();
     let xacNhanMatKhau = $("#confirm-password-update").val();
     if(matKhau === xacNhanMatKhau) {
         modifyStaff(JSON.stringify({
                 IdCode: $('#staff-id-update').val(), // 此处传入的值为3,浏览器控制台打印也显示为3
                 matKhau: matKhau,                    // 随机字符串
                 vaiTro: $('#role-update').val()      // 值为0
             }),'/Library/management/updateStaff'
         );
     } else {
         $('#unmatched-password-message')
             .text("Xác nhận mật khẩu chưa khớp với mật khẩu bạn đã nhập, vui lòng nhập lại").css('color', 'red');
     }
 });

function modifyStaff(data, url) {
    $.ajax({
        url: url,
        method: 'POST',
        contentType: 'application/json',
        data: data,
        success: function () {
            $('#time-update').text(formatDate(new Date()));
            window.location.reload();
            alert("Đã thêm tài khoản thành công");
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.warn('Error:', textStatus, errorThrown);
            alert("Có lỗi");
        }
    });
}

问题现象

前端传入的IdCode值为3,matKhau为随机字符串,vaiTro为0,但后端Controller中接收的UpdateStaffDto实例里,IdCode始终为0,matKhau和vaiTro为空/默认值。尝试移除@RequestBody和JSON.parse均无效。

原因分析与解决方法

核心原因

  1. 属性命名不匹配:DTO中的IdCode采用大驼峰命名,Spring默认的Jackson序列化/反序列化规则遵循小驼峰匹配,前端传入的JSON键是IdCode,Jackson会尝试映射到idCode(小驼峰),导致无法匹配,最终使用属性默认值。
  2. 缺少Setter方法:DTO仅标注@Getter,Jackson反序列化需要Setter方法注入属性值,没有Setter则无法完成数据赋值。

解决步骤

方法一:统一小驼峰命名(推荐)

修改DTO属性为小驼峰,同步前端JSON键名:

  • DTO修改:
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter // 添加Setter注解
public class UpdateStaffDto {
    private int idCode; // 改为小驼峰
    private String matKhau;
    private String vaiTro;
}
  • 前端修改JSON键:
modifyStaff(JSON.stringify({
        idCode: $('#staff-id-update').val(), // 改为小驼峰
        matKhau: matKhau,
        vaiTro: $('#role-update').val()
    }),'/Library/management/updateStaff'
);

方法二:保留原命名,添加Jackson注解

若不想修改命名,在DTO属性上添加@JsonProperty指定JSON键名,同时补充Setter:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter // 添加Setter
public class UpdateStaffDto {
    @JsonProperty("IdCode") // 指定匹配的JSON键名
    private int IdCode;
    private String matKhau;
    private String vaiTro;
}

前端无需修改JSON键。

额外注意点

  • 确保Spring Boot Web Starter依赖已引入(默认包含Jackson相关组件)。
  • 前端必须设置contentType: 'application/json',否则后端无法识别JSON请求体。
  • 前端$('#staff-id-update').val()返回字符串,可通过parseInt()转为数字类型,避免反序列化潜在问题:idCode: parseInt($('#staff-id-update').val())

内容的提问来源于stack exchange,提问作者minhson Bui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:34:52