发送含对象数组的JSON触发400错误,请求无法抵达服务器
我仔细看了你的代码和请求JSON,很快找到了几个导致400 Bad Request的关键问题——都是Jackson反序列化阶段的错误,请求还没到业务逻辑就失败了:
1. Branch无参构造函数的空指针异常
你的Branch类无参构造里直接操作了未初始化的address:
public Branch() { this.address.setAddressCategory(AddressCategory.BRANCH); }
Spring反序列化JSON创建Branch实例时,会先调用无参构造,但此时address还是null,直接调用setAddressCategory会抛出NullPointerException,这是最致命的问题。
修复方法:
先初始化address再设置属性:
public Branch() { this.address = new Address(); this.address.setAddressCategory(AddressCategory.BRANCH); }
2. JSON中的actor属性在Address类中不存在
你发送的JSON里,address对象带了"actor": "1abaaa11-1145-432f-84b0-40b9b551acdd",但你的Address实体类根本没有这个属性。Jackson默认配置下遇到未知属性会直接报错,导致反序列化失败。
修复方法:
二选一即可:
- 删掉JSON里的
actor字段(毕竟你在Company.addBranch方法里已经手动设置了branch.getAddress().setActor(this);,前端不需要传); - 在
Address类上添加注解忽略未知属性:
@Entity @Table(name=Address.TABLE_ADDRESS) @JsonIgnoreProperties(ignoreUnknown = true) public class Address { // ... 原有代码 }
3. EmailAddress的字段名不匹配
JSON里的邮箱字段是"email": {"email": "example@mail.com"},但你的EmailAddress类字段是emailAddress,Jackson没法把JSON里的email映射到emailAddress上,会导致反序列化失败。
修复方法:
给EmailAddress的字段添加@JsonProperty指定JSON字段名:
@Embeddable public class EmailAddress { @Column(name="email") @JsonProperty("email") private String emailAddress; // ... 原有代码 }
额外优化建议:DTO层避免直接使用实体类
你的CompanyDTO里直接用了List<Branch>(JPA实体类),这不是最佳实践——实体类的JPA注解可能干扰Jackson序列化,也不利于控制前后端交互的字段范围。建议创建对应的BranchDTO、AddressDTO来接收前端请求,再在业务层转换为实体类。
比如创建BranchDTO:
public class BranchDTO { private String telephone; private AddressDTO address; // GETTERS AND SETTERS }
然后把CompanyDTO的branches字段改为List<BranchDTO>。
按照上面的步骤修改后,你的请求应该就能正常被反序列化并到达服务器了。
内容的提问来源于stack exchange,提问作者Eddy Freeman

