一尘不染

如何在Struts2网格中显示模型类的嵌套属性?

jsp

我有一个由struts2-jquery-
grid-3.7.0
插件提供的网格,如下所示。

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

可以看出,在几列中有一些嵌套的属性。它们没有在给定的网格中列出(显示)。关联的列只是保留为空白。其余字段照常显示。

我也曾尝试将它们封闭在里面,%{...}但无济于事。

如何在网格中显示此类嵌套属性?有什么特别的待遇吗?

已验证这些嵌套属性是从数据库中获取的,并且模型已正确初始化。


编辑:

动作类:

@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;
    }
}

作为响应,所有这些嵌套属性均为空。单个行的JSON响应如下。

{
  "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
}

阅读 251

收藏
2020-06-10

共1个答案

一尘不染

includePproperties参数中,您需要

  • 指定内部属性的完整路径
  • 逃避点
  • \[\d\]当应用于非集合的对象时,删除第二个表示法

一个例子:

错误的gridModel\\[\\d+\\]\\.subCategory\\[\\d+\\]\\.category

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

2020-06-10