How to display nested properties of a model class in Struts2 grid?

谁说胖子不能爱 提交于 2019-12-25 07:48:18

问题


I have a grid provided by the struts2-jquery-grid-3.7.0 plugin as follows.

<s:url id="remoteurl" action="ProductGrid" namespace="/admin_side"/>
<s:url id="editurl" action="ProductCRUD"/>

<sjg:grid
    id="gridmultitable"
    caption="Product"
    dataType="json"
    href="%{remoteurl}"
    pager="true"
    navigator="true"
    navigatorSearchOptions="{sopt:['eq','ne','lt','gt']}"
    navigatorEdit="false"
    navigatorView="false"
    navigatorAddOptions="{height:280, width:500, reloadAfterSubmit:true}"
    navigatorEditOptions="{height:280, width:500, reloadAfterSubmit:false}"
    navigatorViewOptions="{height:280, width:500}"
    navigatorDelete="true"
    navigatorDeleteOptions="{height:280, width:500,reloadAfterSubmit:true}"
    gridModel="gridModel"
    rowList="5,10,15"
    rowNum="5"
    rownumbers="true"
    editurl="%{editurl}"
    editinline="true"
    multiselect="true"
    onSelectRowTopics="rowselect"
    onEditInlineSuccessTopics="oneditsuccess"
    viewrecords="true"
    shrinkToFit="false"
    width="1045"
    >

    <sjg:gridColumn name="prodId" index="prodId" title="Id" key="true" frozen="true" width="200" formatter="integer" editable="false" dataType="Long" sortable="true" search="true" sorttype="integer" searchoptions="{sopt:['eq','ne','lt','gt']}"/>
    <sjg:gridColumn name="prodName" index="prodName" title="Product Name" width="200" editable="true" sortable="true" search="true" sorttype="text"/>
    <sjg:gridColumn name="prodCode" index="prodCode" title="Product Code" width="200" sortable="true" search="true" editable="true" sorttype="text"/>

    <!--Start nested properties-->

    <sjg:gridColumn name="subCategory.category.catName" index="subCategory.category.catName" title="Category" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="subCategory.subCatName" index="subCategory.subCatName" title="SubCategory" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="brand.brandName" index="brand.brandName" title="Brand" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="fabric.fabricName" index="fabric.fabricName" title="Fabric" width="200" sortable="true" search="true" editable="true" sorttype="text"/>

    <!--End nested properties-->

    <sjg:gridColumn name="marketPrice" index="marketPrice" title="Market Price" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="salePrice" index="salePrice" title="Sale Price" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="featured" index="featured" title="Featured" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="expressDelivery" index="expressDelivery" title="Express Delivery" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="weight" index="weight" title="Weight" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="quantity" index="quantity" title="Quantity" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="visible" index="visible" title="Visible" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="latest" index="latest" title="Latest" width="200" sortable="true" search="true" editable="true" sorttype="text"/>
    <sjg:gridColumn name="prodDesc" index="prodDesc" title="Description" width="200" sortable="true" search="true" editable="true" sorttype="text"/>

</sjg:grid>

As can be seen, there are some nested properties in a few columns. They are not listed (displayed) in the given grid. The associated columns are simply left blank. The rest of the fields are displayed as usual.

I have also tried enclosing them within %{...} but to no avail.

How to display such nested properties in a grid? Is there any special treatment for them?

It was verified that these nested properties were fetched from the database and the model was initialized correctly.


Edit:

The action class:

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value="json-default")
@InterceptorRefs({@InterceptorRef(value="store", params={"operationMode", "AUTOMATIC"})})
public final class ProductAction extends ActionSupport implements Serializable, ModelDriven<Product>
{
    @Autowired
    private final transient ProductService productService=null;
    private static final long serialVersionUID = 1L;

    private Product entity=new Product();
    private List<Product>gridModel=new ArrayList<Product>();

    private String id;
    // Get how many rows we want to have into the grid - rowNum attribute in the grid
    private Integer rows=5;
    // Get the requested page. By default grid sets this to 1.
    private Long page=1L;
    // sorting order - asc or desc
    private String sord;
    // get index row - i.e. user click to sord.
    private String sidx;
    // Search Field
    private String searchField;
    // The Search String
    private String searchString;
    // The Search Operation ['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
    private String searchOper;
    // Your Total Pages
    private Long total;
    // All Records
    private Long records;
    private String oper;

    @Override
    public Product getModel() {
        return entity;
    }

