Using jackson mixin class for a list of objects - jackson

I'm having a problem deserializing the following json
{
"GrpHdr": {
"MsgId": "Message-1",
"CreDtTm": "2018-03-02T10:15:30+01:00[Europe/Paris]",
"NbOfTxs": "1",
"InitgPty": {
"Nm": "Remitter"
}
},
"PmtInf": [
{
"PmtInfId": "1"
},
{
"PmtInfId": "2"
}
]
}
I have created a MixIn class:
public abstract class CustomerCreditTransferInitiationMixIn {
public PaymentInstructions paymentInstructions;
#JsonCreator
public CustomerCreditTransferInitiationMixIn(
#JsonProperty("GrpHdr") GroupHeader GrpHdr,
#JsonProperty("PmtInf") List<PaymentInstruction> PmtInf
) {
this.paymentInstructions = PaymentInstructions.valueOf(PmtInf);
}
#JsonProperty("GrpHdr")
abstract GroupHeader getGroupHeader();
#JsonProperty("PmtInf")
abstract List<PaymentInstruction> getPaymentInstructions();
}
I'm having no trouble deserializing the group header in this case. Mapping different names. But in the PmtInf case I get confused. It is a list that I want to deserialize to a List of PaymentInstructions. But PmtInf is a paymentistruction.
I have created a test:
#Test
public void JacksonMixinAnnotationTestJsonIsoFileFromTester() throws JsonProcessingException, Throwable {
CustomerCreditTransferInitiation customerCreditTransferInitiation;
String jsonFile = "testWithShortNames";
InputStream inputStream = new ClassPathResource(jsonFile + ".json").getInputStream();
ObjectMapper objectMapper = buildMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.addMixIn(CustomerCreditTransferInitiation.class, CustomerCreditTransferInitiationMixIn.class);
objectMapper.addMixIn(GroupHeader.class, GroupHeaderMixIn.class);
objectMapper.addMixIn(PaymentInstruction.class, PaymentInstructionMixIn.class);
objectMapper.addMixIn(PartyIdentification.class, PartyIdentificationMixIn.class);
customerCreditTransferInitiation = objectMapper.readValue(inputStream, CustomerCreditTransferInitiation.class);
//GroupHeader
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader());
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader().getMessageId());
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader().getCreationDateTime());
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader().getNumberOfTransactions());
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader().getInitiatingParty());
Assert.assertNotNull(customerCreditTransferInitiation.getGroupHeader().getInitiatingParty().getName());
//PaymentInstructions
Assert.assertNotNull(customerCreditTransferInitiation.getPaymentInstructions());}
Getting the following error:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "PmtInfId" (class
com.seb.payment.iso.domain.PaymentInstruction), not marked as
ignorable (19 known properties: "paymentInformationId",
"paymentMethod", "created", "paymentTypeInformation", "controlSum",
"debtorAgent", "instructionForDebtorAgent", "numberOfTransactions",
"requestExecutionTime", "debtorAccount", "creditTransferTransactions",
"debtorAgentAccount", "batchBooking", "poolingAdjustmentDate",
"ultimateDebtor", "chargeBearerType", "debtor", "chargesAccount",
"chargesAccountAgent"]) at [Source: UNKNOWN; line: -1, column: -1]
(through reference chain:
com.seb.payment.iso.domain.CustomerCreditTransferInitiation["PmtInf"]->com.seb.payment.iso.domain.PaymentInstruction["PmtInfId"])

In our case we have implemented our own deserializers in abstract iterable.
On:
ObjectReader objectReader = ObjectMapperFactory.instance().readerFor(this.itemClass);
MixedIn classes are lost

Related

Problem to deserialize json to java object of generic type with jackson 2.13.4.2

