有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

spring使用JAXB将Java对象编组为XML会返回意外的输出

我在使用JAXB将bean编组为XML时遇到问题。我有多个REST API端点,我希望从所有端点返回统一的响应,如下所示:

<response>
  <responseHeader> <!-- this will be same for all the end points -->
    <status>OK</status>
    <stausCode>AB-123<statusCode>
  </responseHeader>

  <responseBody>
     <!-- contains end point specific data, could be differnet-->
  </responseBody>
</response>

所以我创建了一个通用的响应DTO:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "response")
public class GenericResponseDto implements Serializable {

    @XmlElement(name="responseHeader")
    private GenericResponseHeaderDto responseHeader;

    @XmlAnyElement(name="responseBody")
    private Object responseBody;

    public GenericResponseHeaderDto getResponseHeader() {
        return responseHeader;
    }

    public void setResponseHeader(GenericResponseHeaderDto responseHeader) {
        this.responseHeader = responseHeader;
    }

    public Object getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(Object responseBody) {
        this.responseBody = responseBody;
    }
}

其中,对于其中一个端点响应,响应主体字段将替换为以下对象:

@XmlRootElement(name = "responseBody")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person implements Serializable {

    @XmlElement(required = false)
    private String phoneNumber;

    @XmlElement(required = false)
    private Integer personId;

    public Integer getPersonId() {
        return personId;
    }

    public void setPersonId(Integer personId) {
        this.personId = personId;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

这是我的球衣终点:

@POST
@Path("/myAPIFirstEndPoint")
@Produces({MediaType.APPLICATION_XML})
public GenericResponseDto myAPIFirstEndPoint(ABC abc) {
    // some work and getting person dto
    Person person = someWork.doWork();

    GenericResponseDto genericResponseDto = new GenericResponseDto();

    // not setting any responseHeader for now, so ignore
    genericResponseDto.setResponseBody(row);

    return genericResponseDto;
}

但它并没有像预期的那样工作。正在对Person对象调用toString()方法,而不是将其编组为XML。我得到了以下不正确的回答:

<?xml version="1.0" encoding="UTF-8" ?>
<response>
<responseBody>
   path.to.package.Person@36af3690[phoneNumber=+123456789,personId=-1]
</responseBody>
</response>

你能告诉我我做错了什么吗?我将Jersey和JAXB与Spring一起使用

编辑:

引入了泛型

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "response")
@XmlSeeAlso({Person.class})
public class GenericResponseDto<T> implements Serializable {

    @XmlElement(name="responseHeader")
    private GenericResponseHeaderDto responseHeader;

    @XmlElement(name="responseBody")
    private T responseBody;

    public GenericResponseHeaderDto getResponseHeader() {
        return responseHeader;
    }

    public void setResponseHeader(GenericResponseHeaderDto responseHeader) {
        this.responseHeader = responseHeader;
    }

    public T getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(T responseBody) {
        this.responseBody = responseBody;
    }
}

更改了Jersey端点,如下所示:

@POST
@Path("/myAPIFirstEndPoint")
@Produces({MediaType.APPLICATION_XML})
public GenericResponseDto<Person> myAPIFirstEndPoint(ABC abc) {
    // some work and getting person dto
    Person person = someWork.doWork();

    GenericResponseDto<Person> genericResponseDto = new GenericResponseDto<Person>();

    // not setting any responseHeader for now, so ignore
    genericResponseDto.setResponseBody(row);

    return genericResponseDto;
}

仍然得到与上述相同的响应

现在,在GenericResponseDto中添加@XmlSeeAlso({Person.class})之后,得到这个响应

   <?xml version="1.0" encoding="UTF-8" ?>
   <response>
    <responseBody xsi:type="Person">
      <phoneNumber>+923454502dd0559</phoneNumber>
      <personId>-1</personId>
    <token />
     </responseBody>
   </response>

共 (0) 个答案