属性\“currency \”的setter定义冲突:javax.money.MonetaryAmountFactory

时间:2016-05-26 01:06:51

标签: json jackson jax-rs wildfly swagger

我在REST端点中使用org.javamoney.moneta.Money类型。我已经实施了ParamConverterProvider。当我在wildfly中部署war文件时,我收到此错误[1]

我如何克服这个问题?

Money类型的示例实现是;

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

}

[1]

10:35:41,056 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 185) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./test2dbwar: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./test2dbwar: java.lang.IllegalArgumentException: Conflicting setter definitions for property "currency": javax.money.MonetaryAmountFactory#setCurrency(1 params) vs javax.money.MonetaryAmountFactory#setCurrency(1 params)
    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.IllegalArgumentException: Conflicting setter definitions for property "currency": javax.money.MonetaryAmountFactory#setCurrency(1 params) vs javax.money.MonetaryAmountFactory#setCurrency(1 params)
    at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getSetter(POJOPropertyBuilder.java:293)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:246)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:127)
    at io.swagger.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:99)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:106)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71)
    at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:342)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:127)
    at io.swagger.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:99)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:106)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71)
    at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:342)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:127)
    at io.swagger.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:99)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:106)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71)
    at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:342)
    at io.swagger.jackson.ModelResolver.resolve(ModelResolver.java:127)
    at io.swagger.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:99)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:106)
    at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:71)
    at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:79)
    at io.swagger.converter.ModelConverters.readAsProperty(ModelConverters.java:58)
    at io.swagger.util.ParameterProcessor.applyAnnotations(ParameterProcessor.java:175)
    at io.swagger.jaxrs.Reader.getParameters(Reader.java:914)
    at io.swagger.jaxrs.Reader.parseMethod(Reader.java:852)
    at io.swagger.jaxrs.Reader.read(Reader.java:293)
    at io.swagger.jaxrs.Reader.read(Reader.java:145)
    at io.swagger.jaxrs.config.BeanConfig.scanAndRead(BeanConfig.java:223)
    at io.swagger.jaxrs.config.BeanConfig.setScan(BeanConfig.java:204)

1 个答案:

答案 0 :(得分:0)

以下内容应在Swagger 2.0.6以及某些早期版本中起作用。

实现io.swagger.v3.oas.integration.api.ObjectMapperProcessor将MixIns传递给Jackson的对象映射器。

package myPkg;

import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.MonetaryAmountFactory;
import javax.xml.bind.annotation.XmlTransient;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;

public class MyObjectMapperProcessor implements io.swagger.v3.oas.integration.api.ObjectMapperProcessor {

  @Override
  public void processJsonObjectMapper(ObjectMapper objectMapper) {
    addMixIns( objectMapper );
  }

  @Override
  public void processYamlObjectMapper(ObjectMapper objectMapper) {
    addMixIns( objectMapper );
  }

  private void addMixIns(ObjectMapper objectMapper) {
    objectMapper.addMixIn( MonetaryAmountFactory.class , MixIn.class );
  }

  public abstract class MixIn {
    @JsonIgnore
    @XmlTransient
    public abstract MonetaryAmountFactory setCurrency(CurrencyUnit currency);

    @JsonIgnore
    @XmlTransient
    public abstract MonetaryAmountFactory setCurrency(String currencyCode);
  }
}

在初始化代码中,将ObjectMapperProcessor类的名称传递给SwaggerConfiguration。

String ctxId = "myContextId";

try {
  JaxrsOpenApiContextBuilder builder = new JaxrsOpenApiContextBuilder();
  builder.setCtxId(ctxId);
  builder.openApiConfiguration(
    new SwaggerConfiguration()
      .resourcePackages( resourcePackages )
      .resourceClasses( resourceClasses )
      .objectMapperProcessorClass( "myPkg.MyObjectMapperProcessor" )
      .prettyPrint(true)
  );

  OpenApiContextLocator.getInstance().putOpenApiContext(
    ctxId ,
    builder.buildContext(true)
  );
} catch (OpenApiConfigurationException e) {
  throw new RuntimeException(e.getMessage(), e);
}