【问题标题】:XmlJavaTypeAdapter XmlElement not working for multiple fieldsXmlJavaTypeAdapter XmlElement 不适用于多个字段
【发布时间】:2023-03-16 01:25:02
【问题描述】:

我有一个像下面这样的 xml,我需要使用这个 xml 来填充下面的对象 我需要日期为所需的格式和日期的时间戳转换。我使用下面提到的代码做到了这一点。

<customer>
    <name>john</name>
    <date>10/10/18</date>
<customer>

@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    @XmlElement(name="name")
    private String name;

    @XmlJavaTypeAdapter (DateSort.class)
    @XmlElement(name="date")
    private String date;

    @XmlJavaTypeAdapter (TimeStampSort.class)
    @XmlElement(name="date")
    private long dateTimestamp;

    setters()/getters()
}

public class DateSort extends XmlAdapter<String, String> implements DateFormats {

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

    @Override
    public String unmarshal(String date) throws ParseException {
        Date pubDate = sourceDateFormat.parse(date);
        return outputDateFormat.format(pubDate);
    }
}

public class TimeStampSort extends XmlAdapter<String, Long> implements DateFormats {

    @Override
    public Long unmarshal(String date) throws Exception {
        Date newDate = sourceDateFormat.parse(date);
        return Long.parseLong(monthFormat.format(newDate));
    }

    @Override
    public String marshal(Long date) throws Exception {
        return new Date(date).toString ();
    }
}

我在这里面临的问题是 XmlJavaTypeAdapter 被称为“日期”而不是 dateTimestamp 属性。我不确定为什么会存在这种行为。

我试过做这个配置

@XmlJavaTypeAdapter (value=DateSort.class, type=Long.class)
@XmlElement(name="PUBDATE", type=Long.class)


@XmlJavaTypeAdapter (value=DateSort.class, type=long.class)
@XmlElement(name="PUBDATE", type=long.class)

并将类型转换为

private Long timeStamp; 

这些都不起作用。

这里的问题是我需要将相同的元素映射到具有转换的多个 pojo 字段。 是否需要添加任何额外的注释来实现这一点?

请帮助我解决问题,因为为什么没有调用 TimeStampSort 适配器,因为 DateSort 被调用并且工作正常。

【问题讨论】:

  • 我已经裁判了那些似乎都不起作用
  • 问题是,我猜你不能映射date XML 元素两次。你的Customer POJO 怎么样?你不能这样做吗?在字符串日期字段的设置器中?
  • 嗨 philonous,感谢您的回复,这是我需要的确认,天气我们可以使用元素两次,我提供了我的 pojo 的示例,它由名称、日期、timeStampdate 属性和设置器组成和吸气剂
  • @Flown 能否请您删除重复标签,这样多人可以查看此标签
  • 我认为您不应该尝试在(取消)编组过程中对数据结构进行转换。考虑创建将 1:1 映射到 XML 的类,并实现转换逻辑以将这些类的实例转换为您的“业务对象”(POJO)。

标签: java xml java-8 marshalling unmarshalling


【解决方案1】:

以下示例说明了如何实现您的要求。

最好“进一步”执行此操作,即在检索未编组的值时在服务中。一般来说,您会尽量避免在简单的映射对象中包含过多的逻辑。

@XmlRootElement
class Customer {

    private String name;

    private String date;

    private long dateTimestamp;

    public String getName() {
        return name;
    }

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

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date; // You can do additional transformations here
        try {
            this.dateTimestamp = new SimpleDateFormat("MM/dd/yy").parse(date).getTime();
        } catch (ParseException e) {
            // Handle this appropriately ;-)
        }
    }

    public long getDateTimestamp() {
        return dateTimestamp;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", Customer.class.getSimpleName() + "[", "]")
                .add("name='" + name + "'")
                .add("date='" + date + "'")
                .add("dateTimestamp=" + dateTimestamp)
                .toString();
    }

}

public class XmlUnmarshaller {

    private static final String XML_STRING =
            "<customer>\n" +
            "    <name>john</name>\n" +
            "    <date>10/10/18</date>\n" +
            "</customer>";

    public static void main(String[] args) {

     try {
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Customer customer = (Customer) jaxbUnmarshaller.unmarshal(new ByteArrayInputStream(XML_STRING.getBytes(StandardCharsets.UTF_8)));
        System.out.println(customer);

      } catch (JAXBException e) {
        e.printStackTrace();
      }
    }

}

【讨论】:

  • 上述方法是解决方法,但我仍在寻找早期代码不起作用的原因。在我看来,这应该有效。
  • 其实我不这么认为。我仍然想知道如果有两个 @XmlElement(name = "date") 注释(具有相同的名称!),为什么它不会抛出异常。因为遇到&lt;date&gt;...&lt;/date&gt;标签应该选择哪一个?我不知道实际的实现,但我猜它只是使用第一个匹配的......
猜你喜欢
  • 2012-10-08
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 2014-09-02
  • 2021-07-07
  • 2019-10-24
  • 1970-01-01
相关资源
最近更新 更多