2012-12-13 33 views
0

对于我在Java/jsp中做的事情,我将会看到很多类似于可变对象的可视表格。每个对象具有不同数量的字段,但共享至少一个链接该对象的更详细页面的id动态生成各种对象的表格

所以我正在考虑制作一些我可以每次重复使用的东西的可能性,不管对象有多少个字段。

这里是想什么,我实现

Object A 
-id 
-name 
-address 

Object B 
-id 
-field2 
-field3 

想一个例子,那意思就是:

Table for Object A's 
id -- name -- address 
1  Bert Street 
2  Jeff Lane 

Table for Object B's 
id -- field2 -- field3 
1  AB   5 
2  Foo  Bar 

什么是实现这一目标的最佳方式是什么?我正在考虑(除id之外),为所有字段的两个对象添加一个可枚举的getter,然后遍历它以生成表。

有没有更好的方法?

+0

通用表理念几乎在每个程序员的一生中的某个时刻出现。这不是一个好主意,因为(1)字段名称和枚举值不适合向非技术用户呈现。 (2)国际化是不可能的。这样的代码最终需要几十个特殊情况才能显示列标题,另外还需要数字格式,日期/时间格式,列对齐等特殊情况。 – VGR

+0

(1)不会传递自定义命名字段来修复此问题,如Sinisa和杰罗姆的帖子? (2)我明白了为什么这可能会非常棘手,但是不能通过在将数据发送到jsp之前插入一个包装器来标记数据来解决这个问题,或者你是说这比麻烦更麻烦吗? – arnehehe

+0

我一直在使用它与我描述的表模型,并且我从来没有在显示任何类型的对象时出现问题,对于我们有国际化工作的每个项目也是如此,所以这也不是问题。在我给出的例子中,甚至有一些国际化的代码。我建议使用通用解决方案。你写了一次,你知道它有效,它将适用于所有未来的课程。 –

回答

1

我通常做的是什么创建一个类像这是一个Map<String,String>我表型号:

import java.io.Serializable; 
import java.util.Arrays; 
import java.util.List; 

import com.tricode.mrc.ui.web.messages.Messages; 

/** 
* 
* @author Sinisa 
* 
* @param <T> the entity type 
*/ 
public abstract class AbstractCrudForm<T extends Serializable> { 

     private List<T> data; 

     public AbstractCrudForm(List<T> data) { 
       this.data = data; 
     } 

     /** 
     * @param record 
     * @return the value of the id field of the given record 
     */ 
     protected abstract String getId(T record); 

     /** 
     * @return ui name of the entity that is displayed <br>i.e. for DataValidationConfiguration will return "Data Validation Configuration" 
     */ 
     public abstract String getUserFriendlyTypeName(); 

     /** 
     * @return the number of fields of the columns (fields) 
     */ 
     public abstract int getNumberOfFields(); 

     /** 
     * Return the column names as seen in the header of the crud table 
     * @return 
     */ 
     public abstract String[] getArrayOfColumnNames(); 

     /** 
     * @param record 
     * @param column 
     * @return 
     */ 
     protected abstract String getDataAtColumn(T record, int column); 

     /** 
     * Returns the data at the specified position 
     * @param row 
     * @param column 
     * @return the data at the specified position 
     */ 
     public String getDataAt(int row, int column) { 
       return getDataAtColumn(data.get(row), column); 
     } 

     /** 
     * @return a list of the data 
     */ 
     protected List<T> getData() { 
       return this.data; 
     } 

     /** 
     * @return the user friendly name for the title of the ui form for editing 
     */ 
     public String getUserFriendlyEditTypeName() { 
       return Messages.getString("AbstractCrudForm.Edit") + getUserFriendlyTypeName(); //$NON-NLS-1$ 
     } 

     /** 
     * @return the user friendly name for the title of the ui form for editing 
     */ 
     public String getUserFriendlySaveTypeName() { 
       return Messages.getString("AbstractCrudForm.New") + getUserFriendlyTypeName(); //$NON-NLS-1$ 
     } 

     /** 
     * @return a list of the column names 
     */ 
     public List<String> getColumns() { 
       return Arrays.asList(getArrayOfColumnNames()); 
     } 

     /** 
     * @param position 
     * @return the column name at a given position 
     */ 
     public String getColumnNameAt(int position) { 
       return getArrayOfColumnNames()[position]; 
     } 

     /** 
     * The result size 
     * @return 
     */ 
     public int resultsSize() { 
       return data.size(); 
     } 

     /** 
     * @param row 
     * @return the value of the id field for the given record 
     */ 
     public String getId(int row) { 
       return getId(data.get(row)); 
     } 

} 

对于每类我想要实现(在你的案件对象A和对象B)我重写这个抽象模型,是这样的:

import java.util.List; 

import com.tricode.misterchameleon.model.DataValidationConfiguration; 
import com.tricode.mrc.ui.web.AbstractCrudForm; 
import com.tricode.mrc.ui.web.messages.Messages; 

