1. 完成练习
==(0) 死循环的解释
add完一个分类,再通过/Category.do转发到showCategories页面,将是一个request,url参数也被带上,将导致不断地调用add;
解决方法是将这个forward的redirect="true"
==(1) 写完list.jsp的分类显示;
==(2) 需要在Filter中增加事务的开始与提交;
=====异常的处理
==(3) 列表页面的添加超链接
=====测试一个超链接:把它放在上面,单独测试一下
==(4) 很多页面都需要写导入标签的操作,重复;解决:静态导入
commons.jspf
<%@page language="java" pageEncoding="UTF-8">
...
*.jsp
<%@include file="/WEB-INF/pages/public/commons.jspf%>
==(5) CategoryAction.add
添加分类名
==(6) 验证
先写服务器端验证: Form.validate
后写客户端验证 : html:form OnSubmit=js
js -> function validate(form)
form.name.value -- 获取name的值
form.name.value.length ==0
returnfalse;
returntrue;
2. 修改和删除功能
== (1) 修改和删除页面相似,使用同一个页面
===将参数hidden
hidden1:{method, value ="${param.id>0 ? 'edit' : 'add'}" //param.id, CategoryForm.id}
hidden2:{id, value}
===Action.editUI
准备分类信息
===Action.edit
更新分类信息
==原有的add方法中验证代码此处也使用;
抽取出来一个方法:booleanvalidateFailed
失败= true; 成功 =false;
==关于编辑时填充原有信息的解释:
FormBean,html:form
editUI中根据请求id获取实体,并填充FormBean
edit根据FormBean中id先获取实体,再更新实体
==服务器端和客户端都对名字是否为空的校验:
用户有可能绕过js校验,直接输入url;
??如何解决id输入了非数字的问题,有没有好的方案?
3. 排序: 按order升序
== select * from itcast_category order byorder;
== 可能2次修改order值
== 需要修改:业务方法
=== 显示分类:列表list --按order排序
===增加分类:添加add --指定为max+1(由Service指定,唯一,新增的在最下面)
===移动分类:上下移动changeOrder -- 可能2次修改order的值
最上面的不能上移,最下面的不能下移;
== 对分类排序时要修改的方法:
===1,在显示所有的分类时,应按照Category.order的值进行升序排列(修改dao
中的find()方法)。
===2,要保证每个Category都有一个唯一的order的值,并且order是在添加分类时
由业务方法定的(CategoryService.addCategory),希望新增的分类显示到
最下面,即order的值最大。
===3,实现让分类上下移动的业务方法CategoryService.changeOrder:让被操作
的Category与显示在他上面的分类(如果是上移)或与显示在他下面的分类
(如果是下移)交换order的值。最上面的不能上移;最下面的不能下移。
== 练习:
(1)写list方法时发现Category和Forum的排序可能不一样,需要修改
在相应的DAOImpl中覆盖find,findAll方法
(2)添加时,Service应该先获取order,再传给DAO
获取maxorder :CategoryDAO增加方法 GenericDAO中增加接口方法;GenericDAOImpl
中使用反射实现(试试beanUtils),2个子类还是要覆盖;
(3)DAO中没有changeOrder方法:从GenericDAO增加一个
== 课堂实现:
(1) add:利用id,让order=id
(2)如何查找上面或下面的分类
定义按order排序两个方法getPrevious(Categoryc), getNext()
如果已经是最上面了,如果是最下面了
== 犯了一个严重的错误:在DAO层中加了太多业务
(3)在具体的DAOImpl中覆盖有关方法;不修改父类原有的方法;
== 乱码问题:
(1) 程序或是数据库中产生乱码?
(2)请求之前调用request.setCharacterEncoding("UTF-8");放在Filter中
4. 对版面的增删改查:基本同分类;
=== 4.1 jsp文件夹: 全部复制;删除list.jsp(应在分类中显示)
=== 4.2 替换Action;
=== 4.3 ForumForm;
=== 4.4 ForumService/ForumServiceImpl;
=== 4.5 DAO/DAOImpl
=== 4.6 配置文件
=== 4.7 修改jsp页面;
=== 4.8 对分类的list.jsp,显示分类的每个版面;
=== 4.9 添加版面时,需要知道分类的id;
版面的form中增加categoryId;
add中获取分类;
版面的排序: set . order by
==小集合中的上下移动问题:修改getPrevious, getNext;
=== 4.10 级联删除;
删除分类必须删除里面的版面 setcasacade="delete" -----struts标签的超级链接也有FormBean[只要字段对应,就有]
=== 4.1.1 删除之前的提示,js实现:
returnwindow.confirm("您要删除...?");
=== 4.12 思考Action中使用Service?
如何将Service放在父类,Action中很多代码重复;
protected的使用;
Action层中这样使用,重构,
Service层也这样使用,重构;
BaseAction中使用的Service是直接定义了具体的实现类;
如何让实现类分离? ??使用工厂
下面的功能实现?
在Service用到的DAO;
在Web用到的Service; 都不要显示实现;
工厂的写法:
public class BeanFactory{
public staticfinal Map<String, Object> beans =null;
public staticObject getBean(String name);
returnbeans.get(name);
getBean("beanName");
}
=====Action中增加构造方法,里面初始化所有的Service;
=====Service中增加构造方法,里面初始化所有的DAO实现;
====== 它们对外全部使用接口;
==== 写配置文件,properties,classpath下
beans.properties
categoryDAO =cn.....
forumDAO =...
categoryService= ....
forumService=....
=====工厂中写静态代码块,读取配置文件,生成相应的实例,并放在Map中;
===== 工厂中写个main方法,可以测试使用;
===== 问题: Service要调用DAO
实例化的顺序需要注意,properties没有顺序;
解决方法:分为2个文件,先加载DAO后加载Service;
读取配置文件不再使用静态代码块,抽取成一个方法;
静态代码块中一个一个的加载
将工厂写成单例或将所有的方法写成静态的;
properties文件放在classpath下,查找这个文件时需要一个相对路径,直接放在classpath下就好。
====== 总结:将实现类与代码分离:
工厂 + 配置文件;