package com.fasterxml.jackson.databind.deser;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.*;
/**
* Unit tests for verifying that field-backed properties can also be
* deserialized as well as setter-accessible properties.
*/
public class TestFieldDeserialization
extends BaseMapTest
{
/*
/**********************************************************
/* Annotated helper classes
/**********************************************************
*/
static class SimpleFieldBean
{
public int x, y;
// not auto-detectable, not public
int z;
// ignored, not detectable either
@JsonIgnore public int a;
}
static class SimpleFieldBean2
{
@JsonDeserialize String[] values;
}
@JsonAutoDetect(fieldVisibility=Visibility.NONE)
static class NoAutoDetectBean
{
// not auto-detectable any more
public int z;
@JsonProperty("z")
public int _z;
}
// Let's test invalid bean too
static class DupFieldBean
{
public int z;
@JsonProperty("z")
public int _z;
}
public static class DupFieldBean2
{
@JsonProperty("foo")
public int _z;
@JsonDeserialize
private int foo;
}
public static class OkDupFieldBean
extends SimpleFieldBean
{
@JsonProperty("x")
protected int myX = 10;
@SuppressWarnings("hiding")
public int y = 11;
}
abstract static class Abstract { }
static class Concrete extends Abstract
{
String value;
public Concrete(String v) { value = v; }
}
static class AbstractWrapper {
@JsonDeserialize(as=Concrete.class)
public Abstract value;
}
/*
/**********************************************************
/* Main tests
/**********************************************************
*/
public void testSimpleAutoDetect() throws Exception
{
ObjectMapper m = new ObjectMapper();
SimpleFieldBean result = m.readValue("{ \"x\" : -13 }",
SimpleFieldBean.class);
assertEquals(-13, result.x);
assertEquals(0, result.y);
}
public void testSimpleAnnotation() throws Exception
{
ObjectMapper m = new ObjectMapper();
SimpleFieldBean2 bean = m.readValue("{ \"values\" : [ \"x\", \"y\" ] }",
SimpleFieldBean2.class);
String[] values = bean.values;
assertNotNull(values);
assertEquals(2, values.length);
assertEquals("x", values[0]);
assertEquals("y", values[1]);
}
public void testNoAutoDetect() throws Exception
{
ObjectMapper m = new ObjectMapper();
NoAutoDetectBean bean = m.readValue("{ \"z\" : 7 }",
NoAutoDetectBean.class);
assertEquals(7, bean._z);
}
public void testTypeAnnotation() throws Exception
{
ObjectMapper m = new ObjectMapper();
AbstractWrapper w = m.readValue("{ \"value\" : \"abc\" }",
AbstractWrapper.class);
Abstract bean = w.value;
assertNotNull(bean);
assertEquals(Concrete.class, bean.getClass());
assertEquals("abc", ((Concrete)bean).value);
}
public void testFailureDueToDups() throws Exception
{
try {
writeAndMap(new ObjectMapper(), new DupFieldBean());
} catch (JsonMappingException e) {
verifyException(e, "Multiple fields representing property");
}
}
public void testFailureDueToDups2() throws Exception
{
try {
writeAndMap(new ObjectMapper(), new DupFieldBean2());
} catch (JsonMappingException e) {
verifyException(e, "Multiple fields representing property");
}
}
// For [JACKSON-226], acceptable field overrides
public void testOkFieldOverride() throws Exception
{
ObjectMapper m = new ObjectMapper();
OkDupFieldBean result = m.readValue("{ \"x\" : 1, \"y\" : 2 }",
OkDupFieldBean.class);
assertEquals(1, result.myX);
assertEquals(2, result.y);
}
}