之前我写的例子是从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>