我使用wildfly 9.0来部署我的war文件。我在REST GET端点中定义了java LocalDateTime、java Money类型。
当我部署我的war文件时,我得到以下错误[1]。基于这个答案[2],我已经为这两种类型编写了"ParamConverterProvider"实现。
它运行得很好(直到现在我还没有看到同样的问题),现在我遇到了同样的问题。有线索吗?
[1]
由以下原因引起:java.lang.RuntimeException:在公共javax.ws.rs.core.Response com.test.rest.StockEndpoint.getItems上找不到为javax.ws.s.QueryParam(\"totalMoneyVolumeForPeriod")采用String param或valueOf()或fromString()方法的构造函数(java.lang.Integer,java.lang.Interger,java.lang.String,java.lang.String
[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;
}
}
使用类路径扫描时,会拾取并注册用@Path
或@Provider
注释的JAX-RS组件。有两种方法可以使用类路径扫描。最常见的方法是只使用@ApplicationPath
注释空Application
类
@ApplicationPath("/api")
public class MyApplication extends Application {}
这足以加载JAX-RS应用程序,并将应用程序的类路径扫描到要注册的组件。
但是,根据规范,一旦我们重写Application
类的任何Set<Object> getSingletons
或Set<Class> getClasses
方法,并返回非空集,这将自动禁用类路径扫描,因为假设我们想自己注册所有内容。
所以在以前的情况下,您可能只是使用类路径扫描。在这种情况下,您需要将提供程序显式添加到getClasses
方法中的类集,因为您重写了该方法以添加其他组件类。