Java Jackson ObjectMapper大小写问题

Java Jackson ObjectMapper大小写问题,java,json,jackson,Java,Json,Jackson,当我序列化/反序列化任何对象时,所有字段名都转换为小写。 是否有任何配置可以让Jackson保持字段名的原样?用于序列化和反序列化 (我知道@JsonProperty,但这似乎不对,因为我需要的只是让Jackson尊重已经存在的东西) 我的测试代码: import java.io.Serializable; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.dat

当我序列化/反序列化任何对象时,所有字段名都转换为小写。 是否有任何配置可以让Jackson保持字段名的原样?用于序列化和反序列化

(我知道@JsonProperty,但这似乎不对,因为我需要的只是让Jackson尊重已经存在的东西)

我的测试代码:

import java.io.Serializable;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;

public class Test {

    static class Example implements Serializable {
        private String Test;
        private String ABC;
        private String XyZ;

        public String getTest() { return Test; }
        public void setTest(String test) { Test = test; }

        public String getABC() { return ABC; }
        public void setABC(String abc) { ABC = abc; }

        public String getXyZ() { return XyZ; }
        public void setXyZ(String xyz) { XyZ = xyz; }
    }

    static class MyPropertyNamingStrategy extends PropertyNamingStrategy {
        @Override
        public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
            return convert(defaultName);
        }
        @Override
        public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
            return convert(defaultName);
        }
        @Override
        public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
            return convert(defaultName);
        }
        private String convert(String input) {
            return input;
        }
    }

    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper()
        .setPropertyNamingStrategy(new MyPropertyNamingStrategy())
        .enable(SerializationFeature.INDENT_OUTPUT)
        .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);      

        //From OBJECT to JSON
        Example ex = new Example();
        ex.setTest("1");
        ex.setABC("2");
        ex.setXyZ("3");
        System.out.println(objectMapper.writeValueAsString(ex));

        //FROM JSON to OBJECT
        String jsonString = "{ \"Test\":\"0\", \"ABC\":\"1\", \"XyZ\":\"2\" }";
        Example fEx = objectMapper.readValue(jsonString, Example.class);
    }   

}

我认为这就是解决方案(使用自定义属性命名策略):

私家侦探

public class PrivatePerson {
    private String firstName;
    private String lastName;

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }
}

我也有同样的问题

这是我的解决方案:

public class MyNamingStrategy extends PropertyNamingStrategy {

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return field.getName();
    }

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

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

    private String convert(AnnotatedMethod method, String defaultName) {

        Class<?> clazz = method.getDeclaringClass();
        List<Field> flds = FieldUtils.getAllFieldsList(clazz);
        for (Field fld : flds) {
            if (fld.getName().equalsIgnoreCase(defaultName)) {
                return fld.getName();
            }
        }

        return defaultName;
    }
}
公共类MyNamingStrategy扩展了PropertyNamingStrategy{
@凌驾
公共字符串名称字段(MapperConfig配置,AnnotatedField字段,字符串默认名称){
返回字段。getName();
}
@凌驾
公共字符串名称遗忘方法(MapperConfig配置,AnnotatedMethod方法,字符串默认名称){
返回转换(方法、默认名称);
}
@凌驾
SetterMethod的公共字符串名称(MapperConfig配置、AnnotatedMethod方法、字符串defaultName){
返回转换(方法、默认名称);
}
私有字符串转换(AnnotatedMethod方法,String defaultName){
Class clazz=method.getDeclaringClass();
List flds=FieldUtils.getAllFieldsList(clazz);
对于(现场fld:fld){
if(fld.getName().equalsIgnoreCase(defaultName)){
返回fld.getName();
}
}
返回defaultName;
}
}

在这种情况下,您将获得属性的确切名称,而不必依赖于方法的正确名称

您可以将Jackson配置为区分大小写:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

尽管
@JsonProperty
不起作用,我还是能够使用
@JsonSetter
@JsonGetter
映射大写的json字段名

@JsonSetter("ABC")
public void setABC(String ABC) {
    this.ABC= ABC;
}

Spring现在将对象字段序列化为“ABC”而不是“ABC”。

实现了一个自定义,也许您是如何使用@JsonProperty的?你是在传递字符串字段名吗?我看不到一种方法来实现PropertyNamingStrategy来正确匹配字段名。如果一个字段名为“ABC”,另一个字段名为XYz,则在序列化/反序列化时,它们将与JSON不匹配。现在,这些字段都是大写的。序列化和反序列化只有在类字段都是大写的情况下才起作用。是否尝试更改convert方法以返回输入?私有字符串转换(字符串输入){return input;}是的。不同之处在于它们现在都是小写的。不尊重大小写,或者它们都是大写、小写或Pascal(第一个字母大写)。。。但是仅仅尊重这个案例是没有办法的。我找到了解决方案并编辑了代码。我已经更改了从nameForField、nameforgermethod和nameForSetterMethod返回的内容。我已经测试了您的类,并收到了从object到json:{“Test”:“1”、“ABC”:“2”、“XyZ”:“3”}以及从json到object的结果:示例{Test='0',ABC='1',XyZ 2'}您期望得到什么?如果您期望相同,但结果不同,则您没有复制最新的解决方案。这对序列化或仅对反序列化有帮助吗?我尝试此方法来反序列化传入的请求。但对我来说,它会影响序列化是毫无意义的。你已经有了对象,每次只能以一种特定的方式序列化它。事实上,这并不能解决OP的问题-他想要序列化和反序列化的原始版本。你是对的,我错过了这一部分。不管怎样,我的回答可能对谷歌未来的发展有所帮助。我发现它比其他解决方案更早。FieldUtils从哪里来?来自Apache Commons:
public class MyNamingStrategy extends PropertyNamingStrategy {

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return field.getName();
    }

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

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

    private String convert(AnnotatedMethod method, String defaultName) {

        Class<?> clazz = method.getDeclaringClass();
        List<Field> flds = FieldUtils.getAllFieldsList(clazz);
        for (Field fld : flds) {
            if (fld.getName().equalsIgnoreCase(defaultName)) {
                return fld.getName();
            }
        }

        return defaultName;
    }
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
@JsonSetter("ABC")
public void setABC(String ABC) {
    this.ABC= ABC;
}