我可以在包中包含多个bindy注释类,并且仍然可以在Camel中解组CSV吗?

时间:2013-05-06 23:24:55

标签: apache-camel bindy

我想有一个像my.company.bindy这样的包,其中有几个类都使用Bindy注释注释。然后我想让Camel路由可以将CSV解组为其中一种类型。我已经完成了所有工作,但如果我在包中有多个bindy注释类,则解组失败。这是因为Bindy试图将CSV行解组到包中的每个类中。并且特定的行不会正确地编组到多个类中。我的数据格式在Spring中声明如下:

<bean class="org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat">
    <property name="packages" value="my.company.bindy"/>
</bean>

4 个答案:

答案 0 :(得分:4)

我的解决办法是按如下方式扩展BindyCsvDataFormat:

/**
* This class changes the behavior of BindyCsvDataFormat. Instead of detecting classes
* in package(s) which are annotated with bindy annotations, this class, specifically
* defines the class that will be unmarshalled into.
*/
public class SingleClassBindyCsvDataFormat extends BindyCsvDataFormat {

private Class<?> modelClass;

@Override
protected BindyAbstractFactory createModelFactory(PackageScanClassResolver resolver) throws Exception {
    return new OneClassBindyCsvFactory(resolver, getModelClass());
}

@Override
public void setPackages(String... packages) {
    throw new UnsupportedOperationException("This dataformat does not support package based model searches.");
}

public Class<?> getModelClass() {
    return modelClass;
}

public void setModelClass(Class<?> modelClass) {
    this.modelClass = modelClass;
}

private static class OneClassBindyCsvFactory extends BindyCsvFactory {

    public OneClassBindyCsvFactory(PackageScanClassResolver resolver, Class<?> modelClass) throws Exception {
        super(resolver, new String[]{});
        Preconditions.checkNotNull(modelClass);
        models = ImmutableSet.<Class<?>>of(modelClass);
        initCsvModel();
    }

}

}

到目前为止,它的作用就像一个魅力!

答案 1 :(得分:4)

此问题已通过Camel 2.16.0修复。

来自http://camel.apache.org/bindy.html

“如果你使用多个模型,每个模型必须放在它自己的包中,以防止出现不可预测的结果。

从Camel 2.16开始不再是这种情况,因为您可以在同一个包中安全地拥有多个模型,因为现在使用类名而不是包名来配置bindy。“

答案 2 :(得分:0)

我使用Java DSL遇到了同样的问题。我有两个用Bindy注释的课程和#34;错误&#34;上课正在实例化。

该实例中的解决方案是完全限定我绑定的包名称

E.g。

from("file:myfile.csv").
  unmarshall().
    bindy(BindyType.Csv, com.company.domain.OrderLine.class).
to("seda:output")

而不是

from("file:myfile.csv").
  unmarshall().
    bindy(BindyType.Csv, OrderLine.class).
to("seda:output")

答案 3 :(得分:0)

我的回答与上述相同,但代码更清晰。我在我的项目中试过它并且工作正常。

import org.apache.camel.dataformat.bindy.BindyAbstractFactory;
import org.apache.camel.dataformat.bindy.BindyCsvFactory;
import org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat;
import org.apache.camel.spi.PackageScanClassResolver;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;

public class CustomBindyCsvDataFormat extends BindyCsvDataFormat {

private Class<?> modelClass;

public CustomBindyCsvDataFormat(Class<?> modelClass) {
    this.modelClass = modelClass;
}

public Class<?> getModelClass() {
    return modelClass;
}

@Override
protected BindyAbstractFactory createModelFactory(PackageScanClassResolver resolver) throws Exception {

    return new CustomBindyCsvFactory(resolver, getModelClass());
}

private class CustomBindyCsvFactory extends BindyCsvFactory {

    public CustomBindyCsvFactory(PackageScanClassResolver resolver, Class<?> modelClass) throws Exception {
        super(resolver, new String[] {});
        Preconditions.checkNotNull(modelClass);
        models = ImmutableSet.of(modelClass);
        initCsvModel();
    }

}

}

而不是使用packageName作为字符串args调用BindyCsvDataFormat,我们可以使用具有完全限定类名作为参数的CustomBindyCsvDataFormat。