Jackson修改字段名和自定义命名
参考:
https://heapdump.cn/article/1922495?from=mobile
1 实现方式
- 使用@JsonProperty指定固定的名称进行名称映射;
- 使用预定义的命名策略PropertyNamingStrategy
- 扩展PropertyNamingStrategy,实现自定义命名策略。
2 说明及示例
2.1 @JsonProperty
测试实体类:
@Data
@Accessors(chain = true)
public class User {
private String name;
private int age;
private String idCard;
}
一个简单的测试类:
public class TestNaming {
public static void main(String[] args) throws JsonProcessingException {
User user = new User().setAge(11)
.setName("小明")
.setIdCard("13523451124");
System.out.println("原始json:" + new ObjectMapper().writeValueAsString(user));
}
}
运行结果如下:
原始json:{"age":11,"idCard":"13523451124","nameStr":"小明"}
添加@JsonProperty注解:
@Data
@Accessors(chain = true)
public class User {
@JsonProperty(value = "nameStr")
private String name;
@JsonProperty(value = "ageStr")
private int age;
private String idCard;
}
再次执行测试类,运行结果如下,字段名称显示的为注解上设置的名称:
原始json:{"idCard":"13523451124","nameStr":"小明","ageStr":11}
2.2 预定义命名策略PropertyNamingStrategy
- 说明:
如果被操作的字段,都需要遵循相同的命名规则,那么可以使用命名策略PropertyNamingStrategy来简化命名操作。具体的策略如下:
策略 | 说明 | 示例 |
---|---|---|
SNAKE_CASE | 小写字母,下划线分割 | user_name |
UPPER_CAMEL_CASE | 字段首字母大写,单词之间不适用分隔符 | UserName |
LOWER_CAMEL_CASE | 字段首字母小写,单词之间不使用分隔符 | userName |
LOWER_CASE | 单词都用小写,单词之间不使用分隔符 | username |
KEBAB_CASE | 单词用小写字母,用连字符分隔 | user-name |
LOWER_DOT_CASE | 单词以小写字母表示,由点分隔 | user.name |
- 示例
实体类:
@Data
@Accessors(chain = true)
public class User {
private String userName;
private int userAge;
private String userIdCard;
}
测试类:
public class TestNaming {
public static void main(String[] args) throws JsonProcessingException {
User user = new User().setUserAge(11)
.setUserName("小明")
.setUserIdCard("13523451124");
System.out.println("原始json:" + new ObjectMapper().writeValueAsString(user));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
System.out.println("SNAKE_CASE:" + objectMapper.writeValueAsString(user));
ObjectMapper objectMapper1 = new ObjectMapper();
objectMapper1.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
System.out.println("UPPER_CAMEL_CASE:" + objectMapper1.writeValueAsString(user));
ObjectMapper objectMapper2 = new ObjectMapper();
objectMapper2.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE);
System.out.println("LOWER_CAMEL_CASE:" + objectMapper2.writeValueAsString(user));
ObjectMapper objectMapper3 = new ObjectMapper();
objectMapper3.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
System.out.println("LOWER_CASE:" + objectMapper3.writeValueAsString(user));
ObjectMapper objectMapper4 = new ObjectMapper();
objectMapper4.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE);
System.out.println("KEBAB_CASE:" + objectMapper4.writeValueAsString(user));
ObjectMapper objectMapper5 = new ObjectMapper();
objectMapper5.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_DOT_CASE);
System.out.println("LOWER_DOT_CASE:" + objectMapper5.writeValueAsString(user));
}
}
运行结果:
原始json:{"userName":"小明","userAge":11,"userIdCard":"13523451124"}
SNAKE_CASE:{"user_name":"小明","user_age":11,"user_id_card":"13523451124"}
UPPER_CAMEL_CASE:{"UserName":"小明","UserAge":11,"UserIdCard":"13523451124"}
LOWER_CAMEL_CASE:{"userName":"小明","userAge":11,"userIdCard":"13523451124"}
LOWER_CASE:{"username":"小明","userage":11,"useridcard":"13523451124"}
KEBAB_CASE:{"user-name":"小明","user-age":11,"user-id-card":"13523451124"}
LOWER_DOT_CASE:{"user.name":"小明","user.age":11,"user.id.card":"13523451124"}
2.3 自定义命名
只需要继承PropertyNamingStrategy.PropertyNamingStrategyBase,并实现translate()方法即可:
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
public class SysLogNamingBaseTest extends PropertyNamingStrategy.PropertyNamingStrategyBase {
@Override
public String translate(String propertyName) {
return propertyName + "_";
}
}
2.3.1 示例1
测试实体类:
@Data
@Accessors(chain = true)
public class User {
private String name;
private int age;
private String idCard;
}
重命名类:
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
/**
* <pre>
* json key值重命名
* </pre>
*
* @author loopy_y
* @since 2023/3/17
*/
public class SysLogNamingBase extends PropertyNamingStrategy.PropertyNamingStrategyBase {
@Override
public String translate(String propertyName) {
return propertyName + "^";
}
}
测试类:
public class TestNaming {
public static void main(String[] args) throws JsonProcessingException {
User user = new User().setAge(11)
.setName("小明")
.setIdCard("13523451124");
System.out.println("原始json:" + new ObjectMapper().writeValueAsString(user));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(new SysLogNamingBase());
System.out.println("替换后的json:" + objectMapper.writeValueAsString(user));
}
}
测试结果:
原始json:{"name":"小明","age":11,"idCard":"13523451124"}
替换后的json:{"name^":"小明","age^":11,"idCard^":"13523451124"}
2.3.2 示例2
测试实体类:
@Data
@Accessors(chain = true)
public class User {
private String name;
private int age;
private String idCard;
}
重命名类:
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
/**
* <pre>
* 日志参数名称替换
* </pre>
*
* @author loopy_y
* @since 2023/3/17
*/
public class SysLogNamingBase extends PropertyNamingStrategy.PropertyNamingStrategyBase {
private Map<String, String> keyInfoMap;
public SysLogNamingBase(Map<String, String> map) {
this.keyInfoMap = map;
}
@Override
public String translate(String propertyName) {
if (CollUtil.isNotEmpty(keyInfoMap)) {
if (keyInfoMap.containsKey(propertyName) && StringUtils.isNotBlank(keyInfoMap.get(propertyName))) {
return keyInfoMap.get(propertyName);
}
}
return propertyName;
}
}
测试类:
public class TestNaming {
public static void main(String[] args) throws JsonProcessingException {
User user = new User().setAge(11)
.setName("小明")
.setIdCard("13523451124");
System.out.println("原始json:" + new ObjectMapper().writeValueAsString(user));
Map<String, String> nameMap = new HashMap<>();
nameMap.put("name", "姓名");
nameMap.put("age", "年龄");
nameMap.put("idCard", "身份证号");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(new SysLogNamingBase(nameMap));
System.out.println("替换后的json:" + objectMapper.writeValueAsString(user));
}
}
测试结果:
原始json:{"name":"小明","age":11,"idCard":"13523451124"}
替换后的json:{"姓名":"小明","年龄":11,"身份证号":"13523451124"}