
导言:看过前几篇自定义注解文章的同学, 应该能感受到JsonSerialize 注解的强大, 本篇将介绍另一个对应的注解JsonDeserializer的强大功能. 这俩注解可以配合着使用, 让你的代码在序列化或反序列化时, 无比的优雅.场景:回忆和前端对接口时, 经常会遇到以下这种场景 : 有一组字段我定义的数据类型是String类型如果选择了一个传单个数字如果多选了需要用逗号分隔比如1,2,3来传值。但是后来对接的时候前端那边说他那边不好处理多选的想要传数组。然而我后边的逻辑都写好了修改的话还需要自己手动一个一个的将数组转为逗号分隔的字符串。这样做是可以但是显得很不优雅。废话不多说,上代码:自定义序列化与反序列化策略类:/** * 序列化时 逗号拼接转数组 0,1,2 - [0,1,2] * * author Lynn * date 2022/11/8 14:45 */NoArgsConstructorpublicclassStringToArraySerializerextendsJsonSerializerString{Overridepublicvoidserialize(Stringstr,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider)throwsIOException{if(StringUtils.isNotBlank(str)){String[]splitstr.split(,);jsonGenerator.writeArray(split,0,split.length);}else{jsonGenerator.writeArray(newString[0],0,0);}}}/** * 反序列化时 将数组转为逗号拼接 [0,1,2] - 0,1,2 * * author Lynn * date 2022/11/8 14:36 */NoArgsConstructorpublicclassArrayToStringDeserializerextendsJsonDeserializerString{OverridepublicStringdeserialize(JsonParserjsonParser,DeserializationContextdeserializationContext)throwsIOException,JsonProcessingException{TreeNodetreeNodejsonParser.getCodec().readTree(jsonParser);if(treeNodeinstanceofIntNode){return((IntNode)treeNode).asText();}elseif(treeNodeinstanceofLongNode){return((LongNode)treeNode).asText();}elseif(treeNodeinstanceofDoubleNode){return((DoubleNode)treeNode).asText();}elseif(treeNodeinstanceofArrayNode){//字符串数组会多出两个引号需要手动去除returnStringUtils.replace(StringUtils.join((ArrayNode)treeNode,,),\,);}elseif(treeNodeinstanceofTextNode){return((TextNode)treeNode).asText();}return;}}自定义数组与逗号拼接字符串自动转化注解:该注解适用于序列化/反序列化场景, 说人话就是解析前端传参以及接口返回对象时./** * 数组和逗号拼接转换注解 * * author Lynn * date 2022/11/8 14:11 */DocumentedTarget(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)JacksonAnnotationsInsideJsonSerialize(usingStringToArraySerializer.class)JsonDeserialize(usingArrayToStringDeserializer.class)publicinterfaceStringArrayConvert{}具体使用:解析入参: 无论前端传 [“0,1,2”] / “0,1,2” 都会转为 “0,1,2”/** * author Lynn * date 2022/8/30 18:35 */DataEqualsAndHashCode(callSupertrue)publicclassProductGroupAddRequestextendsDataBaseRequest{/** * app来源 */StringArrayConvertNotBlank(message展示途经不能为空)EnumValid(message展示途经输入错误,enumClassAppSourceEnum.class)privateStringappSource;}返回出参: 将 “0,1,2” 转化为 [“0,1,2”]/** * author Lynn * date 2022/8/30 16:53 */DatapublicclassProductGroupTreeResponse{/** * app来源 */StringArrayConvertprivateStringappSource;}由此场景可以推广, 但凡前端想要的数据模型和后端定义的不一致, 都可以在序列化与反序列化时, 用自定义序列化类做处理, 这样可以简化业务代码.