0

我正在使用ZK Charts在我的 ZK 框架中构建 HighCharts。在模型 Java 文件中,他们使用静态块在模型中加载硬编码值。例如

static {
    model = new DefaultCategoryModel();
    model.setValue("John", "Apples", new Integer(5));
    model.setValue("John", "Oranges", new Integer(3));
    model.setValue("John", "Pears", new Integer(4));
    model.setValue("John", "Grapes", new Integer(7));
    model.setValue("John", "Bananas", new Integer(2));
    model.setValue("Jane", "Apples", new Integer(2));
    model.setValue("Jane", "Oranges", new Integer(2));
    model.setValue("Jane", "Pears", new Integer(3));
    model.setValue("Jane", "Grapes", new Integer(2));
    model.setValue("Jane", "Bananas", new Integer(1));
    model.setValue("Joe", "Apples", new Integer(3));
    model.setValue("Joe", "Oranges", new Integer(4));
    model.setValue("Joe", "Pears", new Integer(4));
    model.setValue("Joe", "Grapes", new Integer(2));
    model.setValue("Joe", "Bananas", new Integer(5));
}

我的图表很好,但有默认值。现在我想让它动态化。我有几项服务可以为我提供库存水平的产品。这个想法是我想使用这些图表显示低库存警报。

我试图在静态块中调用这些服务,但它抛出空指针异常。

public class BarStackedData
{
private static CategoryModel model;

@Autowired
private static DefaultCustomCommerceCartService defaultCustomCommerceCartService;

@Autowired
private static ProductService productService;

static
{
    model = new DefaultCategoryModel();

    model.setValue(
            "Low Stock",
            "Puma T-Shirts",
            new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                    null)));
    model.setValue(
            "Low Stock",
            "Socks",
            new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                    null)));

    ....... more code .....

}

public static CategoryModel getCategoryModel()
{
    return model;
}

我知道静态块是一个静态初始化器。它将在加载类时执行。但是有没有办法让它动态或者我怎么能用动态值显示这对图表。

日志 :

SEVERE: Servlet.service() for servlet [zkLoader] in context with path [/backoffice] threw       exception [Servlet java.lang.NullPointerException
    at com.rfn.model.BarStackedData.<clinit>(BarStackedData.java:30)
    at com.rfn.widgets.BarStackedComposerController.doAfterCompose(BarStackedComposerController.java:22)
    at com.rfn.widgets.BarStackedComposerController.doAfterCompose(BarStackedComposerController.java:1)
4

2 回答 2

3

静态块中的代码可能在您设置自动装配的变量之前执行 - 因此是 NullPointerException。

您可以尝试创建一个方法并使用 @PostConstruct 对其进行注释,并且在正确配置所有内容后,框架将调用该方法。

@Service
public class BarStackedData
{
    private CategoryModel model;

    @Autowired
    private DefaultCustomCommerceCartService defaultCustomCommerceCartService;

    @Autowired
    private ProductService productService;

    @PostConstruct
    private void setupModel()
    {
        model = new DefaultCategoryModel();

        model.setValue(
                "Low Stock",
                "Puma T-Shirts",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
                "Low Stock",
                "Socks",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

        ....... more code .....

    }

    public CategoryModel getCategoryModel()
    {
        return model;
    }
}

编辑

您需要接口通过静态方法,以便外部图表库可以访问数据。这是我的解决方案,它使用外观类来使静态方法的使用远离主服务:

@Service
public class BarStackedData
{
    private CategoryModel model;

    @Autowired
    private DefaultCustomCommerceCartService defaultCustomCommerceCartService;

    @Autowired
    private ProductService productService;

    @PostConstruct
    private void setupModel()
    {
        model = new DefaultCategoryModel();

        model.setValue(
                "Low Stock",
                "Puma T-Shirts",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
                "Low Stock",
                "Socks",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

        ....... more code .....

    }

    public CategoryModel getCategoryModel()
    {
        return model;
    }
}


@Component
public class DataFacade {

    private static BarStackedData barStackedModel = null;

    @Autowired
    private setBarStackedData(final BarStackedData barStackedModel) {
        DataFacade.barStackedModel = barStackedModel;
    }

    public static CategoryModel getCategoryModel() {
        return barStackedModel.getCategoryModel();
    }

}
于 2014-05-12T04:25:37.123 回答
1

你为什么使用静态块。你也可以在没有它的情况下完成你的工作。

尝试这个 ..

public class BarStackedData
{

   private static CategoryModel model;
   private static DefaultCustomCommerceCartService defaultCustomCommerceCartService;
   private static ProductService productService;

   public static CategoryModel getCategoryModel()
   {
        model = new DefaultCategoryModel();

        model.setValue(
        "Low Stock",
        "Puma T-Shirts",
        new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
        "Low Stock",
        "Socks",
        new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

      ....... more code .....

      return model;
   }

   // Getter Method
   public DefaultCustomCommerceCartService getDefaultCustomCommerceCartService()
   {
      return defaultCustomCommerceCartService;
   }

   // Setter Method
   public void setProductService(ProductService productService)
   {
      this.productService = productService;
   }

}

现在在 spring.xml 文件中注册 bean

<bean id="barStackedData" class="com.java.project.BarStackedData" >
    <property name="defaultCustomCommerceCartService" ref="defaultCustomCommerceCartService" />
    <property name="productService" ref="productService" />
</bean>

正如我在 ZK Chart 中看到的,他们正在使用 Controller。尝试通过注册表获取 bean。

public class BarStackedComposer extends SelectorComposer<Window> 
{
@Wire
Charts chart;

BarStackedData barStackedData;

public void doAfterCompose(Window comp) throws Exception {
    super.doAfterCompose(comp);

    // get spring bean 
    barStackedData = (BarStackedData) Registry.getApplicationContext().getBean("barStackedData");

    chart.setModel(BarStackedData.getCategoryModel());

    chart.getYAxis().setMin(0);
    chart.getYAxis().setTitle("Total fruit consumption");

    chart.getLegend().setBackgroundColor("#FFFFFF");
    chart.getLegend().setReversed(true);

    chart.getPlotOptions().getSeries().setStacking("normal");

    chart.getCredits().setEnabled(false);
 }
}

希望这会帮助你......享受:)

于 2014-05-25T17:07:38.290 回答