You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jackson ObjectMapper生成不含下划线的JSON键名

问题

从第三方API获取的JSON键名带下划线且无法修改,但希望在POJO中使用无下划线的属性名。目前将Magazine对象转回JSON时仍会出现下划线,需要实现:输出的JSON键名不含下划线,同时保留POJO中无下划线的属性名(如name而非_name)。

原JSON示例

{
    "_name": "Vogue",
    "authors": ["Jenny Mason", "Craig Hall"],
    "_edition": "plastic-surgery",
    "_unit_price": "!.75",
    "_publication_date": "03/22/2023"
}

原Jackson ObjectMapper配置

public ObjectMapper initMapper(){
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    return mapper;
}

原Magazine类代码

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;

@Data
public class Magazine {
  
   @JsonProperty("name")
   private String _name;
  
   @JsonProperty("authors")
   private List<String> _authors;
   
   @JsonProperty("unitPrice")
   private String _unitPrice;
   
   @JsonProperty("publicationDate")
   private String _publication_date;
   
   @JsonProperty("edition")
   private String _edition;

   public Magazine(String _name, List<String> _authors, String _edition, 
        String _unitPrice, String _publication_date) {
     this._name = _name;
     this._authors = _authors;
     this._edition = _edition;
     this._unitPrice = _unitPrice;
     this._publication_date = _publication_date;
   }
}

解决方案

原代码的核心问题是@JsonProperty注解的使用逻辑颠倒,且POJO属性命名不符合需求。以下提供两种可行方案:

方案1:修正POJO的注解与属性命名

直接调整@JsonProperty的作用:注解值指定反序列化时(JSON转POJO)对应的带下划线键名,POJO属性用无下划线的命名,这样序列化(POJO转JSON)时就会用属性名作为输出键。

修正后的Magazine类:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;

@Data
public class Magazine {
    // 反序列化匹配JSON的"_name",序列化输出"name"
    @JsonProperty("_name")
    private String name;

    // 反序列化匹配JSON的"authors",序列化输出"authors"
    @JsonProperty("authors")
    private List<String> authors;

    // 反序列化匹配JSON的"_unit_price",序列化输出"unitPrice"
    @JsonProperty("_unit_price")
    private String unitPrice;

    // 反序列化匹配JSON的"_publication_date",序列化输出"publicationDate"
    @JsonProperty("_publication_date")
    private String publicationDate;

    // 反序列化匹配JSON的"_edition",序列化输出"edition"
    @JsonProperty("_edition")
    private String edition;

    public Magazine(String name, List<String> authors, String edition, 
                    String unitPrice, String publicationDate) {
        this.name = name;
        this.authors = authors;
        this.edition = edition;
        this.unitPrice = unitPrice;
        this.publicationDate = publicationDate;
    }
}

方案2:统一配置ObjectMapper命名策略

如果不想给每个属性加注解,可以通过配置ObjectMapper的命名策略,实现全局的下划线键与驼峰属性的映射,序列化时直接输出驼峰键名。

调整后的ObjectMapper配置:

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.annotation.JsonInclude;

public ObjectMapper initMapper(){
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
    // 自定义命名策略:反序列化时下划线转驼峰,序列化时保持驼峰输出
    mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
        @Override
        public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
            return PropertyNamingStrategies.SNAKE_CASE.nameForField(config, field, defaultName);
        }

        @Override
        public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
            return defaultName;
        }

        @Override
        public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
            return PropertyNamingStrategies.SNAKE_CASE.nameForSetterMethod(config, method, defaultName);
        }
    });
    return mapper;
}

此时Magazine类可以完全去掉@JsonProperty注解,直接用无下划线的驼峰属性:

import lombok.Data;
import java.util.List;

@Data
public class Magazine {
    private String name;
    private List<String> authors;
    private String unitPrice;
    private String publicationDate;
    private String edition;

    public Magazine(String name, List<String> authors, String edition, 
                    String unitPrice, String publicationDate) {
        this.name = name;
        this.authors = authors;
        this.edition = edition;
        this.unitPrice = unitPrice;
        this.publicationDate = publicationDate;
    }
}

验证效果

两种方案执行后,Magazine对象序列化输出的JSON都会是无下划线的格式:

{
  "name" : "Vogue",
  "authors" : [ "Jenny Mason", "Craig Hall" ],
  "unitPrice" : "!.75",
  "publicationDate" : "03/22/2023",
  "edition" : "plastic-surgery"
}

内容的提问来源于stack exchange,提问作者BreenDeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:17:52