jaxrs找不到我的joda.money类型的自定义(de)序列化程序 [英] jaxrs could not find my custom (de)serializers for joda.money type

查看:403
本文介绍了jaxrs找不到我的joda.money类型的自定义(de)序列化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为 joda.money.Money 类型编写了我的自定义(de)序列化程序。我用Object Mapper注册它们。但是当我部署war文件时,它说无法找到joda.money.Money类型的序列化器。

I have written my custom (de)serializer for joda.money.Moneytype. I register them with Object Mapper. But when I deploy my war file, it says could not find serializers for joda.money.Money type.

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中注册;

Registering in the 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)


推荐答案

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

I see that you create ObjectMapper in JsonProvider constructor but never use it. You probably should use setMapper(mapper); on JsonProvider at the very end of the constructor.

但我不喜欢不会认为这会解决你的问题。我认为问题是jaxrs只能理解简单的数据类型,如果你想使用自定义类,你必须为基于String的 @ * Param 实现某种String编组操作

But i don't think this will solve your problem. I think the problem is that jaxrs understands only simple data types and if you want to use custom class you have to implement some sort of String marshalling for String based @*Param

从你的堆栈跟踪我看到你使用 jboss ,所以这可能有帮助吗? https://docs.jboss.org/resteasy /docs/3.0.12.Final/userguide/html/StringConverter.html

From your stacktrace i see that you use jboss, so maybe this can help? https://docs.jboss.org/resteasy/docs/3.0.12.Final/userguide/html/StringConverter.html


如果你有一个classOf的类怎么办? ()或此字符串构造函数
不存在或不适合HTTP请求? JAX-RS 2.0有
javax.ws.rs.ext.ParamConverterProvider来帮助解决这种情况。
有关详细信息,请参阅javadoc。

What if you have a class where valueOf() or this string constructor doesn't exist or is inappropriate for an HTTP request? JAX-RS 2.0 has the javax.ws.rs.ext.ParamConverterProvider to help in this situation. See javadoc for more details.

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
        }

    }
}

这篇关于jaxrs找不到我的joda.money类型的自定义(de)序列化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