ModelDriven<T>

本文深入探讨了Java开发中ActionSupport的使用方法及其实现细节,包括如何通过ActionSupport进行模型驱动,以及实例代码解析。

public class LoginAction extends ActionSupport implements ModelDriven<T>{

private T t = new T();//这里需要new,否则取不到东西

public T getModel(){

return t;

}

}

public String toMainPage() throws Exception { // 通知公告资料下载 String sql = "select a.fsid as fsid,a.ftype as ftype,b.fendtime as ftime,fistop as fistop,fisbold as fisbold,a.ftitle as ftitle from tongzhi a,t_sys_flow_use b where a.fflowuseid=b.fsid and b.fstate='"+FlowDao.OVER+"' order by b.fendtime desc limit 5"; ActionContext.getContext().put("tongzhis", getSessionFactory().getCurrentSession().createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list()); ActionContext.getContext().put("xiazais", this.findAll(Xiazai.class, "fistop asc,ftime desc",5)); TSysDepartment department = this.findBySid(TSysDepartment.class, Tools.getCurrentUser().getFrybm()); List<String> roleNames = this.getPeoRole(Tools.getCurrentUser().getFsid()); CustomList<String> viewData = new CustomList(); if (Tools.getCurrentUser().getFsid().equals(AppConstants.SUPER_ADMIN_USER)) {//跳转到超级管理员界面; viewData.add("adminPageQuery","ndsjtj","jycqyjtj_all"); executeViewMethod(viewData); return "adminMain"; }else if("院领导".equals(department.getFdepmc())) { viewData.add("queryYlqxWaitDo","ndsjtj",roleNames.contains("授权签字人")?"jycqyjtj_all":""); }else if ("业务室".equals(department.getFdepmc()) && roleNames.contains("科室主任")) { viewData.add("queryYlqxWaitDo","chaoqiyujing_depart","ndsjtj"); }else if (StringUtils.equalsAny(department.getFdepmc(), "业务室","质量科") && !roleNames.contains("科室主任")) { viewData.add("queryYlqxWaitDo","chaoqiyujing_person"); }else if("是".equals(department.getFisjyjg())) { viewData.add("queryYlqxWaitDo","jycqyjtj_person"); if(roleNames.contains("科室主任")) viewData.add("jycqyjtj_depart"); } viewData.add("queryJJSWaitDo"); viewData.add("queryFuzhuWaitDo"); executeViewMethod(viewData); return "main"; }上述代码运行之后页面不显示数据只有空白行
最新发布
09-20
你提供的这段 Java 代码是一个典型的 Struts2 框架中的 Action 方法,用于跳转到主页面并准备一些数据(如通知公告、下载资料、待办事项等)传递给前端页面。然而你说“**页面不显示数据只有空白行**”,这说明后端可能没有正确地将数据传入页面,或者前端未正确渲染。 --- ### ✅ 问题分析 我们来逐步排查可能导致 **页面为空白、无数据显示** 的原因: --- #### 🔍 1. 数据查询是否成功? ```java String sql = "select a.fsid as fsid,a.ftype as ftype,b.fendtime as ftime,fistop as fistop,fisbold as fisbold,a.ftitle as ftitle from tongzhi a,t_sys_flow_use b where a.fflowuseid=b.fsid and b.fstate='"+FlowDao.OVER+"' order by b.fendtime desc limit 5"; ActionContext.getContext().put("tongzhis", getSessionFactory().getCurrentSession().createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list()); ``` - 使用了原生 SQL 查询,并通过 `ALIAS_TO_ENTITY_MAP` 转换为 `Map<String, Object>` 列表。 - 存在 **SQL 注入风险**:`b.fstate='"+FlowDao.OVER+"'` 是拼接字符串,应使用参数化查询。 - 更重要的是:如果查询结果为空或异常,`tongzhis` 就是空列表或 `null`,但不会报错,前端就看不到内容。 ✅ **建议改写为参数化查询**: ```java String sql = "SELECT a.fsid AS fsid, a.ftype AS ftype, b.fendtime AS ftime, a.fistop AS fistop, a.fisbold AS fisbold, a.ftitle AS ftitle " + "FROM tongzhi a, t_sys_flow_use b " + "WHERE a.fflowuseid = b.fsid AND b.fstate = :fstate " + "ORDER BY b.fendtime DESC LIMIT 5"; List<Map<String, Object>> tongzhis = getSessionFactory().getCurrentSession() .createSQLQuery(sql) .setParameter("fstate", FlowDao.OVER) .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); ActionContext.getContext().put("tongzhis", tongzhis); ``` > ⚠️ 如果不加 `.list()` 或查询出错,会返回 `null`,导致前端拿不到数据。 --- #### 🔍 2. `xiazais` 数据是否正常? ```java ActionContext.getContext().put("xiazais", this.findAll(Xiazai.class, "fistop asc,ftime desc",5)); ``` - 假设 `findAll(Class<T>, String orderBy, int maxResults)` 是自定义方法。 - 需确认: - `Xiazai` 类是否存在? - 是否有数据满足条件? - 排序字段名是否正确?比如 `fistop`, `ftime` 是否真实存在? - 返回值是否真的有数据?可以打印调试: ```java List<Xiazai> xiazais = this.findAll(Xiazai.class, "fistop asc,ftime desc", 5); System.out.println("Xiazai count: " + xiazais.size()); // 调试输出 ActionContext.getContext().put("xiazais", xiazais); ``` --- #### 🔍 3. `ActionContext.getContext().put(...)` 是否有效? Struts2 中,`ActionContext.getContext().put(key, value)` 相当于把数据放入 **ValueStack** 和 **OGNL Context**,供 JSP 页面使用 `${tongzhis}` 或 `<s:iterator value="tongzhis">` 访问。 但如果: - 页面使用的是 Thymeleaf / Freemarker 而不是 JSP; - 或者用了 ModelDriven 而没暴露属性; - 或 Struts 配置禁用了某些访问方式; 会导致数据无法读取。 ✅ 确保你在 JSP 页面中这样访问: ```jsp <s:iterator value="tongzhis" var="item"> <p>${item.fsid}: ${item.ftitle}</p> </s:iterator> ``` 而不是试图用 EL 表达式直接访问 `requestScope.tongzhis`。 --- #### 🔍 4. `executeViewMethod(viewData)` 干了什么? ```java executeViewMethod(viewData); ``` 这个方法看起来是你自己封装的逻辑,可能是根据角色动态执行某些“统计”或“待办任务”的查询,并把结果放到 `ActionContext`。 ⚠️ **关键点:这些数据是不是也放进 `ActionContext` 了?** 例如:`queryYlqxWaitDo` 方法内部有没有做类似: ```java ActionContext.getContext().put("ylqxWaitDoList", list); ``` 如果没有放进去,即使执行了方法,前端也无法获取数据。 👉 所以你需要检查 `executeViewMethod()` 内部实现,确保它确实把各种待办数据 put 到 context。 --- #### 🔍 5. 前端页面是否有错误?HTML 结构问题? 即使后台传了数据,前端也可能因为以下原因显示为空白行: - `<s:iterator>` 标签拼写错误; - OGNL 表达式写错,如 `${tongzhis[0].ftitle}` 访问越界; - CSS 隐藏了元素(如 `display:none`); - JavaScript 报错中断渲染; - 页面根本没写迭代逻辑! ✅ 示例正确的 JSP 显示代码: ```jsp <!-- 显示通知 --> <h3>通知公告</h3> <s:if test="tongzhis != null && !tongzhis.isEmpty()"> <s:iterator value="tongzhis" var="tz"> <div style="<s:property value='#tz.fisbold == 1 ? \"font-weight:bold\" : \"\"'/>"> <s:property value="#tz.ftitle"/> (<s:date name="#tz.ftime" format="yyyy-MM-dd HH:mm"/>) </div> </s:iterator> </s:if> <s:else> 暂无通知 </s:else> ``` --- #### 🔍 6. 异常被捕获但未打印? 当前方法声明抛出 `Exception`,但如果中间发生异常(如 SQL 错误、类转换异常),而你没日志记录,则可能静默失败。 ✅ 添加 try-catch 日志: ```java public String toMainPage() throws Exception { try { // 你的原有逻辑 } catch (Exception e) { e.printStackTrace(); log.error("toMainPage error", e); // 使用 log4j 或 slf4j throw e; } } ``` --- ### ✅ 解决方案总结与修复建议 下面是优化后的完整代码示例(含修复项): ```java public String toMainPage() throws Exception { try { // 1. 查询通知公告(参数化防止注入) String sql = "SELECT a.fsid AS fsid, a.ftype AS ftype, b.fendtime AS ftime, " + "a.fistop AS fistop, a.fisbold AS fisbold, a.ftitle AS ftitle " + "FROM tongzhi a JOIN t_sys_flow_use b ON a.fflowuseid = b.fsid " + "WHERE b.fstate = :fstate " + "ORDER BY b.fendtime DESC LIMIT 5"; List<Map<String, Object>> tongzhis = getSessionFactory().getCurrentSession() .createSQLQuery(sql) .setParameter("fstate", FlowDao.OVER) .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); System.out.println("Tongzhi size: " + tongzhis.size()); // 调试 ActionContext.getContext().put("tongzhis", tongzhis); // 2. 查询资料下载 List<Xiazai> xiazais = this.findAll(Xiazai.class, "fistop asc, ftime desc", 5); System.out.println("Xiazai size: " + xiazais.size()); ActionContext.getContext().put("xiazais", xiazais); // 3. 获取用户部门和角色 TSysDepartment department = this.findBySid(TSysDepartment.class, Tools.getCurrentUser().getFrybm()); List<String> roleNames = this.getPeoRole(Tools.getCurrentUser().getFsid()); CustomList<String> viewData = new CustomList<>(); if (Tools.getCurrentUser().getFsid().equals(AppConstants.SUPER_ADMIN_USER)) { viewData.add("adminPageQuery", "ndsjtj", "jycqyjtj_all"); } else if ("院领导".equals(department.getFdepmc())) { viewData.add("queryYlqxWaitDo", "ndsjtj"); if (roleNames.contains("授权签字人")) viewData.add("jycqyjtj_all"); } else if ("业务室".equals(department.getFdepmc()) && roleNames.contains("科室主任")) { viewData.add("queryYlqxWaitDo", "chaoqiyujing_depart", "ndsjtj"); } else if (StringUtils.equalsAny(department.getFdepmc(), "业务室", "质量科") && !roleNames.contains("科室主任")) { viewData.add("queryYlqxWaitDo", "chaoqiyujing_person"); } else if ("是".equals(department.getFisjyjg())) { viewData.add("queryYlqxWaitDo", "jycqyjtj_person"); if (roleNames.contains("科室主任")) viewData.add("jycqyjtj_depart"); } viewData.add("queryJJSWaitDo"); viewData.add("queryFuzhuWaitDo"); executeViewMethod(viewData); // 确保该方法内 put 了对应的数据 return "main"; } catch (Exception e) { e.printStackTrace(); log.error("Error in toMainPage", e); throw e; } } ``` --- ### ✅ 排查清单(你可以逐条验证) | 检查项 | 是否完成 | |------|--------| | 后台打印 `tongzhis.size()` 和 `xiazais.size()` | ✅ | | SQL 改为参数化查询 | ✅ | | `executeViewMethod` 是否真正向 context 放数据 | ✅ | | JSP 页面是否用 `<s:iterator value="tongzhis">` 正确遍历 | ✅ | | 浏览器开发者工具查看响应 HTML 是否包含数据 | ✅ | | 控制台/日志有无异常输出 | ✅ | --- ### ❓常见相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值