Wildfly抛出"无法找到一个构造函数,它接受一个String参数或一个valueOf()或fromString()方法,用于javax.ws.rs.QueryParam"错误

时间:2016-05-25 23:42:07

标签: rest jax-rs wildfly wildfly-9

我使用wildfly 9.0来部署我的war文件。我有我的REST GET端点中定义的Java LocalDateTime,Java Money类型。

当我部署war文件时,我得到以下错误[1]。基于这个答案[2]我写了#34; ParamConverterProvider"两种类型的实现。

工作正常(直到现在我还没有看到同样的问题)现在我得到同样的问题。 任何线索?

[1]

引起:java.lang.RuntimeException:无法找到为javax.ws.rs.QueryParam采用String参数或valueOf()或fromString()方法的构造函数(\" totalMoneyVolumeForPeriod \&# 34;)on public 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)for basetype:org.javamoney.moneta.Money"}}}}

[2]

jaxrs could not find my custom (de)serializers for joda.money type

示例代码

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;
    }
}

1 个答案:

答案 0 :(得分:2)

使用类路径扫描时,将使用@Path@Provider注释的JAX-RS组件被选中并注册。有几种方法可以使用类路径扫描。最常见的方法是使用Application注释 @ApplicationPath

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

这足以加载JAX-RS应用程序,并将应用程序的类路径扫描到组件进行注册。

但是,根据规范,一旦我们覆盖Set<Object> getSingletons类的任何Set<Class> getClassesApplication方法,并返回非空集,这会自动禁用类路径扫描,因为我们假设我们想要自己注册所有内容。

因此在以前的情况下,您可能只是使用类路径扫描。在这种情况下,您需要将提供程序显式添加到getClasses方法中的类集,因为您覆盖了方法以添加其他组件类。