【问题标题】:Dynamically load a tag for a list of objects of different types为不同类型的对象列表动态加载标签
【发布时间】:2015-04-22 01:41:21
【问题描述】:

我有一个非常不同但需要成为一个列表的一部分的对象列表。例如页面上的小部件列表(天气、时钟、facebook..)。它需要在一个列表中,因为该列表需要按 10 块为一组进行排序、随机化和分页。

我当前解决方案的高级视图如下所示:

一个抽象基类:

abstract class MyBaseClass
{
 Object getMe()
 {
  return this;
 }
}

一个公共父类

public class Common extends MyBaseClass
{
  public String commonMethod()
  {
    return "somestring";
  }
}

其他类

public class A extends Common
{
   public String method_1_ForA();
   public String method_2_ForA();
}

public class B extends Common
{
   public String method_1_ForB();
   public String method_2_ForB();
}

它的实现如下所示:

public class MyQuickTest
{

 public void test()
 {
   List<A> listA = new ArrayList<>();
   List<B> listB = new ArrayList<>();

   List<Common> listCommon = new ArrayList<>();
   listCommon.addAll(listA);
   listCommon.addAll(listB);

   foreach(Common common:listCommon)
   {
      common.getMe(); //will return an object of type A or B
   }

 }

}

为了显示上面的内容,我必须使用自定义标签库返回上面的列表,并遍历我的 jsp 中的对象列表。然后对于每个对象,我必须检查类型,然后调用适当的 jsp/.tag 来呈现项目。

我的问题是:

  1. 有没有比从基类返回“对象”更好的方法来支持这一点?
  2. 如何避免在我的 JSP 中编写 if's?有没有一种方法可以完全根据类型加载标签? - 谷歌告诉我没有......或者如果不是按类型加载,是否还有其他技术、方法或设计模式可以提供更优雅的解决方案?

当前解决方案:

/// loop
 <c:if test="${type==A}"> call render A JSP </c:if>
 <c:if test="${type==B}"> call render B JSP </c:if>     
// end loop

有希望的解决方案:

//loop
  <dispatcher type="${type}"/> //load the appropriate render tag for the object
//end loop

任何帮助或建议将不胜感激。

【问题讨论】:

    标签: java jsp arraylist collections jsp-tags


    【解决方案1】:

    我相信我已经设法找到了上述两个问题(Q1、Q2)的解决方案。我的发现如下:

    第一季度。我不需要返回对象的基类;只要所有子类都继承自“Common”,我就可以返回一个 Common 列表并使用 instanceof 获取子类型信息。因此,考虑到原始示例,我可以省略抽象类“MyBaseClass”,而是执行以下操作。

    public class MyQuickTest
    {
    
     public void test()
     {
      List<A> listA = new ArrayList<>();
      List<B> listB = new ArrayList<>();
    
      List<Common> listCommon = new ArrayList<>();
      listCommon.addAll(listA);
      listCommon.addAll(listB);
    
      foreach(Common common:listCommon)
      {
       if(common instanceof B)
       {
        B b = (B) common;
        String s = b.method_1_ForB();
        //do some other logicfind solutions for the above problem.
       }
      }
    
    }
    

    第二季度。有两种选择: 一世。加载 html 卡盘作为对象的一部分(装饰器模式最适用)。这与 sitemesh 采用的方法非常相似。所以伪代码是这样的:

    //loop
     <c:out value='${common.renderMe}'/> //print the string output (this can be the output of a velocity, thymleaf template render)
    //end loop
    

    二。动态加载适当的 JSP 并执行 JSP 包含。不幸的是,JSP 包含不能将对象作为参数,因此您需要使用一种方法作为 here 使用嵌套范围变量的方法。

    *我选择使用选项“ii”,因为有一个明确的关注点分离,即对象不需要知道它是如何呈现的,而是全部专用于 JSP。 JSP 方法对其他团队成员来说也更直观,并且与我们现有项目的常用方法保持一致 *

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 2021-11-26
      • 2015-03-07
      • 2012-11-23
      相关资源
      最近更新 更多