Java对象中转换空值的字段

打印 上一主题 下一主题

主题 937|帖子 937|积分 2811

在后端返回数据给前端时,公司的框架会把值为null的数据去掉,方便前端取值。
如:Person对象为:{name:"浩二", age:24, weight:null, height:114},那返回给前端的就为{name:"浩二", age:24, height:114}。
如果这个时候有个需求:
  Integer类型的字段为null给-1
  Long类型的字段为null给-1L
  String类型的字段为null给""(空字符串)
  对象类型的字段为null给new对象,
不能直接动框架,因此需要手动转化。
 
代码写死转换

这种是最简单的方式,顾名思义,写死代码的方式一个一个字段来转换
示例

转换对象 ConvertNullFiledInfo
  1. @Data
  2. public class ConvertNullFiledInfo {
  3.     private Integer intNum;
  4.     private Long longNum;
  5.     private String str;
  6.     private ConvertNullFiledInfo info;
  7. }
复制代码
转换代码
  1. @Service
  2. public class ConvertNullFiledService {
  3.     /**
  4.      * 写死代码的方式一个一个字段来转换
  5.      * @param info
  6.      * @return
  7.      */
  8.     public ConvertNullFiledInfo convertFunction01(ConvertNullFiledInfo info) {
  9.         info.setIntNum(info.getIntNum() == null ? -1 : info.getIntNum());
  10.         info.setLongNum(info.getLongNum() == null ? -1L : info.getLongNum());
  11.         info.setStr(info.getStr() == null ? "" : info.getStr());
  12.         info.setInfo(info.getInfo() == null ? new ConvertNullFiledInfo() : info.getInfo());
  13.         return info;
  14.     }
  15.    
  16. }
复制代码
测试代码
  1. import org.junit.Test;
  2. import org.junit.runner.RunWith;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.test.context.junit4.SpringRunner;
  6. @SpringBootTest
  7. @RunWith(SpringRunner.class)
  8. public class ConvertNullFiledServiceTest {
  9.     @Autowired
  10.     private ConvertNullFiledService convertNullFiledService;
  11.     @Test
  12.     public void convertFunction01() {
  13.         // str和info字段给null
  14.         ConvertNullFiledInfo info = createConvertNullFiledInfo(1, 1L, null, null);
  15.         ConvertNullFiledInfo result = convertNullFiledService.convertFunction01(info);
  16.         System.out.println(result);
  17.     }
  18.     /**
  19.      * 自定义字段创建ConvertNullFiledInfo
  20.      * @param intNum
  21.      * @param longNum
  22.      * @param str
  23.      * @param info
  24.      * @return
  25.      */
  26.     private ConvertNullFiledInfo createConvertNullFiledInfo(Integer intNum, Long longNum, String str, ConvertNullFiledInfo info) {
  27.         ConvertNullFiledInfo result = new ConvertNullFiledInfo();
  28.         result.setIntNum(intNum);
  29.         result.setLongNum(longNum);
  30.         result.setStr(str);
  31.         result.setInfo(info);
  32.         return result;
  33.     }
  34.    
  35. }
复制代码
运行结果

可以看到是正常转换了的
问题点

这样写虽然简单方便,但是如果有非常多的对象需要转换,就会有许多重复代码;
而且如果字段有修改(类型、名称、被删除、新增),就需要在去转换方法中修改,因此可以用更好的方式。
 
遍历Filed转换

所有对象都有Class类,而Class有getDeclaredFields()方法,能获取到所有字段(filed),
因此可以使用这种方式来转换。
示例

转换代码
  1. /**
  2.      * 遍历field的方式一个一个字段来转换
  3.      * @param info
  4.      * @return
  5.      */
  6.     public ConvertNullFiledInfo convertByField(ConvertNullFiledInfo info) {
  7.         try {
  8.             Field[] fields = info.getClass().getDeclaredFields();
  9.             for (Field field : fields) {
  10.                 // 设置可访问私有变量
  11.                 field.setAccessible(true);
  12.                 // 获取当前字段值
  13.                 Object value = field.get(info);
  14.                 // value不为空就跳过
  15.                 if (value != null) {
  16.                     continue;
  17.                 }
  18.                 // 获取当前字段类型
  19.                 Class<?> type = field.getType();
  20.                 if (type == Integer.class) {
  21.                     // Integer类型就设置为-1
  22.                     field.set(info, -1);
  23.                 } else if (type == Long.class) {
  24.                     // Long类型就设置为-1L
  25.                     field.set(info, -1L);
  26.                 } else if (type == String.class) {
  27.                     // String类型就设置为“”
  28.                     field.set(info, "");
  29.                 } else if (type == ConvertNullFiledInfo.class) {
  30.                     // ConvertNullFiledInfo类型就设置为新对象
  31.                     field.set(info, new ConvertNullFiledInfo());
  32.                 }
  33.             }
  34.         } catch (Exception e) {
  35.             e.printStackTrace();
  36.         }
  37.         return info;
  38.     }
复制代码
测试代码
  1. @Test
  2. public void convertByField() {
  3.     // str和info字段给null
  4.     ConvertNullFiledInfo info = createConvertNullFiledInfo(1, 1L, null, null);
  5.     ConvertNullFiledInfo result = convertNullFiledService.convertByField(info);
  6.     System.out.println(result);
  7. }
复制代码
运行结果

可以看到也是成功转换了
问题点

这种写法仍然存在问题,可以看到方法的传参和返回值都是固定类型为ConvertNullFiledInfo,
并且在遍历field的时候,也有if判断是写定的ConvertNullFiledInfo,
因此也在一定程度上写死了代码
优化

为了避免写死的情况,可以使用泛型来写
转换代码
  1. @Service
  2. public class ConvertNullFiledService<T> {
  3.    
  4.     /**
  5.      * 使用泛型,遍历field的方式一个一个字段来转换
  6.      * @param object
  7.      * @return
  8.      */
  9.     public T convertByFieldGeneric(T object) {
  10.         try {
  11.             Field[] fields = object.getClass().getDeclaredFields();
  12.             for (Field field : fields) {
  13.                 // 设置可访问私有变量
  14.                 field.setAccessible(true);
  15.                 // 获取当前字段值
  16.                 Object value = field.get(object);
  17.                 // value不为空就跳过
  18.                 if (value != null) {
  19.                     continue;
  20.                 }
  21.                 // 获取当前字段类型
  22.                 Class<?> type = field.getType();
  23.                 if (type == Integer.class) {
  24.                     // Integer类型就设置为-1
  25.                     field.set(object, -1);
  26.                 } else if (type == Long.class) {
  27.                     // Long类型就设置为-1L
  28.                     field.set(object, -1L);
  29.                 } else if (type == String.class) {
  30.                     // String类型就设置为“”
  31.                     field.set(object, "");
  32.                 } else if (type == object.getClass()) {
  33.                     // T类型就设置为新对象
  34.                     Object newObj = object.getClass().newInstance();
  35.                     field.set(object, newObj);
  36.                 }
  37.             }
  38.         } catch (Exception e) {
  39.             e.printStackTrace();
  40.         }
  41.         return object;
  42.     }
  43. }
复制代码
测试代码
  1. @Test
  2. public void convertByFieldGeneric() {
  3.     // 全部字段给null
  4.     ConvertNullFiledInfo info = createConvertNullFiledInfo(null, null, null, null);
  5.     ConvertNullFiledInfo result = (ConvertNullFiledInfo) convertNullFiledService.convertByFieldGeneric(info);
  6.     System.out.println(result);
  7. }
复制代码
运行结果

成功转换
 
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

道家人

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表