首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MonetaryAmount JSR354 / moneta的自定义Json序列化格式,如何正确注册序列化程序

MonetaryAmount JSR354 / moneta的自定义Json序列化格式,如何正确注册序列化程序
EN

Stack Overflow用户
提问于 2022-02-27 16:38:48
回答 1查看 157关注 0票数 0

你好,堆栈溢出专家

我有以下的InvoiceItem类,它有货币金额

代码语言:javascript
复制
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.json.bind.annotation.JsonbTypeSerializer;
import jakarta.json.bind.serializer.JsonbSerializer;
import jakarta.json.bind.serializer.SerializationContext;
import jakarta.json.stream.JsonGenerator;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.eclipse.persistence.annotations.UuidGenerator;
import org.javamoney.moneta.FastMoney;

@Entity
@UuidGenerator(name = "INVOICE_ITEM_GEN")
@Table(name = "invoice_items")
public class InvoiceItem {
    @Getter
    @Setter
    @jakarta.persistence.Id
    @JsonbProperty("id")
    @GeneratedValue(generator = "INVOICE_ITEM_GEN")
    private String Id;

    @Getter
    @Setter
    @Column(name = "name")
    @JsonbProperty("name")
    private String Name;

    @Getter
    @Setter
    @Convert(converter = PersistentFastMoney.class)
    @Column(name = "price")
    @JsonbProperty("price")
    private FastMoney Price;

    public InvoiceItem() {
    }

    public InvoiceItem(String name, String price) {
        this.setName(name);
        this.setPrice(FastMoney.parse(price));
    }
}

我从不同的输入中成功地在我的函数中生成了这个结果。

代码语言:javascript
复制
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/invoices")
public class InvoiceSystem {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Invoice CreateNewInvoice(InvoiceInput input) {
        var invoice = new Invoice();
        invoice.setCreditor(new InvoiceParty());
        for (var item: input.getItems()) {
            invoice.Items.add(item.toInvoiceItem());
        }

        return invoice;
    }
}

toInvoiceItem使用带有两个字符串参数的InvoiceItem的构造器。现在,我希望在创建类之后,将类打印为JSON返回给使用者。

但这次失败了

代码语言:javascript
复制
<body><h1>HTTP Status 500 - Internal Server Error</h1>
<hr/>
<p><b>type</b> Exception report</p>
<p><b>message</b>Internal Server Error</p>
<p><b>description</b>The server encountered an internal error that prevented it from fulfilling this request.</p>
<p><b>exception</b>
<pre>javax.servlet.ServletException: javax.json.bind.JsonbException: Unable to serialize property &#39;Items&#39; from com.openflowlabs.faktura.Invoice</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;Items&#39; from com.openflowlabs.faktura.Invoice</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;price&#39; from com.openflowlabs.faktura.InvoiceItem</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;context&#39; from org.javamoney.moneta.FastMoney</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;amountType&#39; from javax.money.MonetaryContext</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;annotatedInterfaces&#39; from java.lang.Class</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Unable to serialize property &#39;annotatedOwnerType&#39; from sun.reflect.annotation.AnnotatedTypeFactory.AnnotatedTypeBaseImpl</pre>
</p><p><b>root cause</b>
<pre>javax.json.bind.JsonbException: Error getting value on: javax.money.MonetaryAmount</pre>
</p><p><b>root cause</b>
<pre>java.lang.IllegalAccessException: class org.eclipse.yasson.internal.model.ReflectionPropagation cannot access class sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl &#40;in module java.base&#41; because module java.base does not export sun.reflect.annotation to unnamed module @50c1e8e3</pre>
</p><p><b>note</b> <u>The full stack traces of the exception and its root causes are available in the Payara Server
    5.2022.1 #badassfish logs.</u></p>
<hr/>
<h3>Payara Server 5.2022.1 #badassfish</h3></body>

我知道我需要一个自定义序列化程序,但我尝试了一天的每一种可能的方法来制作一个,但我的应用程序就是不吃注释

如何为org.javamoney.moneta.FastMoney类建立一个自定义序列化程序,以便我可以简单地用@JsonbTypeSerializer(FastMoneySerializer.class)来注释所有有这个类的字段,例如Invoice

代码语言:javascript
复制
@Getter
@Setter
@Convert(converter = PersistentFastMoney.class)
@Column(name = "price")
@JsonbProperty("price")
@JsonbTypeSerializer(FastMoneySerializer.class)
private FastMoney Price;

这有可能吗?是否有一些文档说明我需要如何使序列化程序返回这样的JSON?

代码语言:javascript
复制
{
  "name": "Testing",
  "price": "CHF 20"
}

谢谢您提供的任何指针和或解决方案,我真的很难找到关于如何使这些序列化程序工作的教程。如果你有一份好的文档,这也会有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-01 20:39:08

好吧,我找到了解决办法。

如果您想使用jakarta.json,您的运行时需要支持它。我用的是Pyara,它说它支持雅加达EE9,但不知怎么的它不支持。切换到GlassFish解决了这个问题。然后,正确的序列化程序如下所示

代码语言:javascript
复制
package org.mypackage;

import jakarta.json.bind.serializer.JsonbSerializer;
import jakarta.json.bind.serializer.SerializationContext;
import jakarta.json.stream.JsonGenerator;
import org.javamoney.moneta.FastMoney;

public class FastMoneySerializer implements JsonbSerializer<FastMoney> {

    @Override
    public void serialize(FastMoney obj, JsonGenerator generator, SerializationContext ctx) {
        var str = obj.toString();
        generator.write(str);
    }
}

然后,可以将其添加到具有如下FastMoney类型的属性中:

代码语言:javascript
复制
package com.openflowlabs.faktura;

import jakarta.json.bind.annotation.JsonbAnnotation;
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.json.bind.annotation.JsonbTypeSerializer;
import jakarta.json.bind.serializer.JsonbSerializer;
import jakarta.json.bind.serializer.SerializationContext;
import jakarta.json.stream.JsonGenerator;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.eclipse.persistence.annotations.UuidGenerator;
import org.javamoney.moneta.FastMoney;

@Entity
@UuidGenerator(name = "INVOICE_ITEM_GEN")
@Table(name = "invoice_items")
public class InvoiceItem {
    @Getter
    @Setter
    @jakarta.persistence.Id
    @JsonbProperty("id")
    @GeneratedValue(generator = "INVOICE_ITEM_GEN")
    private String Id;

    @Getter
    @Setter
    @Column(name = "name")
    @JsonbProperty("name")
    private String Name;

    @Getter
    @Setter
    @Convert(converter = PersistentFastMoney.class)
    @Column(name = "price")
    @JsonbProperty("price")
    @JsonbTypeSerializer(FastMoneySerializer.class)
    private FastMoney Price;

    public InvoiceItem() {
    }

    public InvoiceItem(String name, String price) {
        this.setName(name);
        this.setPrice(FastMoney.parse(price));
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71286583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档