Wildfly выдает Невозможно найти конструктор, который принимает параметр String или метод valueOf() или fromString() для ошибки javax.ws.rs.QueryParam

Я использую wildfly 9.0 для развертывания моего файла войны. У меня есть типы java LocalDateTime, Java Money, определенные в моих конечных точках REST GET.

Когда я развертываю свой военный файл, я получаю следующую ошибку [1]. На основе этого ответа [2] я написал реализации «ParamConverterProvider» для обоих типов.

Он работал нормально (до сих пор я не видел такой же проблемы), и теперь у меня такая же проблема. Любая подсказка?

[1]

Причина: java.lang.RuntimeException: невозможно найти конструктор, который принимает параметр String или метод valueOf() или fromString() для javax.ws.rs.QueryParam(\"totalMoneyVolumeForPeriod\") в общедоступном javax.ws. rs.core.Response com.test.rest.StockEndpoint.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.String,java.lang.Long,org.javamoney.moneta .Money,java.util.Set,java.lang.String) для базового типа: org.javamoney.moneta.Money"}}}}

[2]

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

Пример кода

package com.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import javax.money.Monetary;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;

import org.javamoney.moneta.Money;

@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(new BigDecimal(value), Monetary.getCurrency("AUD"));
        }

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

    }
}

Класс приложения

package com.test;

import javax.ws.rs.core.Application;

import com.test.autogen*;


import io.swagger.jaxrs.config.BeanConfig;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;

@ApplicationPath("/rest")
public class RestApplication extends Application {
    public RestApplication() {
        BeanConfig beanConfig = new BeanConfig();
        //beanConfig.setVersion("1.0");
        beanConfig.setSchemes(new String[] { "http" });
        beanConfig.setTitle("My API");
        beanConfig.setBasePath("/rest");
        beanConfig.setResourcePackage("com.test.autogen");
        beanConfig.setScan(true);
    }

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>();


        set.add(EmailEndpoint.class);
        set.add(StockEndpoint.class);

        set.add(io.swagger.jaxrs.listing.ApiListingResource.class);
        set.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);

        return set;
    }
}

person Ratha    schedule 25.05.2016    source источник
comment
Убедитесь, что он зарегистрирован. Кроме этого, пожалуйста, покажите какой-нибудь код, который мы можем протестировать.   -  person Paul Samsotha    schedule 26.05.2016
comment
@peeskillet Как и где мне зарегистрироваться?   -  person Ratha    schedule 26.05.2016
comment
@peeskillet я предоставил свой пример кода. Я ничего не делал, кроме этого   -  person Ratha    schedule 26.05.2016
comment
Если вы используете сканирование путей к классам, оно должно быть зарегистрировано аннотацией @Provider. В противном случае вам нужно зарегистрировать его в своем классе Application.   -  person Paul Samsotha    schedule 26.05.2016
comment
здесь, в вашем классе Application в getClasses   -  person Paul Samsotha    schedule 26.05.2016
comment
@peeskillet Как зарегистрироваться в Application class? Я также предоставил свой класс Application. Я тоже использовал аннотацию Provider   -  person Ratha    schedule 26.05.2016
comment
@peeskillet большое спасибо ... это работает нормально ... Извините, эта библиотека чванства вызывала у меня проблемы здесь и там ... Предыдущая работала с аннотацией поставщика.   -  person Ratha    schedule 26.05.2016


Ответы (1)


Когда вы используете сканирование пути к классам, компоненты JAX-RS, аннотированные с помощью @Path или @Provider, будут выбраны и зарегистрированы. Есть несколько способов использовать сканирование пути к классам. Самый распространенный способ — просто создать пустой класс Application с аннотацией @ApplicationPath.

@ApplicationPath("/api")
public class MyApplication extends Application {}

Этого достаточно для загрузки приложения JAX-RS и для сканирования пути к классам приложения до компонентов для регистрации.

Но согласно спецификации, как только мы переопределяем любой из методов Set<Object> getSingletons или Set<Class> getClasses класса Application и возвращаем непустой набор, это автоматически отключает сканирование пути к классам, поскольку предполагается, что мы хотим зарегистрировать все сами.

Так что в предыдущих случаях вы, вероятно, просто использовали сканирование пути к классам. В этом случае вам нужно явно добавить поставщика в набор классов в вашем методе getClasses, так как вы переопределили метод для добавления других классов компонентов.

person Paul Samsotha    schedule 26.05.2016