自定义注解+反射提取对象到map中
一、问题:有时候我们与第三方接口对接传参时,需要将对象里的字段和值以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中的更多相关文章
- 利用反射跟自定义注解拼接实体对象的查询SQL
前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...
- Java 自定义注解实现ORM对象关系映射
一,ORM概念 ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关 ...
- 通过自定义注解反射生成SQL语句
----------------------------------------Program.cs---------------------------------------- using Sys ...
- C# - 通过自定义注解反射生成SQL语句[转]
转自http://blog.163.com/jong_cai/blog/static/87028045200902033553581/ -------------------------------- ...
- list中的对象或者map中的版本号排序 version排序
经常会用到版本号排序,直接把他封装成一个工具用起来比较方便. List<A> aList = new ArrayList<>(); ...aList 赋值 ... Collec ...
- 170313、poi:采用自定义注解的方式导入、导出excel(这种方式比较好扩展)
步骤一.自定义注解 步骤二.写Excel泛型工具类 步骤三.在需要导出excel的类属相上加上自定义注解,并设置 步骤四.写service,controller 步骤一:自定义注解 import ja ...
- SpringAOP的自定义注解实践
springaop属于spring的重要属性,在java中有相当广泛的用途,大家一般都接触过aop实现事务的管理,在xml里配好声明式事务,然后直接在service上直接加上相应注解即可, 今天我们来 ...
- ArcGIS Engine中如何获取Map中已经选择的要素呢
1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的FeatureSelection可不是IFeatureSelectio ...
- Map接口----Map中嵌套Map
package cn.good.com; import java.util.HashMap; import java.util.Iterator; import java.util.Map; impo ...
- ArcGIS Engine中如何获取Map中已经选择的要素呢(转)
ArcGIS Engine中如何获取Map中已经选择的要素呢 1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的Fe ...
随机推荐
- I2C接口
I2C是一种多向控制总线,它是由PHILIPS公司在二十世纪八十年代初设计出来的,利用该总线可实现多主机系统所需的裁决和高低速设备同步等功能,是一种高性能的串行总线.I2C总线只用两根双向传输线就可以 ...
- git 的基础使用
配置: 首次安装完git后,需要配置信息 检查配置: git修改: git config --global user.name "Your_username" 重新设置gi ...
- WebAPI例子
1.WebApiConfig配置API路由 using System; using System.Collections.Generic; using System.Linq; using Syste ...
- rancher 修改域名
rancher 修改域名 rancher 修改ingress.nginx 对应的域名后 cattle-system 名称空间下的pod 依然是连接旧环境的rancher 域名 解决办法 1. 需要登录 ...
- centos7.8GPU服务器搭建
首先官方文档有cuda驱动和toolkit和Linux内核本,gcc版本的对应关系,其中也有一些安装过程可参考: https://developer.nvidia.com/cuda-toolkit-a ...
- iOS 防止charles抓包
方案一:检查手机Wifi是否设置了代理 public func fetchHttpProxy() -> Bool { guard let proxy = CFNetwork ...
- CodeGym自学笔记03——变量、数据类型
变量 变量是用来存储数据的特殊实体. 1.在 Java 语言中,所有数据都存储在变量中. 2.最接近的比喻就好比是一个盒子. 3.在 Java 语言中,每个变量都有三个重要的属性:类型.名称和值. - ...
- calendar.getActualMaximum(calendar.DAY_OF_MONTH)的陷阱,2月份最后一天成了3月3号
引用一下别人的链接: https://blog.csdn.net/dongyuxu342719/article/details/78131697
- shell脚本定时任务转移项目日志
1.之前同时项目部署在根目录,根目录磁盘空间40G,运行一年后日志占了18G的磁盘空间, 根目录只有几个G的磁盘空间,现在写shell脚本定时转移日志文件到挂载的磁盘目录下 2.编写shell脚本 # ...
- 雪花算法生成id长度过长处理
思路:将Long类型转成字符串 代码实现: import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.s ...