JAX-RS响应对象将对象字段显示为NULL值 [英] JAX-RS Response Object displaying Object fields as NULL values

查看:54
本文介绍了JAX-RS响应对象将对象字段显示为NULL值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

First time implementing JAX-RS Client API in an application and I am having some small problems when it comes to storing the response data, which is returned as JSON as a Java BEAN. Refer to the following code snippets below which demonstrate how I have implemented it thus far.

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

本质上,我想将Web服务返回的JSON响应存储到我的Java BEAN中,在这种情况下,该Java BEAN被命名为object. requestObject显然是我要发送到Web服务的数据,我可以确认POST确实成功执行了该操作.

Essentially, I would like to store the returned JSON response from the web service into my Java BEAN, which in this scenario is named object. requestObject is obviously the data which I am sending through to the web service, and I can confirm that POST does perform the operation successfully.

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

After the line of code from the above example I have a simple: object.toString(); call just to see the values currently stored within this object. However, when this executes and printed out to the console, all the object fields are printed out as null, which I do not understand why. I have annotated my Java BEAN class with the following @XmlRootElement above the class, although it still does not work. I do have another object nested as a variable in this Class, would that potentially be the reason why it does not correctly come through?

作为示例,这是我通过CLI curl调用Web服务时JSON返回的对象的样子:

As an example, this is what my JSON returned object looks like when I invoke the web service through CLI curl:

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

为什么会发生这种情况?

Any reasons why this could be happening?

更新 [下面的响应Bean类]

UPDATE [Response Bean Class Below]

@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

@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

推荐答案

因此,我能够重现该问题,并且经过一些测试,我意识到,如果我从正确的观点.我最初是从提供程序配置可能有问题的角度来看它的.但是经过一个简单的仅杰克逊"测试,仅使用ObjectMapper并尝试读取该值,就很清楚了.问题在于json格式和类的结构.

So I was able to reproduce the problem, and after a bit of testing, I realized that the problem was pretty obvious, if I had looked at it from the right perspective. I was originally looking at it from the view that maybe something was wrong with the provider configuration. But after a simple "Jackson only" test, just using the ObjectMapper and trying the read the value, it became clear. The problem is with the json format and the structure of the classes.

这是结构

{
  "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,该属性没有属性,因此不会填充任何内容.

The problem with this is that the top level object is expecting just a single attribute response. But our top level object is ResponseObject, which has no attribute response. With the ignore unknown properties on, the unmarhalling succeeds, because the only attribute is response, for which no attribute exists, so nothing gets populated.

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

A simple (Json/JAXB friendly) fix would be to create a wrapper class, with a response attribute of type 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


Complete Test

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

这篇关于JAX-RS响应对象将对象字段显示为NULL值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