jaxrs не смог найти мои пользовательские (де)сериализаторы для типа joda.money

Я написал свой собственный (де)сериализатор для joda.money.Moneytype. Я регистрирую их с помощью Object Mapper. Но когда я развертываю свой военный файл, он говорит, что не может найти сериализаторы для типа 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)

person Ratha    schedule 05.05.2016    source источник


Ответы (1)


Я вижу, что вы создаете ObjectMapper в конструкторе JsonProvider, но никогда его не используете. Вероятно, вам следует использовать setMapper(mapper); в JsonProvider в самом конце конструктора.

Но я не думаю, что это решит вашу проблему. Я думаю, проблема в том, что jaxrs понимает только простые типы данных, и если вы хотите использовать собственный класс, вам нужно реализовать какой-то маршалинг строк для строк на основе @*Param

Из вашей трассировки стека я вижу, что вы используете 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
        }

    }
}
person varren    schedule 05.05.2016
comment
Спасибо. Но StringConverter устарел. Что можно заменить? - person Ratha; 06.05.2016
comment
Я использую RestEasy 3.0.12. Финальная версия с wildfly 9.0 - person Ratha; 06.05.2016
comment
@Ratha я обновил свой пост. Я думаю, вам следует использовать javax.ws.rs.ext.ParamConverterProvider - person varren; 06.05.2016