1

我有一个 grails 应用程序,它通过类似 API 的 REST 发送从 Java POJO 生成的 xml。

在客户端有一个 Java 客户端,它使用从 XML 创建的相同 Java POJO(在 Grails 和 Java 客户端中使用相同的 jar 库)。

由于某种原因,XML 中的日期没有到达 Java POJO。我怎么进去?有什么我错过的技巧吗?Grails 从数据库中获取日期(列是时间戳类型),XML 有日期和时间,POJO 有 type Date,但时间的 getternull在客户端返回。

这是 POJO 代码:

@Entity
@Table(name = "MODEL_VIEW")
@XmlRootElement
public class Model implements Serializable {

    private static final long serialVersionUID = 1L;
    @Basic(optional = false)
    @Column(name = "MODEL_ID")
    @Id
    private BigInteger modelId;

    @Column(name = "LAST_MODIFIED")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModified;

    public Model() {
    }

    public BigInteger getModelId() {
        return modelId;
    }

    public void setModelId(BigInteger modelId) {
        this.modelId = modelId;
    }

    public Date getLastModified() {
        return lastModified;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

}

更新

这是 XML(由 Grails 生成,使用与上述相同的实体类作为客户端):

<?xml version="1.0" encoding="UTF-8"?>
<list>
<model id="1046">
    <modelId>1046</modelId>
    <lastModified>2013-09-17 17:42:17.478 PDT</lastModified>
</model>

下面是客户端上从 XML 创建 POJO 的代码:

public synchronized List<Model> getAllModels() {
    return targetModel.request(MEDIA_TYPE).get(new GenericType<List<Model>>(){});
}

// psuedo code that creates the "targetModel" object
    private final static String BASE_URL ="http://mybiz.com/myapp"; 
    private Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username,password));
    private WebTarget targetBase = client.target(BASE_URL);
    private WebTarget targetModel = targetBase.path("model");

这是使用 Java EE 7 和 Jersey 客户端 2.0

4

1 回答 1

1

最终的解决方案是为每个jaxb 解组时间戳创建我自己的自定义适配器

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class DateAdapter extends XmlAdapter<String, Date> {

    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");

    @Override
    public String marshal(Date v) throws Exception {
        return dateFormat.format(v);
    }

    @Override
    public Date unmarshal(String v) throws Exception {
        return dateFormat.parse(v);
    }

}

然后将实体类更改为

@Entity
@Table(name = "MODEL_VIEW")
@XmlRootElement
public class Model implements Serializable {

    private static final long serialVersionUID = 1L;
    @Basic(optional = false)
    @Column(name = "MODEL_ID")
    @Id
    private BigInteger modelId;

    @Column(name = "LAST_MODIFIED")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModified;

    public Model() {
    }

    public BigInteger getModelId() {
        return modelId;
    }

    public void setModelId(BigInteger modelId) {
        this.modelId = modelId;
    }

    @XmlJavaTypeAdapter(DateAdapter.class)
    public Date getLastModified() {
        return lastModified;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

}

注意 上的@XmlJavaTypeAdapter注释getLastModified()。它必须继续使用 getter,因为 JPA 和 JAXB 都被使用了。 http://www.objectpartners.com/2010/01/25/using-jpa-and-jaxb-annotations-in-the-same-object/

请注意,@XmlJavaTypeAdapter注释可以放在包中,然后它将应用于所有 Date 类型!

于 2013-09-19T22:00:35.600 回答