Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将JSON字符串反序列化到对象根值大小写敏感?_Java_Json_Spring_Jackson_Json Deserialization - Fatal编程技术网

Java 如何将JSON字符串反序列化到对象根值大小写敏感?

Java 如何将JSON字符串反序列化到对象根值大小写敏感?,java,json,spring,jackson,json-deserialization,Java,Json,Spring,Jackson,Json Deserialization,将项目从Jersey移动到springmvc时面临问题。 如何在Jackson中放松对根值的大小写不敏感 我想同时支持大写和小写。 我们有以下Jackson配置,这些配置对属性和枚举很好,但对根值无效 spring.jackson.mapper.accept-case-insensitive-properties=true spring.jackson.mapper.accept-case-insensitive-enums=true 在我的情况下,我没有访问Car类的权限,因此无法使用任何J

将项目从
Jersey
移动到
springmvc
时面临问题。 如何在
Jackson
中放松对根值的大小写不敏感

我想同时支持大写和小写。

我们有以下
Jackson
配置,这些配置对属性和枚举很好,但对根值无效

spring.jackson.mapper.accept-case-insensitive-properties=true
spring.jackson.mapper.accept-case-insensitive-enums=true
在我的情况下,我没有访问
Car
类的权限,因此无法使用任何
Jackson
注释,如
@JsonRootValue
Car
类的名称更新为“Car”

下面是我所面临的示例类与测试复制问题

在jackson库中配置放松根名称不是很好吗

public class CarTest {

    public class Car {
        String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
    
    @Test
    public void testCarRootValueCaseSensitivity() throws IOException {
        Car car = new Car();
        car.setName("audi");

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
        objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
        String carAsString = objectMapper.writeValueAsString(car);
        System.out.println(carAsString);

        // Works fine with out any exception as the root value Car has captital 'C'
        objectMapper.readValue("{\"Car\":{\"name\":\"audi\"}}", Car.class);

        // Throws exception when lower case 'c' is provided than uppercase 'C'
        objectMapper.readValue("{\"car\":{\"name\":\"audi\"}}", Car.class);
    }
}

当您查看抛出的异常时:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name 'car' does not match expected ('Car') for type [simple type, class com.example.Car]
 at [Source: (String)"{"car":{"name":"audi"}}"; line: 1, column: 2] (through reference chain: com.example.Car["car"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportPropertyInputMismatch(DeserializationContext.java:1477)
    at com.fasterxml.jackson.databind.DeserializationContext.reportPropertyInputMismatch(DeserializationContext.java:1493)
    at com.fasterxml.jackson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:4286)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4200)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
您可以注意到
\u展开并反序列化方法名

在此方法中,您可以找到以下代码:

String actualName = p.getCurrentName();
if (!expSimpleName.equals(actualName)) {
   ctxt.reportPropertyInputMismatch(rootType, actualName,
       "Root name '%s' does not match expected ('%s') for type %s",
       actualName, expSimpleName, rootType);
}
由于始终使用
equals
方法,因此无法配置此行为

如果你真的想用不区分大小写的模式解析它,你可以重写
\u unwrappand deserialize
方法并用
equalsIgnoreCase
替换
equals
。示例类:

class CaseInsensitiveObjectMapper extends ObjectMapper {
    protected Object _unwrapAndDeserialize(JsonParser p, DeserializationContext ctxt, DeserializationConfig config, JavaType rootType, JsonDeserializer<Object> deser) throws IOException {
        PropertyName expRootName = config.findRootName(rootType);
        // 12-Jun-2015, tatu: Should try to support namespaces etc but...
        String expSimpleName = expRootName.getSimpleName();
        if (p.getCurrentToken() != JsonToken.START_OBJECT) {
            ctxt.reportWrongTokenException(rootType, JsonToken.START_OBJECT,
                    "Current token not START_OBJECT (needed to unwrap root name '%s'), but %s",
                    expSimpleName, p.getCurrentToken());
        }
        if (p.nextToken() != JsonToken.FIELD_NAME) {
            ctxt.reportWrongTokenException(rootType, JsonToken.FIELD_NAME,
                    "Current token not FIELD_NAME (to contain expected root name '%s'), but %s",
                    expSimpleName, p.getCurrentToken());
        }
        String actualName = p.getCurrentName();
        if (!expSimpleName.equalsIgnoreCase(actualName)) {
            ctxt.reportPropertyInputMismatch(rootType, actualName,
                    "Root name '%s' does not match expected ('%s') for type %s",
                    actualName, expSimpleName, rootType);
        }
        // ok, then move to value itself....
        p.nextToken();
        Object result = deser.deserialize(p, ctxt);
        // and last, verify that we now get matching END_OBJECT
        if (p.nextToken() != JsonToken.END_OBJECT) {
            ctxt.reportWrongTokenException(rootType, JsonToken.END_OBJECT,
                    "Current token not END_OBJECT (to match wrapper object with root name '%s'), but %s",
                    expSimpleName, p.getCurrentToken());
        }
        if (config.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
            _verifyNoTrailingTokens(p, ctxt, rootType);
        }
        return result;
    }
}
另见:


您需要使用objectMapper.configure(MapperFeature.ACCEPT\u CASE\u INSENSITIVE\u PROPERTIES,true)@Ganeshchaitanya MapperFeature.ACCEPT_不区分大小写_属性适用于属性值,但不适用于根值可能是您应该使用objectMapper.configure(SerializationFeature.WRAP_root_值,true);configure(反序列化功能.UNWRAP_ROOT_值,true)@Ganeshchaitanya问题与取消包装无关,问题id对根值区分大小写。@MichałZiober在我的例子中,我想支持这两种情况。如果我使用MixIn,我将无法同时支持这两个。这一个工作正常,但我现在在全局设置此新的ObjectMapper并替换默认的ObjectMapper时遇到了问题。@TechLearning,请查看,谢谢您的提示。你的解决方案很有效。@TechLearning,我很高兴听到这个消息。
ObjectMapper objectMapper = new CaseInsensitiveObjectMapper();