【问题标题】:JsonMappingException while using Inheritance in json request在 json 请求中使用继承时出现 JsonMappingException
【发布时间】:2018-12-22 00:22:31
【问题描述】:

我有一个要求,Lambda 函数应该有通用输入。根据输入,它应该执行特定于类型的逻辑。 基本上,会有一个接口,根据输入的 json,它应该自动将其映射到相应的子类型。

这是我的课程

public class LambdaFunctionHandler implements RequestHandler<DemographicRequest, String> {

    @Override
    public String handleRequest(DemographicRequest input, Context context) {
        context.getLogger().log("Input: " + input);

        if (input instanceof NameRequest) {
            context.getLogger().log("Name request");
            // name specific logic and update in db
        } else if (input instanceof AddressRequest) {
            context.getLogger().log("Address Request");
            //address specific logic and update in db
        }

        // TODO: implement your handler
        return "Hello from Lambda!";
    }

}

public class AddressRequest implements DemographicRequest {

    private String addressLine1;
    private String addressLine2;
    private String street;
    private String city; 
    private String zipCode;
    private String country;

// setter and getters

}

public class NameRequest implements DemographicRequest {

    private String firstname;
    private String lastname;

//setters and getters
}

@JsonTypeInfo(use = Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @Type(value = NameRequest.class), @Type(value = AddressRequest.class) })
public interface DemographicRequest {

}

当我尝试使用下面的输入请求时,我得到了 JsonMappingException。我使用了@JsonTypeInfo 和@JsonSubTypes(不确定是否以正确的方式使用)。但是还是没用。

{
  "firstname": "fist",
  "lastname": "last"
}

Caused by: java.io.UncheckedIOException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.amazonaws.lambda.demo.model.DemographicRequest, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: lambdainternal.util.NativeMemoryAsInputStream@544fe44c; line: 1, column: 1]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.amazonaws.lambda.demo.model.DemographicRequest, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: lambdainternal.util.NativeMemoryAsInputStream@544fe44c; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:892)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:139)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1511)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1102)

你能帮我解决/解决这个问题吗?

【问题讨论】:

    标签: java json rest jackson aws-lambda


    【解决方案1】:

    错误

    抽象类型要么需要映射到具体类型,要么需要自定义反序列化器,要么需要使用额外的类型信息进行实例化

    表示Jackson无法解析基于接口DemographicRequest的对象。您必须提供具体的类NameRequest、AddressRequest。 如果使用RequestStreamHandler 并“手动”进行反序列化,则唯一能想到的。但我承认这并不是特别优雅。 例如

    public class LambdaFunctionHandler implements RequestStreamHandler {
    
        @Override
        public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException, IOException {
            context.getLogger().log("Input: " + inputStream);
    
            final ObjectMapper objectMapper = new ObjectMapper();
    
            try {
                Object input = objectMapper.readValue(inputStream, NameRequest.class);
                context.getLogger().log("Name request");
                // name specific logic and update in db
            } catch (JsonMappingException e) {
                //
            }
            try {
                Object input = objectMapper.readValue(inputStream, AddressRequest.class);
                context.getLogger().log("Address Request");
                //address specific logic and update in db
            } catch (JsonMappingException e) {
                //
            }
    
            // TODO: implement your handler
            outputStream.write("Hello from Lambda!".getBytes());
            outputStream.close();
        }
    
    }
    

    更好的方法可能是为每种类型提供单独的处理程序。

    【讨论】:

      猜你喜欢
      • 2015-05-19
      • 1970-01-01
      • 2011-10-18
      • 2018-02-28
      • 1970-01-01
      • 2012-08-10
      • 2017-06-05
      • 2015-06-25
      • 2019-04-28
      相关资源
      最近更新 更多