    @Action(value = "ProductCRUD",
    results = {
        @Result(name = ActionSupport.SUCCESS, location = "Product.jsp"),
        @Result(name = ActionSupport.INPUT, location = "Product.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "defaultStack", params = {"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
    public String edit() throws Exception {

        if(oper.equalsIgnoreCase("add")) {
            // Add a row.
        }
        else if(oper.equalsIgnoreCase("edit")) {
            // Update a row.
        }
        else if(oper.equalsIgnoreCase("del")) {
            // Delete a row.
        }
        return ActionSupport.SUCCESS;
    }

    @Action(value = "ProductGrid",
    results = {
        @Result(name = ActionSupport.SUCCESS, type = "json", params = {"includeProperties", "gridModel\\[\\d+\\]\\.prodId, gridModel\\[\\d+\\]\\.prodName, gridModel\\[\\d+\\]\\.prodCode, gridModel\\[\\d+\\]\\.prodDesc, gridModel\\[\\d+\\]\\.marketPrice, gridModel\\[\\d+\\]\\.salePrice, gridModel\\[\\d+\\]\\.featured, gridModel\\[\\d+\\]\\.expressDelivery, gridModel\\[\\d+\\]\\.weight, gridModel\\[\\d+\\]\\.occassion, gridModel\\[\\d+\\]\\.quantity, gridModel\\[\\d+\\]\\.visible, gridModel\\[\\d+\\]\\.latest, gridModel\\[\\d+\\]\\.subCategory, gridModel\\[\\d+\\]\\.fabric, gridModel\\[\\d+\\]\\.brand, gridModel\\[\\d+\\]\\.subCategory\\[\\d+\\]\\.category, total, records, rows, page, sord, sidx, searchField, searchString, searchOper", "excludeNullProperties", "true"})},
    interceptorRefs = {
        @InterceptorRef("params")})
    public String executeAction() {
        records=productService.rowCount().longValue();
        total=new BigDecimal(records).divide(new BigDecimal(rows), 0, BigDecimal.ROUND_CEILING).longValue();

        gridModel=productService.getList((int)(page-1)*rows, rows, new HashMap<String, String>(){{put(sidx, sord);}}, null);
        return SUCCESS;
    }

    public String getJSON() {
        return executeAction();
    }

    public List<Product> getGridModel() {
        return gridModel;
    }

    public void setGridModel(List<Product> gridModel) {
        this.gridModel = gridModel;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getRows() {
        return rows;
    }

    public void setRows(Integer rows) {
        this.rows = rows;
    }

    public Long getPage() {
        return page;
    }

    public void setPage(Long page) {
        this.page = page;
    }

    public String getSord() {
        return sord;
    }

    public void setSord(String sord) {
        this.sord = sord;
    }

    public String getSidx() {
        return sidx;
    }

    public void setSidx(String sidx) {
        this.sidx = sidx;
    }

    public String getSearchField() {
        return searchField;
    }

    public void setSearchField(String searchField) {
        this.searchField = searchField;
    }

    public String getSearchString() {
        return searchString;
    }

    public void setSearchString(String searchString) {
        this.searchString = searchString;
    }

    public String getSearchOper() {
        return searchOper;
    }

    public void setSearchOper(String searchOper) {
        this.searchOper = searchOper;
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public Long getRecords() {
        return records;
    }

    public void setRecords(Long records) {
        this.records = records;
    }

    public String getOper() {
        return oper;
    }

    public void setOper(String oper) {
        this.oper = oper;
    }

    @Action(value = "Product",
        results = {
            @Result(name=ActionSupport.SUCCESS, location="Product.jsp"),
            @Result(name = ActionSupport.INPUT, location = "Product.jsp")},
        interceptorRefs={
            @InterceptorRef(value = "defaultStack", params = {"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
    public String load() throws Exception {
        // This method is only needed to return an initial view on page load. Nothing to see here. Leave it empty.
        return ActionSupport.SUCCESS;
    }
}

In response, those all nested properties are empty. The JSON response for a single row is as follows.

{
  "gridModel": [
    {
      "brand": {

      },
      "expressDelivery": false,
      "fabric": {

      },
      "featured": true,
      "latest": false,
      "marketPrice": 12.00,
      "occassion": "222",
      "prodCode": "aaa",
      "prodDesc": "xxx",
      "prodId": 5,
      "prodName": "ddd",
      "quantity": 1,
      "salePrice": 12.00,
      "subCategory": {

      },
      "visible": true,
      "weight": 22.00
    }    
  ],
  "page": 1,
  "records": 5,
  "rows": 5,
  "sidx": "",
  "sord": "asc",
  "total": 1
}

回答1:


In the includePproperties param, you need to

  • specify the full path to the inner properties
  • escape the dots
  • remove the second \[\d\] notation when applied to objects that are not collections

An example:

wrong : gridModel\\[\\d+\\]\\.subCategory\\[\\d+\\]\\.category

right : gridModel\\[\\d+\\]\\.subCategory\\.category\\.catName



来源:https://stackoverflow.com/questions/21975294/how-to-display-nested-properties-of-a-model-class-in-struts2-grid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!