public class DataValidationConfigurationCrudForm extends AbstractCrudForm<DataValidationConfiguration> { 

     public DataValidationConfigurationCrudForm(List<DataValidationConfiguration> data) { 
       super(data); 
     } 

     @Override 
     public String getTypeName() { 
       return DataValidationConfiguration.class.getSimpleName(); 
     } 

     @Override 
     public String getUserFriendlyTypeName() { 
       return Messages.getString("DataValidationConfigurationCrudForm.DataValidationConfiguration"); //$NON-NLS-1$ 
     } 

     @Override 
     public int getNumberOfFields() { 
       // TODO take it with generics 
       return 8; 
     } 

     @Override 
     public String[] getArrayOfColumnNames() { 
       return new String[] { 
           Messages.getString("DataValidationConfigurationCrudForm.ID"), Messages.getString("DataValidationConfigurationCrudForm.DomainName"), Messages.getString("DataValidationConfigurationCrudForm.FormUrl"), Messages.getString("DataValidationConfigurationCrudForm.PostalCode"), Messages.getString("DataValidationConfigurationCrudForm.HouseNumber"), Messages.getString("DataValidationConfigurationCrudForm.Street"), Messages.getString("DataValidationConfigurationCrudForm.City"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ 
           Messages.getString("DataValidationConfigurationCrudForm.Country") }; //$NON-NLS-1$ 
     } 

     @Override 
     protected String getDataAtColumn(DataValidationConfiguration config, int column) { 
       switch (column) { 
       case 0: 
         return config.getId().toString(); 
       case 1: 
         return config.getDomainName(); 
       case 2: 
         return config.getFormUrl(); 
       case 3: 
         return config.getPostalCode(); 
       case 4: 
         return config.getHouseNumber(); 
       case 5: 
         return config.getStreet(); 
       case 6: 
         return config.getCity(); 
       case 7: 
         return config.getCountry(); 
       default: 
         throw new IllegalArgumentException(Messages.getString("DataValidationConfigurationCrudForm.YouShouldntHaveGottenHere")); //$NON-NLS-1$ 
       } 
     } 

     @Override 
     protected String getId(DataValidationConfiguration record) { 
       return record.getId().toString(); 
     } 

} 

我这个对象传递到JSP,然后我有绘制表格的通用JSP文件:

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 
<div class="row"> 
    <div class="twelve columns"> 
     <h1>${genForm.getUserFriendlyTypeName()}</h1> 

     <a href="${genForm.getCreateLink()}" class="btn_styled">Create</a> 
     <table class="border"> 
      <thead> 
       <tr> 
        <c:forEach var="col" items="${genForm.getColumns()}"> 
         <th>${col}</th> 
        </c:forEach> 
        <!-- Add two more for delete and edit --> 
        <th></th> 
        <th></th> 
       </tr> 
      </thead> 
      <c:if test="${genForm.resultsSize() == 0}"> 
       <tr colspan="${genForm.getNumberOfFields()}"> 
        <td><spring:message code="common.crud.norecords" text="common.crud.norecords"/></td> 
       </tr> 
      </c:if> 
      <c:if test="${genForm.resultsSize() > 0}"> 
       <c:forEach var="row" begin="0" end="${genForm.resultsSize() - 1}"> 
        <tr> 
         <c:set var="edit" value="?" /> 
         <c:forEach var="column" begin="0" 
          end="${genForm.getNumberOfFields() - 1}"> 
          <td>${genForm.getDataAt(row, column)}</td> 
          <c:set var="edit" 
           value="${edit}${genForm.getJavaFieldNameAt(column)}=${genForm.getDataAt(row, column)}&" /> 
         </c:forEach> 
         <!-- Add delete and edit buttons --> 
         <th><a id="edit-row" class="btn_styled" 
          href="${genForm.getEditLink()}${edit}"><spring:message 
            code="common.button.edit" text="common.button.edit" /></a></th> 
         <th><a id="delete-row" class="btn_styled" 
          href="${genForm.getDeleteLink()}?id=${genForm.getId(row)}"><spring:message 
            code="common.button.delete" text="common.button.delete" /></a></th> 
        </tr> 
       </c:forEach> 
      </c:if> 

     </table> 
    </div> 
</div> 

所有我发布的代码不应该被视为一个复制/粘贴的解决方案,因为它可能不能马上工作。它应该被看作是一个想法,并且是解决问题的一种干净方式。

2

您可以添加一个字段到您的主类,该字段将是Map<String,Object>,其中Map的密钥将是您的属性的名称。

或者,如果你的字段始终是字符串,你可以使用Properties,它们基本上是一些小波折(例如默认值)

+0

我想这几乎是我打算采取的方法。 不幸的是,我无法保证字符串值始终保持一致,所以我只能解决Map 的问题。谢谢 – arnehehe