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

时间:2014-10-31 13:33:43

标签: java json web-services jax-rs jersey-2.0

首次在应用程序中实现JAX-RS Client API并且在存储响应数据时遇到一些小问题,这些问题作为Java BEAN返回为JSON。请参阅下面的代码片段,其中演示了到目前为止我是如何实现它的。

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

基本上,我希望将来自Web服务的返回JSON响应存储到我的Java BEAN中,在此方案中将其命名为objectrequestObject显然是我发送到Web服务的数据,我可以确认POST确实成功执行了操作。

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

例如,当我通过CLI @XmlRootElement调用Web服务时,这就是我的JSON返回对象的样子:

curl

为什么会发生这种情况的原因?

更新 [下面的响应Bean类]

"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
        }
    }

属于@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 Class

1 个答案:

答案 0 :(得分:4)

所以我能够重现这个问题,经过一些测试后,我意识到问题非常明显,如果我从正确的角度看待它的话。我最初从视图中看到它可能是提供程序配置出错了。但经过一个简单的杰克逊只有#34;测试,只是使用ObjectMapper并尝试读取值,它变得清晰。问题在于json格式和类的结构。

这是结构

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

这是你的课程

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

这个问题是顶级对象只需要一个属性response。但我们的顶级对象是ResponseObject,其中 没有属性response。通过忽略未知属性,解组成功,因为唯一的属性是response,没有属性,因此不会填充任何内容。

一个简单的(Json / JAXB友好)修复方法是创建一个包装类,其response属性为ResponseObject

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);

完成测试

<强> ResponseObject

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    }";
    }
}

<强> ResponseWrapper此类

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}";
    } 
}

<强> TestResource

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
    }
  }
}