gpt4 book ai didi

java - JAX-RS 响应对象将对象字段显示为 NULL 值

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:09 25 4
gpt4 key购买 nike

第一次在应用程序中实现 JAX-RS 客户端 API,在存储响应数据时遇到了一些小问题,响应数据以 JSON 的形式返回Java BEAN。请参阅下面的代码片段,它们展示了我到目前为止是如何实现它的。

object = client.target(uri).request().post(Entity.entity(requestObject, APPLICATION_JSON), Object.class);

本质上,我想将从 Web 服务返回的 JSON 响应存储到我的 Java BEAN 中,在这个场景中它被命名为 objectrequestObject 显然是我发送到 Web 服务的数据,我可以确认 POST 确实成功执行了操作。

在上述示例的代码行之后,我有一个简单的:object.toString(); 调用只是为了查看当前存储在此对象 中的值。但是,当它执行并打印到控制台时,所有 object 字段都打印为 null,我不明白这是为什么。我已经在我的 Java BEAN 类上面用下面的 @XmlRootElement 注释了,尽管它仍然不起作用。我在这个类中确实有另一个对象作为变量嵌套,这可能是它不能正确通过的原因吗?

例如,当我通过 CLI curl 调用 Web 服务时,我的 JSON 返回对象如下所示:

"response": {
"description": "test charge",
"email": "testing@example.com",
"ip_address": "192.123.234.546",
"person": {
"name": "Matthew",
"address_line1": "42 Test St",
"address_line2": "",
"address_city": "Sydney",
"address_postcode": "2000",
"address_state": "WA",
"address_country": "Australia",
"primary": null
}
}

为什么会发生这种情况?

更新 [下面的响应 Bean 类]

