hutool的中有方法BeanUtil.beanToMap()
可以实现,但在实际应用过程中发现,如果要转换的对象中存在List类型的话,集合中的对象是不会转化为下划线格式的。本方法是为了解决这个问题。
BeanUtil.beanToMap()
static Map<String,Object> beanToMap(Object bean, Map<String,Object> targetMap, boolean isToUnderlineCase, boolean ignoreNullValue)
Hutool官网
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
@Slf4j
public class BeanMapUtils {
/**
* 将对象装换为map,支持驼峰命名转下划线
* 支持hutool的@Alias注解
* @param bean 要转换的类
* @param isUnderscore 是否转成蛇形命名
* @return
*/
public static Map<String, Object> bean2Map(Object bean, boolean isUnderscore) {
Map<String, Object> map;
if (isUnderscore) {
String s = JSONUtil.toJsonStr(bean);
bean = JSONUtil.parseObj(s);
try {
map = formatKey((JSONObject) bean, false);
} catch (Exception e) {
log.error("bean2Map 对象装换为map出现错误!!!e:", e);
throw new CalcBusinessException("公共类错误");
}
}else {
map = BeanUtil.beanToMap(bean, false, false);
}
return map;
}
/**
* 转换为驼峰格式/转换为下划线方式
*
* @param json 等待转换的方法
* @param upper 首字母大写或者小写
* @return 转换后的
*/
public static JSONObject formatKey(final JSONObject json, boolean upper) {
JSONObject real = new JSONObject();
for (String it : json.keySet()) {
Object objR = json.get(it);
// 转换为驼峰格式
String key = StrUtil.toUnderlineCase(it);
// 首字母大写或者小写
key = upper ? StrUtil.upperFirst(key) : StrUtil.lowerFirst(key);
if (objR instanceof JSONObject) {
real.set(key, formatKey((JSONObject) objR, upper));
}else if (objR instanceof JSONArray) {
JSONArray jsonA = new JSONArray();
for (Object objA : (JSONArray) objR) {
jsonA.add(formatKey((JSONObject) objA, upper));
}
real.set(key, jsonA);
}else {
real.set(key, objR);
}
}
return real;
}
}
public class MainTest {
/**
* 测试bean2map
*/
@Test
public void test() {
BeanTest beanTest = BeanTest.builder()
.nameAge("nameage").ageName(BigDecimal.ONE).nameAgeTest("test2")
.testRest(CollUtil.newArrayList(BeanTest2.builder().nameAgeTest("2222").build()))
.build();
Map<String, Object> map = BeanMapUtils.bean2Map(beanTest, true);
Console.log(map);
// 结果:{"name_age":"nameage","name_age_test2":"test2","age_name":1,"test_rest2":[{"nameAgeTest":"2222"}]}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BeanTest {
//@Alias("name_age")
private String nameAge;
@Alias("name_age_test2")
private String nameAgeTest;
//@Alias("age_name")
private BigDecimal ageName;
@Alias("test_rest2")
private List<BeanTest2> testRest;
private List<Map<String, BigDecimal>> testMapList;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BeanTest2 {
private String nameAgeTest;
private BigDecimal ageNameTest;
}
formatKey()
方法是由网上的方法(原方法)改过来的,但这个方法有点问题,只支持string类型的转换。hutool在使用JSONUtil.parseObj()
方法时,会将value转为JSONArray
、JSONObject
以及BigDecimal(小数)
、Integer(整数且在int范围内)
、Long(整数且大于int范围)
、Boolean(true or false)
、String(其他)
。