一、问题:有时候我们与第三方接口对接传参时,需要将对象里的字段和值以map形式传给别人,此时可以借助其他的工具类,但是我个人用起来不太灵活,还会把多余的字段传给别人,因此我们自己动手搞一套

二、思路

  1.别人的字段定义和我们定义的名称可能不一样,字段名称需要能够自定义;

  2.要能够忽略对象里面的字段;

  3.要能支持对字段做简单的非空校验;

  4.复杂的pojo需要递归,这里只考虑简单的pojo对象。

三、步骤

1.定义字段的注解


/**
* 字段转化适配
*
* @author xuzhangxing
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldMask {

// 指定新的字段名,如果不指定就取原字段名
String value() default "";

// 是否忽视这个字段
boolean ignore() default false;

// 字段为空时是否仍然需要放入map中,默认是不放入
boolean nullIgnore() default false;

// 是否必传,如果设置true 值为null时会抛出异常
boolean required() default false;
}

2.通过反射转成map



import java.lang.reflect.Field;
import java.util.*;

/**
* 字段转map 且能够自定义字段名称或者直接忽视该字段
*
* @author xuzhangxing
*/
public final class ParamMapUtil {

public static List<Field> getAllFields(Class<?> cls) {
final List<Field> allFields = new ArrayList<>();
Class<?> currentClass = cls;
while (currentClass != null) {
final Field[] declaredFields = currentClass.getDeclaredFields();
Collections.addAll(allFields, declaredFields);
currentClass = currentClass.getSuperclass();
}
return allFields;
}

public static Map<String, Object> generateMap(Object target) {
Map<String, Object> result = new HashMap<>();
if (target == null) {
return result;
}
List<Field> allFields = getAllFields(target.getClass());
for (Field field : allFields) {
Object fieldObj;
field.setAccessible(Boolean.TRUE);
try {
fieldObj = field.get(target);
} catch (IllegalAccessException e) {
throw new RuntimeException("ParamMapUtil 获取field 值异常-->" + e.getMessage());
} finally {
field.setAccessible(Boolean.FALSE);
}

FieldMask[] fieldMasks = field.getAnnotationsByType(FieldMask.class);
if (fieldMasks.length > 0) {
FieldMask fieldMask = fieldMasks[0];
if (fieldMask.ignore()) {
continue;
}
// 如果需要非空校验且该字段为空时,抛出异常
if (fieldMask.required() && fieldObj == null) {
throw new RuntimeException("参数" + field.getName() + "必填");
}

// 字段为空时,是否还放入map中
if (fieldObj == null && fieldMask.nullIgnore()) {
continue;
}

// 是否重命名了
String fieldName = fieldMask.value();
if (fieldName == null || fieldName.length() < 1) {
result.put(field.getName(), fieldObj);
} else {
result.put(fieldName, fieldObj);
}
} else {
// 默认所有字段都加进去,需要忽略字段时,标注FieldMask注解且ignore设置成true
result.put(field.getName(), fieldObj);
}
}
return result;
}

}

三、测试

1 pojo

/**
* @author xuzhangxing
*/
public class UserDTO {
@FieldMask("Name")
private String name;
@FieldMask(required = true)
private String age;
@FieldMask(nullIgnore = true)
private String height;
private String email;
@FieldMask(ignore = true)
private String password; // ...geter setter
}

2. 方法调用:

    public static void main(String[] args) {
UserDTO userDTO = new UserDTO();
userDTO.setName("xzx");
userDTO.setAge("12");
userDTO.setEmail("123@qq.com");
userDTO.setPassword("123456");
Map<String, Object> generateMap = ParamMapUtil.generateMap(userDTO);
System.out.println(generateMap);
}

3.结果:

{age=12, email=123@qq.com, Name=xzx}

四、总结

  1、map中的字段可以通过注解控制字段是否重命名,字段是否直接忽略,字段为空是否抛出异常,字段为空是否不放入map

  2、注意如果不标注注解,默认是放入map中

