jdk8, springboot;
客户端包括了很多,电视端 手机端 小程序端 web 端;
除了 web 端,好像都不太愿意接收 null ;
例如 java 一个实体类 我返回给他们,某些字段为空的话 也想接收 "",不要 null ;
这一块我想问问大佬们,都是怎么优雅处理的;
不会要每个 bean ,都 private String a = "";
1. 判断 Null 和 "" 有很大区别吗? 因为什么呢
2.java 编译过程中,null 要比""占用的资源少吧
1
doco 318 天前 8
web 端也不想要 null
|
2
ZhLTE 318 天前
序列化的时候统一处理
|
3
pota 318 天前
这么和你说 "" 和 null 不是一个类型的数据。你定义一个参数是 string 我塞一个 null 给你,你怎么想?
|
6
falsemask 318 天前
spring.jackson.default-property-inclusion=NON_NULL
|
7
laaaaaa OP @pota 对 还有这个问题,如果返回的是 json 或者 数组, 没有数据 我一般会给 [] 或者 {}, 但是服务端如果返回这样 貌似要 new 一个对象返回, 这不是又耗费资源了吗
|
8
me1onsoda 318 天前
null 要多一步判空吧
|
9
chendy 318 天前
直接不返回就行
或者让他们换一个完善点的 ui 框架,自动把 null 显示成空白那种 |
10
azhangbing 318 天前
因为 kotlin 默认非空
|
11
wu67 318 天前
举个例子.
你这样返回的时候, JS 代码仔需要写多好几个判断来取数, 尤其是需要字符串内容做正则的时候 if (typeof a === 'string' && /balabala/.test(a)) {} 要不就是 if (a.length) 能解决的时候, 需要 if (Array.isArray(a) && a.length) , 看起来是没什么, 但是页面结构复杂度以上去, 数据字段一开始多, 这一大堆多出来的判断, 就会成为客户端代码的屎山 |
12
NewYear 318 天前 2
1 、有的语言里,null 会报错。还会导致 if 判断不按预期的分支走。(特别适合用来写屎山,因为从语言层面你看不出任何一点不按预期分支走的可能,直到单独调试在这里才发现卧槽)
2 、有的语言里,null 不会报错但是每次都要考虑它就显得很烦了,谁都不想增加负担。 一般的解决方案:禁止 null 的存在,明确每个值的意义。 未定义也不许用 null ,字符串可以用"",数字可以用 0 或者-1 (具体按自己的定义来)。 数字类型:1 是男,0 是女,-1 是未定义 又或者 0 是未定义,1 是男,2 是女,3 是跨性别男,4 是…… 字符串类型:""是未定义,"男"是男。 日期类型:“1970 年 1 月 1 日”是未定义,或者“0000 年 00 月 00 日”是未定义。 |
13
MoonLin 318 天前
不返回的话他们可以自己用默认值,返回为 null 就覆盖了默认值,如果要处理的话其实也可以,自己实现反序列化就好了,但是我估计客户端不愿意干,不然你也不会来问了。所以你不如直接不返回,看你用什么序列化框架,一般如 6#所述加个注解就好了。
|
14
NewYear 318 天前
null 和 string/int/date 的类型都不同,不能直接用真的很烦。
楼主后端用是什么语言,不是强类型语言吗。 |
15
sanmaozhao 318 天前
我觉得应该返回 null ( OP 没说返回的数据格式是啥,默认 JSON 了)
1 、JSON 里面本来就是有 null 这个类型的 2 、数字型,不返回 null 的话,用什么表示这项数据没有值呢?用哪个数值都不太合适 如果没值的项直接不返回的话,其实和返回 null 差别也不大 比如对于 js ,就是判断 undefined 和 null 的差别 |
16
wu67 318 天前
还有一个典中典的, 忘记是什么时候遇到的, 有个变量的值, 是 'null'...
出 bug 找前端查的时候, 那一个山崩地裂... if('null') {1} else {2} // 1 |
17
null123456 318 天前
调用此方法:StringUtils.isNotBlank(String str)
|
18
vagusss 318 天前
springboot 默认的序列化应该是 Jackson, 应该有配置项可以直接达到你要的效果
|
19
lyxxxh2 318 天前
啥类型的就返回啥类型 很正常
web 端口也一样 字符: ''.split('a') 数组: [].map((() => {})如果返回个 null,前端: mmp |
20
cslive 318 天前
加注解,字段为 null 会忽略 json 序列化
|
21
yxisenx 318 天前
jackson 的话直接在返回实体上面加个
@JsonInclude(JsonInclude.Include.NON_NULL) |
22
potatowish 318 天前 via iPhone
返回空字符串和 null 在服务端含义是不同的,而客户端是表现层,所以这个差异是体现不出来的,都是没有值。
还有就是代码健壮性的问题,如果客户端处理了 null ,那么即便服务端返回空字符串,客户端也不会有问题。 |
23
nicocho 318 天前 via Android
好久没看到优雅这个词了
|
24
sanmaozhao 318 天前
@potatowish
> 返回空字符串和 null 在服务端含义是不同的,而客户端是表现层,所以这个差异是体现不出来的,都是没有值。 这个其实不太对,现在的客户端早就不是简单的渲染表现层了,也是有部分业务逻辑在里面的 所以我上面才觉得,服务端就应该如实地返回 null |
25
XXWHCA 318 天前
null 不返回就行,他们可能是不喜欢返回没有意义的 null 字段,客户端这种强类型语言开发时不返回的字段引用类型默认值也是 null😂,文档写明白就行了
|
26
kalista 318 天前
go 也不喜欢 null ,甚至数据库定义里面都是 not null 的
|
27
Ayanokouji 318 天前
数据库加默认值,能解决不少问题
|
28
yolee599 318 天前 1
为啥要返回 null ?没意义啊,如果这个字段没有数据,直接不传这个字段就好了,不用多此一举还浪费网络带宽。
|
29
treblex 318 天前
我最近开始写 getValue(obj,"a.b.c.d") 这样的东西,取到 null 的时候就不会崩溃了🙈
|
30
ZeroDu 318 天前
|
31
wangritian 318 天前
我是 go 后端,用中间件拦截控制器的输出,然后通过反射递归的把空指针 nil 改成空值
但其实站在团队角度,我更支持客户端应该有健壮性,兼容 null 和空值 就像我从来不设计请求参数不传(null)和传空值有不同含义,应该最大的去兼容 |
32
nerkeler 318 天前
`private String a = ""` 简单粗暴,或者用注解 @JsonIgnore 指定参数(具体忘记是啥了) 不返回 null 的字段 ,怎么简单怎么来呗,或者统一处理请求字段 null 的都给个初始值,不过实现麻烦了点
|
33
broken123 318 天前
你应该想想各个客户端的语言是不一样的 安卓 java kotlin ,flutter dart web js ts , 还有各种小程序 直接给一个默认值就行了
|
34
broken123 318 天前
实际上客户端也只有强制类型语言才会 做 null 判断 js 会 出现 undfi 和 null 这种情况 java 写他妈一大堆非空判断再取是真的很烦心。代码丑陋的一笔。
|
35
darkengine 318 天前
有一天,后端跟我说,前端要判断某个接口返回的复杂结构里字段是不是 null 或者 undefine
我问哪个字段需要判断,他说不是很简单吗,所有字段。。。 卧尼🐎个很简单 |
36
zjp 318 天前
在序列化层做呗,Jackson 的话是单独处理 null 值的,参考 https://stackoverflow.com/a/18123772
JsonInclude.Include.NON_NULL 的结果是没有字段 |
37
linzhe141 318 天前
前端加一大段```a?.b?.c?.d ?? "无数据"```
|
38
zjsxwc 318 天前 via Android
我写 js 就喜欢 null ,
如何某个字段是 object , 但这个 object 数据没有,那你也必须给我一个 null 值,不然如果你直接不给我这个字段,我 js 取这个字段时就直接报错执行不下去。 |
39
zjsxwc 318 天前 via Android
我写 js 就喜欢 null ,
如果某个字段是 object , 但这个 object 数据没有,那你也必须给我一个 null 值,不然如果你直接不给我这个字段,我 js 取这个字段时就直接报错执行不下去。 如果某个字段是 int ,你却给了我一个 0 ,我怎么表示,这是业务上比如用户还没填写,还是用户已经填写了 0 ,string 也一样道理。 |
40
xuanbg 318 天前
null 就是 null 。又不是我要给 null ,肯定是你前端没给数据数据库里面才存的 null 。你前端凭啥不要 null ?
|
41
mshadow 318 天前 via Android
@pota {}给[],一般是后端 php 的坑,map 和数组在 php 中都是 array ,空 array 会 json 序列化为[],这个一般要 php 特殊处理一下
|
42
oatw 317 天前
有一种主义叫“无 null 主义”,数据库里就不可以有 null ,尤其是涉及到三值逻辑的时候。
|
43
DzwsGo 317 天前
kotlin 默认非空,如果没有做特殊处理 json 转换的时候遇到 null 就会崩溃,做处理就会出现很多?
另外 @chendy #9 后端是不是可以换个完善点的框架,自动把 null 换成相应数据类型默认值? 😁 |
44
pota 317 天前
@laaaaaa #7 java 应该没有这个问题吧? map 结构化之后就是{}啊。像楼上说的,PHP 会有这个问题。API 数据类型一致因为我不是 java ,一般我解决方案就是可能出现类型不一致的定义 Attribute 获取
|
45
cleveryun 317 天前 via Android
前面有楼层提到数值没值返回 0 不合适时返回 null 的。这个没业务场景的情况下且认为没问题。这里其实他们说的最大问题不是是否返回 null ,而是与接口文档是否一致。如果会返回 null ,那接口文档里就不应该只写会返回数值,应该把 null 也写上。这是联调涉及到的契约精神的问题,不应该字段值类型都变成盲盒。
|
46
chendy 317 天前
@DzwsGo 写过 kt 和 ts ,需要?的时候就给?呗,业务逻辑允许 null ,代码没理由不允许 null (其实展示层还好,如果有逻辑啥的就比较麻烦,有时候甚至原样复制粘贴但是去掉?然后加校验和报错)
这么一说其实塞默认值可能在序列化这一步更合适? 字符串就 "",列表就 [],但是对象和数字不好处理,特别是需要区分‘填了’和‘没填’,需要有‘草稿’这类的功能的时候更是如此… |
47
j1132888093 317 天前
整型的 null 和 0 ,字符串的 null 和空本来就是不同的意义,凭啥不要 null ?你要是说 null 就直接不返回这个字段还能理解
|
48
wangtian2020 317 天前
返回的 json 出现 null 或者是 undefined 我立马活都不干了跟后端去 battle ,所有字段必须初始化成空字符串/空数字
|
49
2123123 317 天前
字符串空跟 null 的绝大部分时候意义是一样的,所以字符串我一般初始值给 ""
但是空数字意义是不一样的,非要传个特定数字或者 "" 代表空的话也要多一次判断,跟判断一次 null 本质上不是一样吗? |
50
leonshaw 317 天前
幼儿园就讲过的问题,0 不一定是没有,白色不等于透明
|
51
jl1014171068 317 天前
null 也还能接受,但是还有返回"null"的..........
|
52
dyv9 317 天前 via Android
对于数字栏,有时候没填写和 0 意思是不一样的。
|
53
BBCCBB 317 天前
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
这样直接就不返回那个值了, 一样有问题. 最好的办法就是前端判断.. |
54
xingdaorong 317 天前
@zjsxwc 你说的不合理,假如 age 字段不填,可以返回 null 不能 0,因为含义不同一个没有年纪,一个是 0 岁,字符串比如名字,可以是 null 可以是"",但是最好是"",因为前端可能用字符串方法不做判空报错。但是比如一个数组,没有数据就是空数组[]而不是 null 。总结:如果没有特殊含义就一定用同类型的,不用 null 。
|
55
exmario 317 天前 1
null 还好说,但是给个"null"算什么回事
|
56
zjsxwc 317 天前
@xingdaorong
我还是坚持除了 array 必须用空数组[]外,别的全都可以 null 。 如果你不允许 null ,那么对于任意字段 XXX ,你必须额外添加一个字段 isXXXNotNull 来表示,XXX 字段是没有被填写状态还是已经被填写了。 |
57
lujiaosama 317 天前
我最讨厌的是数字型字段原本该返回 NULL 或者''. 给我返回了个-1. 问题是-1 有些场景在业务上是有意义的. 直接显示个-1 容易误导用户.
|
58
wmui 317 天前
不是不能是 null ,是要保持数据结构一致。如果是数字,默认值可以是 0 不能是 null ,如果是字符串,默认值可以是'',如果是对象,默认值可以是 null
|
59
zerofancy 316 天前
我们是基本类型一般不要有 null ,这样客户端可以定义 int 而不是 Integer 。其他类型包括 String 都当作可能为 null 来处理。
尽管我们用了 Kotlin ,但序列化框架还是 gson ,所以一般还是把几乎所有字段定义成可空的。 |
60
Jhon11 316 天前 via iPhone
用 protobuf
|
61
yusheng88 316 天前 via Android
1. null 和默认值是两个概念,null 是没有值,判 null 是调用方的责任
2. 字段能否为 null ,是产品,业务决定的,如果有默认值,也是产品和业务决定的。 3. 字段为 null ,或者为 null 时不返回字段,前端处理不了的,领导还倾向前端的,只能对你表示可怜 |
62
liuhuihao 316 天前
个人观点
String 空值情况:空值一律返回'',理由是一般情况下字符串字段都是用来展示用的,如有逻辑判断<用户是否填了>这个字段,那可以增加一个 boolean 字段表示是否填了, 但这种情况业务上很少,因为作为入参的时候一个输入框没填其实 = 空字符串 Number 空值需要根据业务场景来处理,比如“好友数”等各种计数的空值可以是 0 ,男女等 未选择的话可以用 -1 表示。但如果是一个非必填数字输入框,可以输入任意值的这种,null 值 应该是需要的 Boolean 同 Number ,需要根据业务场景来处理。 Array 空值一律应为 [] Object 不应返回 null ,比如“人”这个对象有个字段叫“父亲信息”,有的人可能没有父亲,这种情况 “父亲信息” 字段不应返回 null ,而是在“父亲信息”这个对象里面的 “是否存在父亲”字段做判断 总结我的观点:除了 Number 和 Boolean 可以返回 null ,字符串、对象、数组都不应返回 null |
63
liuhuihao 316 天前
@yusheng88 产品和业务决定的应该是 字段是否可以为空,帖子讨论的为空的时候接口是否该返回 null 。很多值为空时候返回其实是可以在接口设计阶段避免的。
个人理解,如字符串 null 和'' 其实是一个含义都表示没填,数组[] 和 null 其实也是一个含义都表示没有。对象则应该在对象内部增加字段判断是否存在,Number 和 Boolean 大多数情况下也不需要返回 null 。 |
64
QlanQ 316 天前
我比较赞同 #58 的观点
接口的基本原则就是 数据结构必须一致,如果你的这个数据定义是 string 那这个值没有设置之前都是 '',不应该是 null 上面有说 如果是 null 就不返回的情况,这种我见了就直接打,你都是强类型语言了,返回的结构还不一样?我在判断一个数据的值是不是真之前,还要考虑这个值存不存在? 两个例子,现在已经有 1w 用户了,突然加了个需求,用户可以弄一个签名,类似 QQ 签名,这个时候,你要加表字段,按楼上一些人说的,那这个用户没有设置过,值应该是 null 是吧,那现在一个用户设了签名,后面又清空了签名,那你在保存用户的签名时候,是改成空字符还是 null ?你返回的数据是什么? 上面提到年龄,如果这个字段的信息是保存用户的年龄,那 null 是什么意思呢? |
65
liuhuihao 316 天前
数据定义和返回必须一致,这个我支持。你可以看下 我 62 楼的回复,有些情况下 null 还是有必要的。比如一个非必填输入框只支持填写任意的数字,那么这种情况下 我这边通常在定义这个字段的时候就定义为 number | null ,用 null 来表示“没有填”。
|
66
xingdaorong 316 天前
@zjsxwc 没听懂啥意思,这个是否被改写的状态真实业务场景的状态是啥,很多不需要这个字段
|
67
yusheng88 316 天前 via Android
@liuhuihao
1. 我的评论应该很清楚,接口该返回 null 就返回 null 2. null 和"不是一个东西,等你什么时候调用接口后不用对 string 返回值判 null 再讨论这个吧。 3. 集合,容器类推荐返回空集合,因为关注的是容器内的元素,而不是容器,容器应该存在的 |
68
liuhuihao 316 天前
@yusheng88 #67 没理解你的意思。我们这边接口针对 string 、数组、对象 类型前端确实是不需要 判 null 的,因为约定的是啥类型返回就是啥类型,空值也一样,string 类型为空时当然应该为空字符串,null 又不是字符串类型,类型定义和数据返回的类型应该一致。
|
69
jones2000 316 天前
null 字段,直接不要返回就不可以了, 还能节省流量。
|
71
lancelock 316 天前
空数字是各什么概念,哪个数字是空的?
|
72
Coder89757 316 天前
@doco #1 主要原因是给了 null 之后,解构取值兜底逻辑会直接失效。。。
```javascript const { str = '' } = response; // 假如 str 直接不存在,对象中连这个属性 key 都没有,前端拿到的 str 就是 undefined ,此时会兜底成空字符串,下面这个语句会正常运作,UI 正常渲染 const newStr = str.replace('foo', 'bar'); // 假如 str 传了 null ,这里直接 error 了,假如这段逻辑在 React 或者 Vue 渲染逻辑里面,这块 UI 直接就白了 ``` 核心问题还是在于,这种做法改变了返回字段的类型,把前端或者客户端,抛进了类型判断的屎山地狱 |