当前位置: 首页 > 面试题库 >

jaxrs找不到我的joda.money类型的自定义(反)序列化器

索和璧
2023-03-14
问题内容

我已经为joda.money.Money类型编写了自定义(反)序列化器。我向对象映射器注册它们。但是当我部署war文件时,它说找不到joda.money.Money类型的序列化程序。

import org.joda.money.Money;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

    public class MoneyDeserializer extends StdDeserializer<Money> {

    private static final long serialVersionUID = 1L;

    public MoneyDeserializer() {
        super(Money.class);
    }

    @Override
    public Money deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        ...
    }
}

在ObjectMapper中注册;

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.joda.money.Money;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import xx.serializers.MoneyDeserializer;
import xx.serializers.MoneySerializer
@Provider
public class JsonProvider extends JacksonJsonProvider {

    public JsonProvider() {

        ObjectMapper mapper = new ObjectMapper();

        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // Register <Money> (de)serializers
        SimpleModule tstmodule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
        tstmodule.addDeserializer(Money.class, new MoneyDeserializer());
        tstmodule.addSerializer(Money.class, new MoneySerializer());
        mapper.registerModule(tstmodule);

        mapper.registerModule(new JodaModule());

    }

}





  2:24:00,860 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 151) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./api: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./api: java.lang.RuntimeException: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam("sale") on public javax.ws.rs.core.Response com.xx.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.Long,org.joda.money.Money,java.lang.String,java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime,java.time.LocalDateTime,java.lang.Long,java.lang.Long,java.lang.Long,java.lang.Long,java.lang.String) for basetype: org.joda.money.Money
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.RuntimeException: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam("sale") on public javax.ws.rs.core.Response xx.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.Long,org.joda.money.Money,java.lang.String,java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime,java.time.LocalDateTime,java.lang.Long,java.lang.Long,java.lang.Long,java.lang.Long,java.lang.String) for basetype: org.joda.money.Money
    at org.jboss.resteasy.core.StringParameterInjector.initialize(StringParameterInjector.java:218)

问题答案:

我看到您ObjectMapperJsonProvider构造函数中创建但从未使用过。您可能应该setMapper(mapper);在构造函数的最后使用JsonProvider。

但是我认为这不会解决您的问题。我认为问题在于jaxrs仅了解简单的数据类型,如果您要使用自定义类,则必须为基于String的字符串实现某种形式的String编组@*Param

从您的stacktrace中,我看到您使用jboss,所以这可能会有所帮助?https://docs.jboss.org/resteasy/docs/3.0.12.Final/userguide/html/StringConverter.html

如果您有一个valueOf()或此字符串构造函数不存在或不适合HTTP请求的类,该怎么办?JAX-RS
2.0具有javax.ws.rs.ext.ParamConverterProvider可以在这种情况下提供帮助。有关更多详细信息,请参见javadoc。

https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ParamConverterProvider.html

这样的事情可能应该起作用:

@Provider
public class MoneyConverterProvider  implements ParamConverterProvider {

    private final MoneyConverter converter = new MoneyConverter();

    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
        if (!rawType.equals(Money.class)) return null;
        return (ParamConverter<T>) converter; 
    }

    public class MoneyConverter implements ParamConverter<Money> {

        public Money fromString(String value) {
            if (value == null ||value.isEmpty()) return null; // change this for production
            return Money.of(CurrencyUnit.EUR, Double.parseDouble(value));
        }

        public String toString(Money value) {
            if (value == null) return "";
            return value.getAmount().toString(); // change this for production
        }

    }
}


 类似资料:
  • 我正在尝试反序列化我不拥有的类的对象。该类具有属性名称,如id、address、name,但其getter是getId、getAddress等。 当我尝试使用Jackson反序列化JSON时,我得到 看起来发生这种情况是因为Jackson正在寻找的是getId,而不是getId。由于我不拥有底层类,因此无法使用Jackson的注释将属性映射到自定义json字段。 如何使用对象属性到其getter方

  • 下面是我的项目的实体类 这是会话表 这里是用户实体 我正在使用JPARepository在我的mysql数据库中保存训练和会话对象 但每当我保存训练对象或会话对象时 我得到了错误 我谷歌了它,发现我需要序列化和反序列化手动…但我不知道怎么做…请帮帮我..

  • 问题内容: 我正在使用jackson库将JSON映射到对象中。我已经简化了问题 很多 ,这是发生了什么: 我正在解析一个空的JSON字符串: 在上,出现以下异常: 当我在类中有 两个 返回a的方法时,就会发生这种情况。删除其中一种方法不会导致异常。 实际上,我对映射器查看方法的事实感到惊讶,它应该设置我指示的字段。 这是怎么回事 问题答案: 我通过将转换为来解决此问题:

  • 我正在尝试从我的网站获取JSON数据,并使用REST API 2。但当我运行应用程序时,此错误消息显示: 找不到类型[简单类型,类com.example.app.ReferralApiModel]的(Map)键反序列化器 我正在使用改装库。 这是我的改装电话代码: 这是我的ReferralsPlaceHolderApi类: 这也是我的参考模型课程: 这是我试图获取的json数据: 有人能帮我吗?。

  • 我创建了一个新的自定义反序列化程序,当json中存在空字符串时,该反序列化程序将作为null返回 我的问题是从性能的角度来看的。我想优化一个事实,即在字段的每一个可能的更改中都必须更改反序列化器。有可能优化你的吗?我正在考虑使用Reflaction,但我不知道怎么做。有可能吗?

  • I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器