在java中跨不同类工作的Json反序列化程序

在java中跨不同类工作的Json反序列化程序,java,json,Java,Json,我正在尝试创建一个跨类工作的@JsonDeserializer。我使用的是JAX-RS,传入的json字符串将包含snake case中的字段。我想重写json反序列化,这样我的java对象就不会有snake-case字段。由于java对象的创建是在JAX-RS中进行的,因此我在所有请求类上使用@JsonDeserializer注释。我当前的实现有一个通用基类,但我需要为所有具体的类扩展它,以便传入我想要创建的实际类。有没有更一般的方法 例如,我有多个请求对象,如下所示: @JsonDe

我正在尝试创建一个跨类工作的@JsonDeserializer。我使用的是JAX-RS,传入的json字符串将包含snake case中的字段。我想重写json反序列化,这样我的java对象就不会有snake-case字段。由于java对象的创建是在JAX-RS中进行的,因此我在所有请求类上使用@JsonDeserializer注释。我当前的实现有一个通用基类,但我需要为所有具体的类扩展它,以便传入我想要创建的实际类。有没有更一般的方法

例如,我有多个请求对象,如下所示:

    @JsonDeserialize(using = MyRequestDeserializer.class)
    public class MyRequest {
    ....
    }
我创建了一个通用反序列化程序,如下所示:

public class GenericRequestDeserializer extends JsonDeserializer<Object> {

private static ObjectMapper objectMapper = new ObjectMapper();

@Override
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
    return null;
}

protected Object deserializeIt(JsonParser jsonParser, Class cls) {
    try {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        Iterator<String> fieldNames = node.fieldNames();

        Object object = cls.newInstance();

        while(fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            JsonNode value = node.get(fieldName);

            String newFieldName = convertFieldName(fieldName);

            //TODO: currently failing if I do not find a field, should the exception be swallowed?
            Class returnType = object.getClass().getMethod("get" + newFieldName).getReturnType();
            Method setMethod = object.getClass().getMethod("set" + newFieldName, returnType);

            Object valueToSet = null;
            if(value.isTextual()) {
                valueToSet = value.asText();
            } else if(value.isContainerNode()) {
                valueToSet = objectMapper.readValue(value.toString(), returnType);
            } else if (value.isInt()) {
                valueToSet = value.asInt();
            }

            setMethod.invoke(object, valueToSet);
        }

        return object;

    } catch (Exception e) {
        throw new TokenizationException(GatewayConstants.STATUS_SYSTEM_ERROR,
                "Error in deserializeIt for " + cls.getSimpleName() + " caused by " + e.getMessage(), e);
    }
}

private String convertFieldName(String fieldName) {

    StringBuilder newFieldName = new StringBuilder();

    int length = fieldName.length();
    boolean capitalize = true;  //first character should be capitalized

    for(int i = 0; i < length; i++) {
        char current = fieldName.charAt(i);

        if(current == '_') {
            //remove the underscore and capitalize the next character in line
            capitalize = true;
        } else if(capitalize) {
            newFieldName.append(Character.toUpperCase(current));
            capitalize = false;
        } else {
            newFieldName.append(current);
        }
    }

    return newFieldName.toString();
}

有没有办法摆脱所有MyRequestDeserializer类?换句话说,GenericRequestDeserializer是否能找出它实际反序列化的类?

因此我找到了一个更好的选项,可以将所有对象更改为snake case。我没有在每个类上使用序列化器和反序列化器,而是能够在Spring中将ObjectMapper注入JsonProvider。ObjectMapper已经支持一个属性,该属性将自动执行驼峰案例到蛇案例的转换。我只需要在我的类中覆盖GetSingleton方法,该方法扩展应用程序如下:

public class MyApp extends Application {
....
@Override
public Set<Object> getSingletons() {
    final Set<Object> objects = new LinkedHashSet<Object>();


    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

    objects.add(new JacksonJsonProvider(objectMapper));

    return objects;
}
}
公共类MyApp扩展应用程序{
....
@凌驾
公共集getSingleton(){
最终设置对象=新LinkedHashSet();
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.SetPropertyName策略(
属性命名策略。带下划线的CAMEL\u CASE\u到\u LOWER\u CASE\u);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
add(新的JacksonJsonProvider(objectMapper));
归还物品;
}
}

因此,我找到了一个更好的选择,可以将所有对象更改为snake case。我没有在每个类上使用序列化器和反序列化器,而是能够在Spring中将ObjectMapper注入JsonProvider。ObjectMapper已经支持一个属性,该属性将自动执行驼峰案例到蛇案例的转换。我只需要在我的类中覆盖GetSingleton方法,该方法扩展应用程序如下:

public class MyApp extends Application {
....
@Override
public Set<Object> getSingletons() {
    final Set<Object> objects = new LinkedHashSet<Object>();


    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

    objects.add(new JacksonJsonProvider(objectMapper));

    return objects;
}
}
公共类MyApp扩展应用程序{
....
@凌驾
公共集getSingleton(){
最终设置对象=新LinkedHashSet();
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.SetPropertyName策略(
属性命名策略。带下划线的CAMEL\u CASE\u到\u LOWER\u CASE\u);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
add(新的JacksonJsonProvider(objectMapper));
归还物品;
}
}