Java的驼峰与下划线的属性对象互相转换



import com.xxxx.util.constant.PropertyNameStyle;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

@Slf4j
public class GenericPropertyConverter {

public static final char UNDERLINE_CHAR = '_';

public static <T> T convertObject(Object originObj, PropertyNameStyle originStyle, Class<T> targetClass) {

return baseConvertObject(originObj, originStyle, targetClass, null, null);
}

public static <T, F> List<T> convertObject(List<F> originLst, PropertyNameStyle originStyle, Class<T> targetClass) {
if (Objects.isNull(originLst)) {
return null;
}
List<T> result = Lists.newArrayListWithCapacity(originLst.size());
originLst.forEach(o -> result.add(convertObject(o, originStyle, targetClass)));
return result;
}

/**
*
* @param originObj 待转换的源对象,【不可为null】
* @param originStyle 源对象的property的命名风格,【不可为null】
* @param targetClass 目标对象,【不可为null】FieldNamingPolicy
* @param customizePropertyNameMap 自定义转换属性,【可为null】
* @param excludePropertyNameList 自定义的排除属性,【可为null】
* @return
*/
public static <T> T baseConvertObject(Object originObj, PropertyNameStyle originStyle, Class<T> targetClass,
Map<String, String> customizePropertyNameMap, List<String> excludePropertyNameList) {

T targetObj;
try {
targetObj = targetClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {

log.error("通用的风格属性名转换时出错\n{}", e.getMessage());
return null;
}

Class<?> originClass = originObj.getClass();
PropertyDescriptor[] originPds = BeanUtils.getPropertyDescriptors(originClass),
targetPds = BeanUtils.getPropertyDescriptors(targetClass);
Function<String, String> propertyConvertFunc = PropertyNameStyle.CAMEL.equals(originStyle)
? GenericPropertyConverter::camel2Underline
: GenericPropertyConverter::underline2Camel;
for (PropertyDescriptor originPd : originPds) {

String propertyName = originPd.getName();
if ("class".equals(propertyName)) {

continue;
}

if (CollectionUtils.isNotEmpty(excludePropertyNameList) && excludePropertyNameList.contains(propertyName)) {

continue;
}

String newPropertyName = StringUtils.EMPTY;
if (MapUtils.isNotEmpty(customizePropertyNameMap)) {

newPropertyName = customizePropertyNameMap.get(propertyName);
}
if (StringUtils.isBlank(newPropertyName)) {

newPropertyName = propertyConvertFunc.apply(propertyName);
}
if (StringUtils.isBlank(newPropertyName)) {

continue;
}

Class<?> originPropertyType = originPd.getPropertyType();
for (PropertyDescriptor targetPd : targetPds) {

if (newPropertyName.equals(targetPd.getName()) == false) {

continue;
}

Method originReadMethod = originPd.getReadMethod(),
targetWriteMethod = targetPd.getWriteMethod();
if (originReadMethod != null && targetWriteMethod != null
&& ClassUtils.isAssignable(targetWriteMethod.getParameterTypes()[0], originPropertyType)) {

try {
if (Modifier.isPublic(originReadMethod.getDeclaringClass().getModifiers()) == false) {

originReadMethod.setAccessible(true);
}
Object value = originReadMethod.invoke(originObj);
if (Modifier.isPublic(targetWriteMethod.getDeclaringClass().getModifiers()) == false) {

targetWriteMethod.setAccessible(true);
}
targetWriteMethod.invoke(targetObj, value);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {

log.error("通用的风格属性名转换时出错\n{}", e1.getMessage());
return null;
}
}
}
}
return targetObj;
}

/**
* 驼峰转下划线
*
* @param camelStr
* @return
*/
public static String camel2Underline(String camelStr) {

if (StringUtils.isEmpty(camelStr)) {

return StringUtils.EMPTY;
}

int len = camelStr.length();
StringBuilder strb = new StringBuilder(len + len >> 1);
for (int i = 0; i < len; i++) {

char c = camelStr.charAt(i);
if (Character.isUpperCase(c)) {

strb.append(UNDERLINE_CHAR);
strb.append(Character.toLowerCase(c));
} else {

strb.append(c);
}
}
return strb.toString();
}

/**
* 下划线转驼峰
*
* @param underlineStr
* @return
*/
public static String underline2Camel(String underlineStr) {

if (StringUtils.isEmpty(underlineStr)) {

return StringUtils.EMPTY;
}

int len = underlineStr.length();
StringBuilder strb = new StringBuilder(len);
for (int i = 0; i < len; i++) {

char c = underlineStr.charAt(i);
if (c == UNDERLINE_CHAR && (++i) < len) {

c = underlineStr.charAt(i);
strb.append(Character.toUpperCase(c));
} else {

strb.append(c);
}
}
return strb.toString();
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Spring Boot开发中,我们经常需要将JSON对象转换Java对象或反之亦然。但是,在JSON和Java对象之间转换的过程中,往往会遇到下划线驼峰命名风格的差异问题。这个时候,我们可以使用Spring Boot自带的Jackson库进行转换。下面我将详细介绍如何在Spring Boot中使用Jackson库进行下划线驼峰格式的转换。 1. 下划线转换驼峰Spring Boot中,使用Jackson库进行下划线驼峰命名格式的转换,需要在配置文件中进行配置,首先我们需要在application.yaml配置文件中添加以下内容: ```yaml # 进行下划线转换驼峰 spring: jackson: property-naming-strategy: com.fasterxml.jackson.databind.PropertyNamingStrategy$SnakeCaseStrategy ``` 添加这段配置代码后,就可以实现下划线转换驼峰。在进行Java对象与JSON字符串之间的转换时,JSON字符串的下划线将会自动转换Java对象驼峰命名格式,例如,原本`user_name`的JSON字段在Java对象中将会变成`userName`。 2. 驼峰转换下划线进行Java对象与JSON字符串之间的转换时,我们也可以将Java对象中的驼峰命名格式转换为JSON字符串中的下划线。要实现这个功能,我们需要在配置文件中加入以下代码: ```yaml # 进行驼峰转换下划线 spring: jackson: property-naming-strategy: com.fasterxml.jackson.databind.PropertyNamingStrategy$SNAKE_CASE ``` 这时候,在进行Java对象与JSON字符串之间的转换时,Java对象中的驼峰命名格式就会被自动转换成JSON字符串中的下划线格式,例如,Java对象中的`userName`字段会自动被转换成JSON字符串中的`user_name`。 总结: 在Spring Boot中,使用Jackson库进行下划线驼峰命名格式的转换,只需要在application.yaml配置文件中添加一段内容即可。设置`com.fasterxml.jackson.databind.PropertyNamingStrategy$SnakeCaseStrategy`可以将下划线转换Java对象驼峰命名格式,而将`com.fasterxml.jackson.databind.PropertyNamingStrategy$SNAKE_CASE`设置为属性命名策略,则可以将Java对象中的驼峰命名格式自动转换成JSON字符串中的下划线格式。这样的配置可以很方便地适应不同的数据接口和Java对象

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值