There's a message defined as below, note there're different implementations of the generic type M
// The message definition
#Value
#Builder(toBuilder = true)
#Jacksonized
public class MyMessage<M> {
#Builder.Default
Map<String, String> props = new HashMap<>();
M content;
}
// One implementation of the generic type M in MyMessage
class ContentType1 {
String name;
SomeSimplePojo pojo;
Map<String, String> contentProps;
}
Here's an example of above message:
{
"props": {
"trace-id": "3468f6022b749dbc"
},
"content": {
"name": "contentExample1",
"pojo": {
"field1": "val1",
"field2": "val2"
},
"contentProps": {
"/Count": "9",
"/Email": "someone#stackoverflow.com"
}
}
}
The message was deserialized basically with below code snippet, by com.fasterxml.jackson.* version 2.10.4. It worked fine before.
ObjectMapper objectMapper = new ObjectMapper();
MyMessage<String> rawMsg = objectMapper.readValue(jsonStr, new TypeReference<MyMessage<String>>() {});
// Here clazzOfM is the class of type M
MyMessage<M> convertedMsg = MyMessage.<M>builder().content(objectMapper.convertValue(rawMsg.getContent(), clazzOfM)).props(rawMsg.getProps()).build();
But recently, I upgraded com.fasterxml.jackson.databind to 2.13.4.2, all other com.fasterxml.jackson.* to 2.13.4. Then it failed at this line MyMessage<String> rawMsg = objectMapper.readValue(jsonStr, new TypeReference<MyMessage<String>>() {}); with Exception, which points to the generic type M, field content at column 52:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
at [Source: (String)"{"props":{"trace-id":"3468f6022b749dbc"},"content":{"name":"contentExample1","pojo":{"field1":"val1","field2":"val2"},"contentProps":{"/Count":"9","/Email":"someone#stackoverflow.com"}}}"; line: 1, column: 52] (through reference chain: com.demo.example.MyMessage$MyMessageBuilder["content"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1741)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1515)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1420)
at com.fasterxml.jackson.databind.DeserializationContext.extractScalarFromObject(DeserializationContext.java:932)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:62)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:158)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.vanillaDeserialize(BuilderBasedDeserializer.java:293)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:217)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3612)
I tried to change the problematic line to MyMessage<M> rawMsg = objectMapper.readValue(jsonStr, new TypeReference<MyMessage<M>>() {});, no exception then, but I still have two questions.
Is the above change a correct approach to deserialize json text to MyMessage by jackson 2.13.4(.2)? What is the best practice to this kind of deserialization if the above isn't.
After the above change, I notice that the type of rawMsg.content is LinkedHashMap, it isn't M(CotentType1 in this test) as I expected. But the type of convertedMsg.content IS ContentType1 after executing this converting line MyMessage<M> convertedMsg = MyMessage.<M>builder().content(objectMapper.convertValue(rawMsg.getContent(), clazzOfM)).props(rawMsg.getProps()).build();.
I can't understand why the type of rawMsg.content is LinkedHashMap instead of ContentType1. Could someone help explain?

#JsonIdentityInfo doesn't handle circular references correctly in a generic list