@XmlRootElement(name = "response")
public class ResponseObject {

// Instance Variables
private String description;
private String email;
private String ip_address;
private Person person;
// Standard Getter and Setter Methods below

属于 ResponseObject 类的 Person 对象

@XmlRootElement
public class Card {

// Instance Variables
private String name;
private String address_line1;
private String address_line2;
private String address_city;
private int address_postcode;
private States address_state;
private String address_country;
private String primary;
// Standard Getter and Setter Methods below

最佳答案

所以我能够重现这个问题,经过一些测试,我意识到如果我从正确的角度来看问题,这个问题是非常明显的。我最初是从提供者配置可能有问题的角度来看它的。但经过简单的“仅 Jackson”测试后,仅使用 ObjectMapper 并尝试读取值,它就变得清晰了。问题在于 json 格式和类的结构。

结构如下

{
"response": {
"description": "test charge",
..
"person": {
"name": "Matthew",
..
}
}
}

这是你的类(class)

public class ResponseObject {
private String description;
private Person person;
...
}
public class Person {
private String name;
}

问题在于顶层对象只需要一个属性response。但是我们的顶级对象是 ResponseObject,它没有没有 response 属性。启用忽略未知属性后,解码成功,因为唯一的属性是 response,它不存在任何属性,因此不会填充任何内容。

一个简单的(Json/JAXB 友好的)修复是创建一个包装器类,具有 ResponseObject 类型的 response 属性

public class ResponseWrapper {
private ResponseObject response;
}

这将使解码成功

final ResponseWrapper ro = target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(new ResponseWrapper()
, MediaType.APPLICATION_JSON_TYPE), ResponseWrapper.class);

完成测试

响应对象

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "response")
public class ResponseObject {

private String description;
private String email;
private String ip_address;
private Person person;

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getIp_address() {
return ip_address;
}

public void setIp_address(String ip_address) {
this.ip_address = ip_address;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

@Override
public String toString() {
return "ResponseObject{"
+ "\n description=" + description
+ "\n email=" + email
+ "\n ip_address=" + ip_address
+ "\n person=" + person
+ "\n }";
}
}

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {
// Instance Variables
private String name;
private String address_line1;
private String address_line2;
private String address_city;
private int address_postcode;
private String address_state;
private String address_country;
private String primary;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress_line1() {
return address_line1;
}

public void setAddress_line1(String address_line1) {
this.address_line1 = address_line1;
}

public String getAddress_line2() {
return address_line2;
}

public void setAddress_line2(String address_line2) {
this.address_line2 = address_line2;
}

public String getAddress_city() {
return address_city;
}

public void setAddress_city(String address_city) {
this.address_city = address_city;
}

public int getAddress_postcode() {
return address_postcode;
}

public void setAddress_postcode(int address_postcode) {
this.address_postcode = address_postcode;
}

public String getAddress_state() {
return address_state;
}

public void setAddress_state(String address_state) {
this.address_state = address_state;
}

public String getAddress_country() {
return address_country;
}

public void setAddress_country(String address_country) {
this.address_country = address_country;
}

public String getPrimary() {
return primary;
}

public void setPrimary(String primary) {
this.primary = primary;
}

@Override
public String toString() {
return "Person{"
+ "\n name=" + name
+ "\n address_line1=" + address_line1
+ "\n address_line2=" + address_line2
+ "\n address_city=" + address_city
+ "\n address_postcode=" + address_postcode
+ "\n address_state=" + address_state
+ "\n address_country=" + address_country
+ "\n primary=" + primary
+ "\n }";
}
}

响应包装器

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class ResponseWrapper {
private ResponseObject response;

public ResponseObject getResponse() {
return response;
}

public void setResponse(ResponseObject response) {
this.response = response;
}

@Override
public String toString() {
return "ResponseWrapper{"
+ "\n response=" + response
+ "\n}";
}
}

测试资源

package jersey.stackoverflow.jaxrs;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/test")
public class TestResource {

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getResponse(ResponseObject ro) {
final String json = "{\n"
+ " \"response\": {\n"
+ " \"description\": \"test charge\",\n"
+ " \"email\": \"testing@example.com\",\n"
+ " \"ip_address\": \"192.123.234.546\",\n"
+ " \"person\": {\n"
+ " \"name\": \"Matthew\",\n"
+ " \"address_line1\": \"42 Test St\",\n"
+ " \"address_line2\": \"\",\n"
+ " \"address_city\": \"Sydney\",\n"
+ " \"address_postcode\": \"2000\",\n"
+ " \"address_state\": \"WA\",\n"
+ " \"address_country\": \"Australia\",\n"
+ " \"primary\": null\n"
+ " }\n"
+ " }\n"
+ "}";
return Response.created(null).entity(json).build();
}
}

单元测试:TestTestResource

import jersey.stackoverflow.jaxrs.ResponseWrapper;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
import org.junit.Test;

public class TestTestResource extends JerseyTest {

@Test
public void testPostReturn() throws Exception {
final WebTarget target = target("test");
final ResponseWrapper ro = target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(new ResponseWrapper()
, MediaType.APPLICATION_JSON_TYPE), ResponseWrapper.class);
System.out.println(ro);

}

@Override
protected Application configure() {
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);

return createApp();
}

@Override
protected void configureClient(ClientConfig config) {
config.register(createMoxyJsonResolver());
}

public static ResourceConfig createApp() {
// package where resource classes are
return new ResourceConfig().
packages("jersey.stackoverflow.jaxrs").
register(createMoxyJsonResolver());
}

public static ContextResolver<MoxyJsonConfig> createMoxyJsonResolver() {
final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig();
Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
moxyJsonConfig.setNamespacePrefixMapper(namespacePrefixMapper).setNamespaceSeparator(':');
return moxyJsonConfig.resolver();
}
}

pom.xml 中的依赖

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>2.13</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-bundle</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>

结果:仅使用 toString

ResponseWrapper{
response=ResponseObject{
description=test charge
email=testing@example.com
ip_address=192.123.234.546
person=Person{
name=Matthew
address_line1=42 Test St
address_line2=
address_city=Sydney
address_postcode=2000
address_state=WA
address_country=Australia
primary=null
}
}
}

关于java - JAX-RS 响应对象将对象字段显示为 NULL 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26675967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com