wsimport 生成 getter 在 ObjectMapper 中不工作

wsimport generated getter not working in ObjectMapper

下面是wsimport生成的class-(注意getter名称getOProposalData())-

public class UpdateProposalRequest {
    protected ObjProposalData oProposalData;

    public ObjProposalData getOProposalData() {
        return oProposalData;
    }
    public void setOProposalData(ObjProposalData value) {
        this.oProposalData = value;
    }
}

我正在尝试使用来自 com.fasterxml.jackson.core (jackson-databind) -

的 ObjectMapper 将字符串转换为上述 class 的对象
private ObjectMapper mapper = new ObjectMapper();
UpdateProposalRequest requestObject = mapper.readValue(requestStr, UpdateProposalRequest.class);

requestStr 具有以下 JSON -

{
    "oProposalData": {
    .
    .
    .
    }
}

当我 运行 应用程序时,它抛出以下异常 - (注意 - 已知 属性 名称 - oproposalData) -

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "oProposalData" (class co.xxx.service.updateproposal.UpdateProposalRequest), not marked as ignorable (one known property: "oproposalData"])

经过一番摸索,我发现问题出在从 wsimport 生成的 getter 名称上。如果我把它改成getoProposalData(),那么上面的异常就不会抛出。

以下是我能想到的解决该问题的 2 种解决方法 -

  1. 对于每个 getter 方法,为 ObjectMapper 添加以下注释以选择正确的字段名称 - @JsonProperty("oProposalData")

  2. 用 wsimport 生成 class 文件后,使用像 eclipse 这样的 IDE 自动生成 getter 和 setter。 (Eclipse 将生成具有与 ObjectMapper 格式匹配的正确格式的 getter)。

这些方法的问题是我有数百个这样的 class 文件,它们有多个字段。因此手动添加注释或生成 getters 和 setters 将花费大量时间。此外,对 WSDL 文件的任何小改动都会导致重新生成 class 文件并再次手动更改 getter 名称。

有没有办法在生成 class 文件时控制 getter/setter 名称格式?

或者有没有办法在调用 readValue/writeValue 时向 ObjectMapper 提供 getter 格式?

更新-

我发现通过扩展 PropertyNamingStrategy,我们将能够提供自己的转换策略。但我无法为上述情况获得正确的转换。 Link -- Link

任何人都可以提供上述情况下所需的确切转换策略吗?

我通过使用 PropertyNamingStrategy 使其正常工作,如下所示 --

public class MyNameStrategy extends PropertyNamingStrategy {
    @Override
    public String nameForField(MapperConfig config, AnnotatedField field, String defaultName) {
        return convertFieldName(field.getName());
    }

    @Override
    public String nameForGetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) {
        return convertMethodName(method.getName(),defaultName);
    }

    @Override
    public String nameForSetterMethod(MapperConfig config, AnnotatedMethod method, String defaultName) {
        return convertMethodName(method.getName(),defaultName); 
    }

    public String convertMethodName(String methodName,String defaultName) {
        if(methodName.compareTo("isEmpty")==0 || methodName.compareTo("isNaN")==0 || methodName.compareTo("isInfinite")==0) {
            return defaultName;
        }
        return convertFieldName(methodName.substring(3));
    }

    public String convertFieldName(String fieldName) {
        char[] arr=fieldName.toCharArray();
        if(arr.length!=0) {
            if(Character.isUpperCase(arr[0])){
                char lower = Character.toLowerCase(arr[0]);
                arr[0] = lower;
            }
        }
        return new StringBuilder().append(arr).toString();
    }
}

使用上面的 class 对象如下 -

ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new MyNameStrategy());
UpdateProposalRequest requestObject=mapper.readValue(request, UpdateProposalRequest.class);