自定义注解+反射提取对象到map中的更多相关文章

  1. 利用反射跟自定义注解拼接实体对象的查询SQL

    前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...

  2. Java 自定义注解实现ORM对象关系映射

    一,ORM概念 ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关 ...

  3. 通过自定义注解反射生成SQL语句

    ----------------------------------------Program.cs---------------------------------------- using Sys ...

  4. C# - 通过自定义注解反射生成SQL语句[转]

    转自http://blog.163.com/jong_cai/blog/static/87028045200902033553581/ -------------------------------- ...

  5. list中的对象或者map中的版本号排序 version排序

    经常会用到版本号排序,直接把他封装成一个工具用起来比较方便. List<A> aList = new ArrayList<>(); ...aList 赋值 ... Collec ...

  6. 170313、poi:采用自定义注解的方式导入、导出excel(这种方式比较好扩展)

    步骤一.自定义注解 步骤二.写Excel泛型工具类 步骤三.在需要导出excel的类属相上加上自定义注解,并设置 步骤四.写service,controller 步骤一:自定义注解 import ja ...

  7. SpringAOP的自定义注解实践

    springaop属于spring的重要属性,在java中有相当广泛的用途,大家一般都接触过aop实现事务的管理,在xml里配好声明式事务,然后直接在service上直接加上相应注解即可, 今天我们来 ...

  8. ArcGIS Engine中如何获取Map中已经选择的要素呢

    1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的FeatureSelection可不是IFeatureSelectio ...

  9. Map接口----Map中嵌套Map

    package cn.good.com; import java.util.HashMap; import java.util.Iterator; import java.util.Map; impo ...

  10. ArcGIS Engine中如何获取Map中已经选择的要素呢(转)

    ArcGIS Engine中如何获取Map中已经选择的要素呢   1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的Fe ...

随机推荐

  1. SFC-系统文件检查器

    Microsoft (R) Windows (R) Resource Checker 6.0 版 版权所有 (C) Microsoft Corporation.保留所有权利. 扫描所有保护的系统文件的 ...

  2. File类-绝对路径 相对路径

    绝对路径:通过给定的路径能够直接在我的电脑中找到的文件 相对路径:文件相对于应用程序的路径 结论: 我们在开发中要尽量使用相对路径 File方法只能读取小文件,是一下子全读出来.如果读大文件则使用文件 ...

  3. VUE学习-优化组件

    组件(优化) 动态组件 keep-alive 当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题. 有时我们更希望那些标签的组件实例能够被在它们第一次被创建的时候 ...

  4. Intel与AMD之间的故事

    本人中文作文水平仅仅达到小学一年级,通俗易懂,不会术语,对于外行人特别友好,内行人不吝赐教,多谢指正! 背景:Intel(CPU制造商大哥),AMD(二哥,yes) 诺伊斯(Intel创始人,集成电路 ...

  5. kubectl查询日志命令

    防水堡 bug日志定位命令: docker logs --tail 100 xxx:xxx 是容器的id 或者名称kubectl logs-f --tail 100 xxx:xxx 是pod 的id, ...

  6. 八、常用Api

    Object 深拷贝和浅拷贝 Objects 包装类 StringBuilder StringJoin Math System RuntimeBigDecimal Date SImpleDateFor ...

  7. shell脚本:报错syntax error near unexpected token `$'\r''解决方法

    之前的shell脚本是在服务器上编写的,后来又已复制的方式存在在了电脑上,以txt文件的形式存放的.于是复制到了编辑工具中,进行了相应项的修改.修改完毕后,拿到服务器上测试,结果执行sh XXX.sh ...

  8. MavenDependencies 报错缺少jar包

    1.首先看你的工程是否是maven项目,如果不是,则先转换为maven项目. 如果已经是maven项目了,maven的依赖库无法添加,则移步2: 2.项目右键,选择maven,然后子菜单,选择&quo ...

  9. 单个Java文件连接数据库demo

      在单个java文件中,尝试连接数据库,跟python的模块包安装方式很接近,已经测试成功,把博客写一下,记录下来.   首先把jdb的驱动包下载下来,就是一个jar包,下面是官网下载地址 官网下载 ...

  10. vue 数组对象深拷贝 并根据某项属性排序

    vue 数组对象深拷贝 并根据某项属性   serialNumber  排序 原始数据 navListData: [ { name: '企业速览', isHot: false, isVip: fals ...