前几天开发时踩了个坑,前端拿不到 isSuccess 的值,调接口看返回也确实有数据,排查了半天才发现是字段命名的问题。今天就把这个踩坑过程整理出来,希望能帮大家少走弯路。
Java Bean 的 getter/setter 规范
- 普通类型比如 int、String 这些,getter 是 getXxx (),setter 是 setXxx ()。就像 username 字段,对应 getUsername () 和 setUsername (),这部分大家基本都熟。
- 但布尔类型不一样,规范里 getter 是 isXxx () 而不是 getXxx ()。比如 success 这个布尔字段,getter 应该是 isSuccess (),setter 还是 setSuccess ()。
这个规则本身没问题,但当布尔字段名自带 is 前缀时,矛盾就出现了。
下面就是笔者踩中的坑
当时定义了一个接口返回结果类,想着让字段名直观些,就给布尔字段加了 is 前缀:
public class Result {// 布尔字段带is前缀private boolean isSuccess;private String message;// IDE自动生成的getter/setterpublic boolean isSuccess() {return isSuccess;}public void setSuccess(boolean success) {this.isSuccess = success;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}
当后端返回Result
对象时,
- 对于
getMessage()
:去掉get
前缀,首字母小写 → JSON 字段名为message
(符合预期); - 对于
isSuccess()
:去掉is
前缀,首字母小写 → JSON 字段名为success
(而非字段名isSuccess
)。
最终序列化后的 JSON 是这样的:
{"success":true,"message":"操作成功"}
前端开发按字段名isSuccess
接收数据(比如response.isSuccess
),那自然对应不上, 也就接收不到数据了
为什么序列化工具依赖 getter 而非字段名?
后来查了下才明白,这和 Java 的封装思想有关:
- 字段通常是
private
修饰的,外部本就不该直接访问,序列化工具尊重封装原则; - 灵活性更高:可以通过自定义 getter 修改序列化结果。例如字段
isVip
,可通过isMember()
getter 让 JSON 显示member
字段。
解决方案:
最佳实践:布尔字段去掉 is 前缀
这是最符合规范、零成本的方案。将isSuccess
改为success
,其他代码不变:
public class Result {// 布尔字段不带is前缀private boolean success;private String message;// getter/setterpublic boolean isSuccess() {return success;}public void setSuccess(boolean success) {this.success = success;}// ...其他方法
}
此时序列化后的 JSON 为{"success":true,"message":"操作成功"}
,前后端直接用success
对接即可,完美契合直觉。
自定义 getter 方法
public class Result {private boolean isSuccess;private String message;// 自定义getter,方法名改为getIsSuccess()public boolean getIsSuccess() {return isSuccess;}public void setSuccess(boolean success) {this.isSuccess = success;}// ...其他方法
}
序列化工具会解析getIsSuccess()
:去掉get
前缀 → JSON 字段名为isSuccess
。但这种方式不符合 Java Bean 规范,不推荐优先使用。