【问题标题】:Can I have multiple bindy annotated classes in a package and still unmarshal CSVs in Camel?我可以在一个包中有多个绑定注释类并且仍然在 Camel 中解组 CSV?
【发布时间】:2013-05-06 23:24:55
【问题描述】:

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

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

【问题讨论】:

    标签: apache-camel bindy


    【解决方案1】:

    Camel 2.16.0 已修复此问题。

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

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

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

    【讨论】:

    • 哇!感谢您对此的更新,最好是在受支持的代码路径中。
    【解决方案2】:

    我对此的解决方案是按如下方式扩展 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();
        }
    
    }
    
    }
    

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

    【讨论】:

    • 看起来很棒,但是你如何告诉 Bindy/Camel 使用你的类而不是你重载的类?
    【解决方案3】:

    我在使用 Java DSL 时遇到了同样的问题。我有两个用 Bindy 注释的类,并且正在实例化“错误”的类。

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

    例如

    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")
    

    【讨论】:

      【解决方案4】:

      我的答案与上面相同,但代码更清晰。我在我的项目中尝试过,效果很好。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-29
        • 2019-07-21
        • 1970-01-01
        • 2016-08-27
        • 2010-11-13
        • 2012-11-12
        • 1970-01-01
        相关资源
        最近更新 更多