Java 如何将jersey客户端配置为使用服务器期望的相同json格式?
这是我需要的json(由Ember生成,但在服务器上工作): 这是我得到的json:Java 如何将jersey客户端配置为使用服务器期望的相同json格式?,java,json,jersey-2.0,jersey-client,Java,Json,Jersey 2.0,Jersey Client,这是我需要的json(由Ember生成,但在服务器上工作): 这是我得到的json: {"id":null,"partyType":"jdo.party.model.Company","name":"Test Company","firstName":"","lastName":""} 我需要jersey客户端发出正确的json,我不知道为什么。 客户端代码: client = ClientBuilder.newClient(); client.register(JacksonFeature.
{"id":null,"partyType":"jdo.party.model.Company","name":"Test Company","firstName":"","lastName":""}
我需要jersey客户端发出正确的json,我不知道为什么。
客户端代码:
client = ClientBuilder.newClient();
client.register(JacksonFeature.class);
client.register(new LoggingFilter(Logger.getGlobal(),true));
resource = client.target("http://localhost:8090/crm/api").path("/customers");
CustomerDto dto = new CustomerDto(null, "jdo.party.model." + type, name, "", "");
response = resource.request()
.accept(APPLICATION_JSON)
.post(Entity.json(dto), CustomerDto.class);
我要在客户端和服务器上转换为json的类:
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "customer")
@JsonRootName("customer")
public class CustomerDto implements Serializable {
@XmlAttribute
private UUID id;
@XmlAttribute
@NotEmpty
private String partyType;
@XmlAttribute
private String name;
@XmlAttribute
private String firstName;
@XmlAttribute
private String lastName;
public CustomerDto(Party party) {
if (party instanceof Person) {
partyType = ((Person) party).getClass().getCanonicalName();
firstName = ((Person) party).getFirstName();
lastName = ((Person) party).getLastName();
} else if (party instanceof Organization) {
partyType = ((Organization) party).getClass().getCanonicalName();
name = ((Organization) party).getName();
} else {
throw new IllegalArgumentException(
String.format("Customer must be person or Organization. %s was passed instead.",
party.getClass().getCanonicalName()));
}
id = party.getId();
}
@AssertTrue
public boolean hasName() {
return isNotBlank(name) || isNotBlank(lastName);
}
public String getPartyType() {
return partyType;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((partyType == null) ? 0 : partyType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CustomerDto other = (CustomerDto) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (partyType == null) {
if (other.partyType != null)
return false;
} else if (!partyType.equals(other.partyType))
return false;
return true;
}
@Override
public String toString() {
return "CustomerDto [id=" + id + ", partyType=" + partyType + ", name=" + name + ", firstName=" + firstName
+ ", lastName=" + lastName + "]";
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public UUID getId() {
return id;
}
/**
*
*/
private static final long serialVersionUID = 1L;
public CustomerDto() {
super();
}
public CustomerDto(UUID id, String partyType, String name, String firstName, String lastName) {
super();
this.id = id;
this.partyType = partyType;
this.name = name;
this.firstName = firstName;
this.lastName = lastName;
}
}
因此,我们需要完成两件事:
@JsonInclude(JsonInclude.Include.NON_NULL)
这将告诉Jackson忽略空值。您还需要确保将null
作为构造函数值传递,而不是”
(这不是一回事)
你可以。。。
如果要全局设置此属性,可以在ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.registerModule(new JaxbAnnotationModule());
有几种方法可以注册此ObjectMapper
,以便在应用程序中使用
上下文解析器中配置它,如图所示。然后向客户端注册ContextResolver
client.register(new ObjectMapperContextResolver());
client.register(new JacksonJaxbJsonProvider(objectMapper, null));
ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
实际使用的值由@JsonRootName
注释值确定
请参见上文,了解如何配置要与应用程序一起使用的映射器
注意,为了保持对Jaxb注释的支持,您可能需要向
ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.registerModule(new JaxbAnnotationModule());
我不确定这一点,因为使用JacksonFeature,JAXB注释已经得到支持。但我不知道提供ObjectMapper是否会覆盖这一点。与显式使用JacksonJaxbJsonProvider相同。因此,您可能只想测试一下。如果您只需要JSON中的partyType和name属性,那么为什么要在CustomerDto.java类中注释其他字段呢?我在服务器端寻找配置,以便根据需要包装JSON。。错过了我做第二个选项的注释配置。非常感谢@JimBarrows在您的问题中,有一件事我不太确定,那就是为什么服务器会希望JSON被包装,即
{“customer”:{}}
。通常,它只需要{}
。如果将其包装到客户端,则需要在服务器上展开,在这种情况下,可以使用mapper.configure(反序列化功能.unwrap\u ROOT\u VALUE,true)
。但是如果你一开始没有这个,我不知道为什么你甚至需要在客户端包装它。我已经按照peskillet所说的配置了服务器。我忘记了我是通过java完成的,而不是通过配置文件。因此我感到困惑。编辑以试图澄清它。工作json由Ember生成,并由服务器接受。不工作是由Jackson从DTO(在服务器上工作)生成的。