struts2修改数据,以及表单验证如何做到不冲突

小灰狼 2011-04-23 04:59:11
如果做一个 action 以及对应的jsp,要对一条信息进行修改,并且对数据中的表单域进行了非空验证,常见的做法是重点向到这个 action 配置好的 url,并且在 url 后带一个 id 参数,对应的 action 收到这个 id 后从数据库中取出数据,并且设置action 的相关信息,最后在 jsp 中展现

比如要对一个员工信息进行修改,则url可能会是
http://localhost:8080/myproject/edit-employee.action?empId=123456

对应的 action 类会有类似这样的代码:
public class EditEmployeeAction extends ActionSupport{
private int empId;
private String empName;
private Date empBirth;

//......

public String getEmpName(){
return this.empName;
}
@RequiredFieldValidator(message="姓名不能为空")
@RequiredStringValidator(message="请填写姓名")
public void setEmpName(String value){
this.empName = value;
}

// 省略其它属性和getter、setter方法

public String execute(){
try{
// 打开数据库
EmployeeDao dao = new EmployeeDao();
Employee emp = new dao.getById(this.empId);

if(this.empName == null){
// empName == null,说明此次访问是重定向过来,而不是通过表单提交的
this.empName = emp.getName();
this.empBirth = emp.getBirth();
// ......
}else{
emp.setName(this.empName);
emp.setBirth(this.empBirth);
//......
dao.update(emp);
}
}catch(Throwable ex){
// 异常处理代码
}finally{
// 关闭数据库
}
}
}


但是,如果我在这个 Action 中对 empName 属性设置了 RequiredFieldValidator,则 struts2 的缺省拦截器会在调用 execute 方法之前检测这个属性值是否为空,如果为空就直接返回"input",而不再高用 execute() 方法,从而导致 action 没有从数据库中读入这个员工的个字段信息,最后用户在编辑界面看到的是一片空白

请教各位,是如何处理的?
...全文
225 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
小灰狼 2011-04-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 redlotus_lyn 的回复:]
业务Action实现Preparable接口。

把Employee emp = new dao.getById(this.empId);

方法prepare()方法中。

prepare()页面校验失败时,也执行。
[/Quote]


不过你倒是提醒了我,可以这样做:
1、给 struts 自定义一个接口:
public interface BeforeValidateInterface{
public void doBefore();
}

2、定义一个拦截器:
public class BeforeValidationInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Action action = (Action) invocation.getAction();
if(action instanceof BeforeValidation){
try{
((BeforeValidation)action).beforeValidation();
}catch(Throwable ex){
ex.printStackTrace();
}
}
return invocation.invoke();
}

}

3、在 struts.xml 中定义一个 package,并且重新定义这个 package 的拦截器栈,其实就是把 struts-default.xml 中默认的拦截器栈复制过来,并且在 validation 拦截器之前插入我自定义的拦截器
以后所有的 package 都将继承这个 package

4、如果需要我的功能,可以在 Action 中实现 BeforeValidation 接口,并且在接口的实现方法中进行初始化工作
小灰狼 2011-04-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 redlotus_lyn 的回复:]
业务Action实现Preparable接口。

把Employee emp = new dao.getById(this.empId);

方法prepare()方法中。

prepare()页面校验失败时,也执行。
[/Quote]

这样好象不行

Action 实现 Preparable 接口之后,struts2 先调用了 prepare 方法,然后再调用各个 setter 方法
这样一来,在 prepare 方法调用时,Action 还没有得到 empId
redlotus_lyn 2011-04-26
  • 打赏
  • 举报
回复
业务Action实现Preparable接口。

把Employee emp = new dao.getById(this.empId);

方法prepare()方法中。

prepare()页面校验失败时,也执行。
小灰狼 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhangao0086 的回复:]
就是说empId是不可能空的,但是empName可能为空,但是可以修改?你是想用户在编辑完后empName不能为空?这样的话,你就不要让Struts给你校验了,你自己校验,把你的if(this.empName == null)改成:

Java code
if(ServletActionContext.getRequest().getMethod().equalsIgnoreCase("GE……
[/Quote]

不知道是你否明白我的意思

就是链接跳过去的时候,action 可以接收到参数 empId,但是这个时候肯定是没有员工的姓名、性别、地址等信息的,这些信息是action根据传入的 empId 从数据库中取出来,然后提供给 jsp 进行展示的

但是如果给 empName, empBirth, empAddress 等 加上验证之后,拦截器会在调用 execute 之前进行表单域验证,当判断为空时,验证失败,而不再调用 execute 方法


你说的不用验证器进行验证,这个办法我可以做到,但是这就丧失了struts2的优点,我希望有一个办法即可以用 struts2 提供的验证器,又可以解决我的问题
留下买路财 2011-04-24
  • 打赏
  • 举报
回复
LZ可以在struts.xml中设置<result name="input" >姓名所在的页面</result>让它转到员工信息页面,并提示姓名不能为空,让用户进行填写再提交,这样就行了
Bannings 2011-04-23
  • 打赏
  • 举报
回复
就是说empId是不可能空的,但是empName可能为空,但是可以修改?你是想用户在编辑完后empName不能为空?这样的话,你就不要让Struts给你校验了,你自己校验,把你的if(this.empName == null)改成:
if(ServletActionContext.getRequest().getMethod().equalsIgnoreCase("GET"))


如果是GET方式提交的,就说明是要到修改页面,如果是表单提交,struts2默认是POST方式.

81,090

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