I'm serializing and deserializing a list including two objects, with circular references there.
First I tried ObjectIdGenerators.StringIdGenerator as the generator.
//Using latest version for the dependencies
//jackson.version = 2.13.1
//jackson-jsog = 1.1.2
#NoArgsConstructor
#JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
public static class Outer {
#Setter
#Getter
private Inner inner;
}
#NoArgsConstructor
#JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
public static class Inner {
#Getter
private Outer outer;
public Inner(Outer outer) {
this.outer = outer;
outer.setInner(this);
}
}
public static void main(String[] args) throws Exception {
// There are circular references between Outer and Inner
Outer outer = new Outer();
Inner inner = new Inner(outer);
// Turn on type info
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfSubType(Object.class).build();
ObjectMapper mapper = new ObjectMapper()
.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING,
JsonTypeInfo.As.PROPERTY);
List<Object> source = Lists.newArrayList(outer, inner);
String json = mapper.writeValueAsString(source);
System.out.println(json);
//This is the json serialized by StringIdGenerator, which doesn't make sense for the second instance(no type info there,just a UUID)
//See below
List<Object> target = mapper.readerForListOf(Object.class).readValue(json);
System.out.println(target);
//So I finally got an Outer instance and a string in the target list, not equal to source list at all
//[com.foo.bar.SomeTest$Outer#4b29d1d2, acb5231d-13de-4e22-92c6-cb1ec0530de1]
}
This is the json serialized by StringIdGenerator, which doesn't make sense for the second instance(no type info there,just a UUID)
[
"java.util.ArrayList",
[
{
"#class": "com.foo.bar.SomeTest$Outer",
"#id": "df6ed346-6b27-4983-8dc2-5c07ddfa8f8f",
"inner":
{
"#class": "com.foo.bar.SomeTest$Inner",
"#id": "acb5231d-13de-4e22-92c6-cb1ec0530de1",
"outer": "df6ed346-6b27-4983-8dc2-5c07ddfa8f8f"
}
},
"acb5231d-13de-4e22-92c6-cb1ec0530de1"
]
]
Then I tried JSOGGenerator
#NoArgsConstructor
#JsonIdentityInfo(generator = JSOGGenerator.class)
public static class Outer {
#Setter
#Getter
private Inner inner;
}
#NoArgsConstructor
#JsonIdentityInfo(generator = JSOGGenerator.class)
public static class Inner {
#Getter
private Outer outer;
public Inner(Outer outer) {
this.outer = outer;
outer.setInner(this);
}
}
public static void main(String[] args) throws Exception {
// There are circular references between Outer and Inner
Outer outer = new Outer();
Inner inner = new Inner(outer);
// Turn on type info
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfSubType(Object.class).build();
ObjectMapper mapper = new ObjectMapper()
.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING,
JsonTypeInfo.As.PROPERTY);
List<Object> source = Lists.newArrayList(outer, inner);
String json = mapper.writeValueAsString(source);
System.out.println(json);
//This is the json serialized by JSOGGenerator, which does make sense
//See below
List<Object> target = mapper.readerForListOf(Object.class).readValue(json);
//However, I got an InvalidTypeIdException while deserializing
//Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.voodoodyne.jackson.jsog.JSOGRef]: missing type id property '#class'
}
This is the json serialized by JSOGGenerator, which does make sense.
[
"java.util.ArrayList",
[
{
"#class": "com.foo.bar.SomeTest$Outer",
"#id": "1",
"inner":
{
"#class": "com.foo.bar.SomeTest$Inner",
"#id": "2",
"outer":
{
"#ref": "1"
}
}
},
{
"#ref": "2"
}
]
]
However, I got an InvalidTypeIdException while deserializing.
And I found the property "#id" is not handled correctly.
See ObjectIdValueProperty._valueDeserializer._baseType, which type is JSOGRef and it can not parse "1"(String) as object id value.
My questions
What's the correct way to deal with this?
Do we have some other generator to try?

Spring Batch - Unable to deserialize the execution context - OffsetDateTime - cannot deserialize

