У меня есть требование, лямбда-функция должна иметь общий ввод. основываясь на вводе, он должен выполнять логику, специфичную для данного типа. По сути, будет интерфейс, основанный на входном 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)
Не могли бы вы помочь мне разобраться / решить эту проблему?




Ошибка
abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
означает, что Джексон не может разобрать объект на основе интерфейса 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();
}
}
Вероятно, лучшим подходом было бы предоставление отдельного обработчика для каждого типа.