我遇到问题,我在Glassfish上部署了一个Web服务,并没有对POST数据进行反序列化以正确添加人员。
当我在测试用例中序列化/反序列化时,它工作正常。如何使GF像我的测试用例一样使用ObjectMapper?我的bean很好,以及适用于我的测试用例的JSON,但是当发布到REST服务时它不起作用。
public class PhoneNumber implements Serializable {
String countryCode;
String areaCode;
String subscriberNubmer;
String extension;
public PhoneNumber() {
super();
}
/**
* @param countryCode
* @param areaCode
* @param subscriberNubmer
* @param extension
*/
public PhoneNumber(String countryCode, String areaCode, String subscriberNubmer,
String extension) {
super();
this.countryCode = countryCode;
this.areaCode = areaCode;
this.subscriberNubmer = subscriberNubmer;
this.extension = extension;
}
... getters and other stuff ...
}
@Entity
@Table(name = "ent_person")
public class Person implements Serializable, Comparable<Person> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* Comment for <code>serialVersionUID</code>
*/
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;
public Person() {
super();
}
/**
* @param firstName
* @param nickname
* @param lastName
* @param middleNames
* @param idNum
* @param isMale
* @param birthday
*/
public Person(String firstName, String nickname, String lastName, List<String> middleNames,
String idNum, char isMale, Date birthday, Map<String, PhoneNumber> phoneNumbers) {
super();
this.firstName = firstName;
this.nickname = nickname;
this.lastName = lastName;
this.middleNames = middleNames;
this.idNum = idNum;
this.isMale = isMale;
this.birthday = birthday;
this.phoneNumbers = phoneNumbers;
}
... getters and setters ...
}
这是测试用例序列化方法生成的JSON数据,并且在测试用例中使用ObjectMapper
正确地反序列化。但是,它不会在Web应用程序中正确反序列化。
{
"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
}
}
}
以下是我发布上述JSON时Web服务给我的内容。请注意,phoneNumbers地图只有1个键&#34;条目&#34;没有价值???
{"firstName":"John","id":1,"idNum":"js3234","isMale":"n","lastName":"Smith","middleNames":["Stelling","Deering"],"nickname":"JJ","phoneNumbers":{"entry":[]}}
这是测试用例,效果很好,上面的JSON是这个案例生成的(val String)
@Test
public void testSimpleSerializeToFromJson() throws IOException {
int phoneNumberCount;
Person p;
p = BeanFactory.getDummyPerson();
assertNotNull(p.getPhoneNumbers());
phoneNumberCount = p.getPhoneNumbers().size();
assertTrue(phoneNumberCount > 0);
String val = mapper.writeValueAsString(p);
assertNotNull(val);
Person p2 = mapper.readValue(val, Person.class);
System.out.println(p2.getPhoneNumbers());
assertNotNull(p2.getPhoneNumbers());
assertTrue(p2.getPhoneNumbers().size() == phoneNumberCount);
assertFalse(p == p2);
assertTrue(p2.equals(p));
}
答案 0 :(得分:1)
我必须添加一个自定义MessageBodyReader来读取String。因为我已经有一个工作单元测试来读取字符串,所以添加正确的类和注释以及之后的所有工作都很简单:
@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;
}
}