首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

SSH 电商项目实战(七):Struts2 整合 JSON 实现 EasyUI DataGrid 数据交互

     編輯:Java 相關知識

从静态 JSON 到动态数据:Struts2 JSON 插件全集成

上篇实现了 EasyUI DataGrid 静态 JSON 展示,本篇打通「前端 DataGrid ↔ Struts2 Action ↔ Service ↔ DB」完整数据链路,实现分页、条件查询、关联对象序列化控制。

核心架构流程

EasyUI DataGrid (url: 'category_queryJoinAccount.action', page, rows)
        ↓ HTTP GET/POST
Struts2 Dispatcher → CategoryAction.queryJoinAccount()
        ↓ 注入参数 (model.type, page, rows)
CategoryService.queryJoinAccount(type, page, rows) → Hibernate HQL 分页查询
        ↓ 返回 List (含关联 Account)
Action 封装 Map pageMap { total, rows }
        ↓ Struts2 JSON Result (root=pageMap, excludeProperties)
JSON 响应 → DataGrid 渲染

关键代码实现

1. 基础 Action 封装分页参数

@Controller("baseAction")
@Scope("prototype")
public class BaseAction<T> extends ActionSupport 
        implements ModelDriven<T>, RequestAware, SessionAware, ApplicationAware {
    
    // EasyUI 分页参数自动注入
    protected Integer page;   // 当前页
    protected Integer rows;   // 每页行数
    
    // JSON 结果数据容器
    protected Map<String, Object> pageMap = new HashMap<>();
    
    // ModelDriven 自动实例化模型对象
    @Override public T getModel() { ... }
    
    // 域对象注入
    @Override public void setRequest(Map<String, Object> request) { this.request = request; }
    // ... session, application 同理
}

2. CategoryAction 业务处理

@Controller("categoryAction")
@Scope("prototype")
public class CategoryAction extends BaseAction<Category> {
    
    @Resource CategoryService categoryService;
    
    public String queryJoinAccount() {
        pageMap = new HashMap<>();
        
        // 1. 条件分页查询数据行
        List<Category> rows = categoryService.queryJoinAccount(
            model.getType(), page, rows);
        pageMap.put("rows", rows);
        
        // 2. 查询总记录数(用于分页控件)
        Long total = categoryService.getCount(model.getType());
        pageMap.put("total", total);
        
        return "jsonMap"; // 对应 struts.xml result name
    }
}

3. Service 层 HQL 实现

@Service("categoryService")
public class CategoryServiceImpl extends BaseServiceImpl<Category> 
        implements CategoryService {
    
    @Override
    public List<Category> queryJoinAccount(String type, int page, int size) {
        String hql = "FROM Category c LEFT JOIN FETCH c.account WHERE c.type LIKE :type";
        return getSession().createQuery(hql)
            .setString("type", "%" + type + "%")
            .setFirstResult((page - 1) * size)
            .setMaxResults(size)
            .list();
    }
    
    @Override
    public Long getCount(String type) {
        String hql = "SELECT COUNT(c) FROM Category c WHERE c.type LIKE :type";
        return (Long) getSession().createQuery(hql)
            .setString("type", "%" + type + "%")
            .uniqueResult();
    }
}

4. struts.xml JSON 结果精细配置

<package name="shop" extends="json-default"> <!-- 继承 json-default 包含 struts2-json-plugin -->
    <action name="category_*" class="categoryAction" method="{1}">
        <result name="jsonMap" type="json">
            <!-- 指定序列化根对象 -->
            <param name="root">pageMap</param>
            
            <!-- 排除敏感/循环引用字段:Account.password -->
            <param name="excludeProperties">
                rows\[\d+\]\.account\.password
            </param>
        </result>
    </action>
</package>

关键点:

  • extends="json-default":必须继承,提供 type="json" Result 类型
  • root=pageMap:只序列化 Map,避免序列化整个 Action 对象
  • excludeProperties:正则排除字段,rows\[\d+\]\.account\.password 匹配列表中每个元素的关联对象密码字段,防止敏感信息泄露

5. 前端 DataGrid 完整配置

$('#dg').datagrid({
    url: 'category_queryJoinAccount.action',
    loadMsg: 'Loading......',
    queryParams: { type: '' }, // 传递查询条件
    fitColumns: true,
    striped: true,
    nowrap: true,
    singleSelect: true,
    pagination: true, // 启用分页工具栏
    
    // 行样式交替
    rowStyler: function(index, row) {
        return index % 2 == 0 ? 'background:#fff' : 'background:#ffffe0';
    },
    
    // 冻结列(复选框+ID)
    frozenColumns: [[
        { field: 'ck', checkbox: true },
        { field: 'id', title: '编号', width: 80 }
    ]],
    
    // 普通列
    columns: [[
        { 
            field: 'type', title: '分类名称', width: 120,
            formatter: (v, r, i) => '<span title="' + v + '">' + v + '</span>'
        },
        { 
            field: 'hot', title: '热销', width: 80,
            formatter: (v, r, i) => v 
                ? '<input type="checkbox" checked disabled>' 
                : '<input type="checkbox" disabled>'
        },
        { 
            field: 'account.login', title: '所属管理员', width: 150,
            formatter: (v, r, i) => r.account?.login ?? '无管理员'
        }
    ]]
});

JSON 响应示例

{
  "total": 25,
  "rows": [
    {
      "id": 1,
      "type": "手机数码",
      "hot": true,
      "account": { "id": 2, "login": "admin", "name": "管理员A" } // password 已排除
    },
    ...
  ]
}

常见问题排查

现象原因解决
DataGrid 显示 "total:0, rows:[]"root 对象不包含 total/rows 字段检查 Action 封装 Map 键名、struts.xml root 配置
分页工具栏不显示/页码错乱total 值类型不对或未返回确保 Service 返回 Long,Action 放入 Map
关联对象序列化报错/死循环双向关联循环引用excludeProperties 排除反向引用,或实体加 @JsonIgnore
中文乱码响应编码未设置struts.xml <constant name="struts.i18n.encoding" value="UTF-8"/>

总结

Struts2 整合 JSON 核心在于:Action 封装标准 Map 结构 → json-default 包提供序列化 → excludeProperties 精准控制输出。配合 EasyUI DataGrid 标准协议(total+rows),实现零胶水代码的前后端数据交互。下一步可扩展:编辑器联动、导出 Excel、批量操作等企业级功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved