容易OA项目笔记(2):bean对象模型驱动多Action、每个Action单函数("redirect""prototype")
之前我写的例子是从jsp直接传递字符串,然后一类操作归为一个Action,每个Action中有好些具体执行的函数。项目中是:bean对象模型驱动多Action、每个Action单函数。
表单提交后,重复提交的问题、数据同步的问题也没考虑过,这个项目里都给出了解决方法。("redirect"、"prototype")
一:数据流
1:User.java
hibernate管理Annotation,
这儿插入数据时候,出过一个“ORA-01400: 无法将 NULL 插入”的错误
是因为oracle在删除完表格,并且提交之后,表格没有被真正删掉,新建同名表格以后,竟然两表格合并了,定义成NOT NULL的字段也就该报错了
2:提交Jsp
导入struts标签
<%@ taglib prefix="s" uri="/struts-tags"%>struts标签中用OGNL表达式提交表单
他这的显示用了的是i18n,语言的配置properties文件放在src下
<s:form action="saveUser"> <s:textfield name="user.firstname" label="%{getText('firstname')}"></s:textfield> <s:textfield name="user.lastname" label="%{getText('lastname')}"></s:textfield> <s:textfield name="user.age" label="%{getText('age')}"></s:textfield> <s:submit></s:submit> </s:form>
3:action
聚合service和user,但user不像我原来那样靠spring配置注入,只注入service就够了
private User user; private UserService service;
每个操作对应一个action,每个action对应一个execute()和一个validate(),便于管理
给action分组,user类的操作就对应:X.action.user包
public String execute() throws Exception { Map request = (Map) ActionContext.getContext().get("request"); request.put("list", service.findAll()); return SUCCESS; }
4:serviceImpl
继承于HibernateDaoSupport,然后用getHibernateTemplate(),靠spring注入sessionFactory就行了,
不用聚合sessionFactory,也不用聚合HibernateTemplate
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
public void saveUser(User user) { this.getHibernateTemplate().save(user); }
@SuppressWarnings("unchecked")是告诉编译器,不用检查强制类型转换了
@SuppressWarnings("unchecked") public List<User> findAllUsers() { String hql = "from User user order by user.id desc"; return (List<User>)this.getHibernateTemplate().find(hql); }
5:显示jsp
struts标签的表单,
迭代输出ognl取值
调用了ognl直接跳转到action的具体方法
还有个javascript用于确认删除数据
<table border="1" width="80%" align="center"> <tr> <td>序号</td> <td>姓</td> <td>名</td> <td>年龄</td> <td>删除</td> <td>更新</td> </tr> <s:iterator value="#request.list" id="ul"> <tr> <td><s:property value="#ul.id"/></td> <td><s:property value="#ul.firstname"/></td> <td><s:property value="#ul.lastname"/></td> <td><s:property value="#ul.age"/></td> <td><s:a href="deleteUser.action?user.id=%{#ul.id}" onClick="del();">delete</s:a></td> <td><s:a href="updatePUser.action?user.id=%{#ul.id}">update</s:a></td> </tr> </s:iterator> </table>
<script type="text/javascript"> function del() { if(confirm("你真的想删除该记录么?")) { return true; } return false; } </script>
二:struts处理
主要成功之后的重定向,type="redirect"
操作成功后,重定向相当于重新发问一下最新的action,不会出现数据不同步或者重复提交的问题
struts默认是“转发”(一个requset)会重复提交
“重定向”(俩request),重新请求一次,保证正确性
<action name="saveUser" class="saveUserAction"> <result name="success" type="redirect">listUser.action</result> <result name="input">/save.jsp</result> </action>
三:spring处理
主要是多例的问题,scope="prototype"
所有人的用户操作如果是都是访问单例singleton的SaveUserAction那就一定会出问题
“prototype”相当于每次请求都新创建一个实例,保证数据正确
<bean id="saveUserAction" class="com.test.action.user.SaveUserAction" scope="prototype"> <property name="service" ref="userService"></property> </bean> <bean id="listUserAction" class="com.test.action.user.ListUserAction" scope="prototype"> <property name="service" ref="userService"></property> </bean>
和spring管理的action相反:
dao只负责连接数据库,并没有状态,所以应配置成单例(spring容器内唯一实例)
//dataSource注入sessionFactory再注入dao
<bean id="userDao" class="com.xxx.dao.impl.xxx" scope=“singleton”>
//dao注入注入service
<bean id="userService" class="com.xxx.service.impl.xxx"》
<p userDao fer=userDao>