2015-11-02 44 views
0

我有这样的Web服务方法。我将通过POST发送JSON映射到该方法,并且没有正确设置地址字段。我知道JSON是有效的,因为它直接将单元测试转换为JSON并将其读回。测试通过(反序列化的对象有2个电话号码),这是确切的字符串。杰克逊的Web服务 - 解析地图<String,PhoneNumber>不起作用

@POST 
@Override 
@Consumes({"application/xml", "application/json"}) 
public void create(Person entity) { 
    System.out.println("Saving entity: " + entity); 
    super.create(entity); 
    System.out.println("Saved: " + entity); 
} 

当我发布JSON它不会在对象上设置的电话号码映射。下面是输出:

信息:保存实体:个人{ID = NULL,名字=约翰,昵称= JJ,姓氏=史密斯,middleNames = [Stelling,迪林],IDNUM = js3234,isMale = n,birthday = null,phoneNumbers = null}

Info:Saved:Person {id = 2,firstName = John,nickname = JJ,lastName = Smith,middleNames = [Stelling,Deering],idNum = js3234,isMale = N,生日= NULL,PHONENUMBERS = NULL}

这里是JSON:

{ 
    "id": null, 
    "firstName": "John", 
    "nickname": "JJ", 
    "lastName": "Smith", 
    "middleNames": [ 
     "Stelling", 
     "Deering" 
    ], 
    "idNum": "js3234", 
    "isMale": "n", 
    "birthday": 778266673889, 
    "phoneNumbers": { 
     "Personal Mobile": { 
      "countryCode": "26", 
      "areaCode": "200", 
      "subscriberNubmer": "4069942", 
      "extension": null 
     }, 
     "Home": { 
      "countryCode": "79", 
      "areaCode": "115", 
      "subscriberNubmer": "9518863", 
      "extension": null 
     } 
    } 
} 

的对象是这样的:

@Entity 
@Table(name = "ent_person") 
public class Person implements Serializable, Comparable<Person> { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 

private static final long serialVersionUID = -4680156785318108346L; 

protected String firstName; 

protected String nickname; 

protected String lastName; 

@ElementCollection(fetch = FetchType.EAGER) 
protected List<String> middleNames; 

protected String idNum; 

protected char isMale; 

@Temporal(value = TemporalType.DATE) 
protected Date birthday; 

@ElementCollection(fetch=FetchType.EAGER) 
@MapKeyColumn(name = "name") 
@Column(name = "value") 
protected Map<String, PhoneNumber> phoneNumbers; 
--- Snipped getters, setters, to string and constructors -- 

这是PhoneNumber对象

public class PhoneNumber implements Serializable { 

private static final long serialVersionUID = -423634682785318106L; 

public static transient final String HOME = "Home"; 

public static final String PERSONAL_MOBILE = "Personal Mobile"; 

public static final String OFFICE = "Office"; 

public static final String WORK_MOBILE = "Work Mobile"; 

public static final String FAX = "Fax"; 

public static final String PAGER = "Pager"; 

public static final String TOLL_FREE = "Toll Free"; 

public static final String OTHER = "Other"; 

String countryCode; 

String areaCode; 

String subscriberNubmer; 

String extension; 

回答

0

好了,我终于找到了答案。根据this table

我不得不添加一个自定义MessageBodyReader读取字符串的地图不会自动反序列化。由于我已经有一个工作单元测试来读取字符串,所以添加正确的类和注释以及之后的所有工作都很简单:

@Consumes("application/json") 
@Provider 
public class PersonReader 
implements MessageBodyReader<Person> { 
    ObjectMapper mapper; 

    public PersonReader(){ 
     mapper = new ObjectMapper(); 
    } 

    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
     return type == Person.class; 
    } 

    public Person readFrom(Class<Person> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { 
     Person p = mapper.readValue(entityStream, Person.class); 
     return p; 
    } 
}