I'm trying to create a spring batch job with multiples steps and passing object from step to step.
To do this I use ExecutionContext that i promoted from step to job context.
At first run, no problem data goes right from step to step
At next runs, I get the error :
"Unable to deserialize the execution context" Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of java.time.OffsetDateTime (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
I write context in a ItemWriter like so :
#Override
public void write(List<? extends Employee> items) throws Exception {
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
List<Employee> e = new ArrayList<Employee>();
e.addAll(items);
stepContext.put("someKey", e);
}
And read it back in a ItemReader (from another step) with :
#BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.someObject = (List<Employee>) jobContext.get("someKey");
}
I check spring database context and my dates (LocalDate, OffsetDateTime, ...) are store like :
"LocalDate": {
"year": 2019,
"month": "OCTOBER",
"dayOfMonth": 30,
"monthValue": 10,
"era": ["java.time.chrono.IsoEra", "CE"],
"dayOfWeek": "WEDNESDAY",
"dayOfYear": 303,
"leapYear": false,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
}
"OffsetDateTime": {
"offset": {
"totalSeconds": 0,
"id": "Z",
"rules": {
"fixedOffset": true,
"transitionRules": ["java.util.Collections$UnmodifiableRandomAccessList", []],
"transitions": ["java.util.Collections$UnmodifiableRandomAccessList", []]
}
},
"month": "OCTOBER",
"year": 2019,
"dayOfMonth": 28,
"hour": 13,
"minute": 42,
"monthValue": 10,
"nano": 511651000,
"second": 36,
"dayOfWeek": "MONDAY",
"dayOfYear": 301
}
I guess it's jackson's choice to store it like that (I custom nothing)
But it seems that jackson can't read it's own format at next run ?!
My stubs are generated with from swagger with "swagger-codegen-maven-plugin" and configOptions/dateLibrary=java8 so I can't change them.
I tried to add
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
And
#PostConstruct
public void init() {
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
In the #SpringBootApplication
no change
Any ideas ? Either to store dates more simply like "2019-11-04" or make jackson read it's own format ?
Your object mapper should be set on the Jackson2ExecutionContextStringSerializer used by the job repository. You can extend DefaultBatchConfigurer and override createJobRepository:
#Bean
public JobRepository createJobRepository() throws Exception {
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Jackson2ExecutionContextStringSerializer defaultSerializer = new Jackson2ExecutionContextStringSerializer();
defaultSerializer.setObjectMapper(objectMapper);
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setTransactionManager(transactionManager);
factory.setSerializer(defaultSerializer);
factory.afterPropertiesSet();
return factory.getObject();
}
EDIT :
My bad I just saw that I have a
#Bean
public BatchConfigurer batchConfigurer(#Qualifier("batchDataSource") DataSource dataSource) {
return new DefaultBatchConfigurer(dataSource);
}
That provide 2 batchConfigurer to spring.
Thanks !
ORIGINAL :
Thanks it seems promising.
But I dont find where to extends and use it, on which class.
I have a Batch Class configuration :
#Configuration
#EnableConfigurationProperties(BatchProperties.class)
public class BatchDatabaseConfiguration {
#Value("${spring.datasource.driver-class-name}")
private String driverClassName;
#Value("${spring.datasource.url}")
private String dbURL;
#Bean("batchDataSource")
public DataSource batchDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(dbURL);
return dataSource;
}
#Bean
public BatchConfigurer batchConfigurer(#Qualifier("batchDataSource") DataSource dataSource) {
return new DefaultBatchConfigurer(dataSource);
}
#Bean(name = "batchTransactionManager")
public PlatformTransactionManager batchTransactionManager(#Qualifier("batchDataSource") DataSource dataSource) {
DataSourceTransactionManager tm = new DataSourceTransactionManager();
tm.setDataSource(dataSource);
return tm;
}
}
And a Class with Job's definition :
#Configuration
#EnableBatchProcessing
public class ExtractionJobConfiguration {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Bean
public Job creationJob() {
...
}
[...]
}
And the main :
#EntityScan(basePackages = { "..." })
#SpringBootApplication
#EnableAsync
public class App {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(App.class, args);
}
What do you think ?
I also read that Spring Batch 4.2.0+ allow for customisation of ObjectMapper in Jackson2ExecutionContextStringSerializer (https://jira.spring.io/browse/BATCH-2828)
Is that what you propose ? (I don't find other information)

SerializationException of Avro Date Object (Date LogicalType)

I have a publisher that accepts a GenericRecord class.
#Override
public Future<RecordMetadata> publish(GenericRecord genericRecord) {
Future<RecordMetadata> recordMetadataFuture =
getPublisher().send(new ProducerRecord<>(producerConfiguration.getProperties()
.getProperty(ProducerConfiguration.PROPERTY_NAME_TOPIC), "sample.key",genericRecord));
return recordMetadataFuture;
}
private KafkaProducer<String, GenericRecord> getPublisher() {
return new KafkaProducer<>(producerConfiguration.getProperties());
}
And I have the following avro schema:
{
"type" : "record",
"name" : "SampleDate",
"namespace": "com.sample.data.generated.avro",
"doc" : "sample date",
"fields" : [
{
"name" : "sampleDate",
"type" : {
"type" : "int",
"logicalType" : "date"
}
}
]
}
I have built my own serializer:
Date Serializer:
#Component
public class SampleDateSerializer implements Serializer<GenericRecord> {
private AvroGenericSerializer serializer;
#Override
public void configure(Map<String, ?> configs, boolean isKey) {
serializer = new AvroGenericSerializer(SampleDate.SCHEMA$);
}
#Override
public byte[] serialize(String topic, GenericRecord data) {
return serializer.serialize(data);
}
#Override
public void close() {
}
Generic Serializer:
public class AvroGenericSerializer {
private EncoderFactory avroEncoderFactory;
private DecoderFactory avroDecoderFactory;
private GenericDatumWriter<GenericRecord> avroWriter;
private GenericDatumReader<GenericRecord> avroReader;
public AvroGenericSerializer(Schema schema) {
avroEncoderFactory = EncoderFactory.get();
avroDecoderFactory = DecoderFactory.get();
avroWriter = new GenericDatumWriter<>(schema);
avroReader = new GenericDatumReader<>(schema);
}
public byte[] serialize(GenericRecord data) {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final BinaryEncoder binaryEncoder = avroEncoderFactory.binaryEncoder(stream, null);
try {
avroWriter.write(data, binaryEncoder);
binaryEncoder.flush();
stream.close();
return stream.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Can't serialize Avro object", e);
}
}
public GenericRecord deserialize(byte[] bytes) {
try {
return avroReader.read(null, avroDecoderFactory.binaryDecoder(bytes, null));
} catch (IOException e) {
throw new RuntimeException("Can't deserialize Avro object", e);
}
}
}
However, when testing my publisher class, I am encountering the following error:
org.apache.kafka.common.errors.SerializationException: Can't convert value of class com.sample.data.generated.avro.SampleDate to class com.sample.message.serialize.SampleDateSerializer specified in value.serializer
Debugging the code, I have found out that the
GenericDatumWriter.write()...
method is returning null when calling the
Conversion conversion = this.getData().getConversionByClass(datum.getClass(), logicalType);
which is called from
org.apache.avro.generic.GenericData
public <T> Conversion<T> getConversionByClass(Class<T> datumClass, LogicalType logicalType) {
Map conversions = (Map)this.conversionsByClass.get(datumClass);
return conversions != null?(Conversion)conversions.get(logicalType.getName()):null;
}
In this regard, is there a way for me to populate the
GenericData.conversionsByClass
Map, so that it can return the correct converter to use for the given
date logicalType?
I have solved it by passing the GenericData object in my GenericDatumWriter.
My Generic Serializer now looks like this:
public AvroGenericSerializer(Schema schema) {
avroEncoderFactory = EncoderFactory.get();
avroDecoderFactory = DecoderFactory.get();
final GenericData genericData = new GenericData();
genericData.addLogicalTypeConversion(new TimeConversions.DateConversion());
avroWriter = new GenericDatumWriter<>(schema, genericData);
avroReader = new GenericDatumReader<>(schema);
}

Parsing JSON into custom POJO which has Map as one it's class member

I have below JSON which I want to parse into below bean classes.
{
"timeStamp": "123123123123",
"pznFlowFlag": "true",
"pznRequestFlag": "true",
"sessionId": "SampleSessionId",
"ipAddress": "172.148.0.1",
"offers": [
{
"111": {
"eep" : "44279",
"spl_ind" : "true"},
"121": {
"eep" : "44520",
"spl_ind" : "false"},
"333": {
"eep" : "45419",
"spl_ind" : "false" }
}]
}
Bean class 1
public class DistributedCookieBean {
#JsonProperty("timeStamp")
private String timeStamp;
#JsonProperty("pznFlowFlag")
private String pznFlowFlag;
#JsonProperty("pznRequestFlag")
private String pznRequestFlag;
#JsonProperty("sessionId")
private String sessionId;
#JsonProperty("ipAddress")
private String ipAddress;
#JsonProperty("offers")
private Map<String, OfferCookieBean> offers = new HashMap<String, OfferCookieBean>();
...<setters & getters>
}
Bean class 2
public class OfferCookieBean {
#JsonProperty("eep")
private String eep;
#JsonProperty("spl_ind")
private String spl_ind;
...<setters & getters>
}
Here I am not able to parse into the these Java POJOs using below code.
jsonObjMapper.readValue(jsonString, DistributedCookieBean.class);
Stacktrace:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.Map out of START_ARRAY token
at [Source: json.txt; line: 6, column: 31]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:192)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:134)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:23)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:135)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:221)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:391)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:287)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1588)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1074)
at Test.main(Test.java:29)
Thanks in advance!
The error message points to the problem: the offers field is declared as a map while in JSON it is an array of maps.
Try to change Map<String, OfferCookieBean> offers = new HashMap<String, OfferCookieBean>() to List<Map<String, OfferCookieBean>> offers; and see what happens.