jaxrs找不到我的joda.money类型的自定义(de)序列化程序 [英] jaxrs could not find my custom (de)serializers for joda.money type
问题描述
我已经为 joda.money.Money
类型编写了我的自定义(de)序列化程序。我用Object Mapper注册它们。但是当我部署war文件时,它说无法找到joda.money.Money类型的序列化器。
I have written my custom (de)serializer for joda.money.Money
type. 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屋!