请教个struts2 验证跳转的问题

niuzk0411 2009-10-08 04:35:57
问题是这样的,我这个也是刚刚发现这个问题
譬如我有个页面是addNews.jsp 新闻添加页面,有新闻标题、分类、新闻内容等信息。然后分类在action里面查询出来
在addNews.jsp页面里直接引入这个<s:action 这个标签来显示action处理的新闻分类
校验失败的时候在addNews.jsp给予提示
struts2配置文件如下:
<action name="saveOrUpdate" class="saveOrUpdate">
<result name="input">addNews.jsp</result>
<result>addNews.jsp</result>
</action>
但校验失败action跳转到addNews.jsp页面的时候 新闻分类就出不来了,就是说<s:action>这个引入action的标签就不执行了

问题不知道该怎么解决了,望高手给予解决下,分不够再加
...全文
1409 点赞 收藏 57
写回复
57 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
yugongsong 2011-10-21
kanakn
回复
zhpt1985 2009-12-24
<action name="saveOrUpdate" class="saveOrUpdate">
<result name="input">addNews.jsp </result>
<result name = "error">错误页.jsp </result>
<result name = "success">成功页.jsp </result>
</action>
action中成功就return SUCCESS;
错误就return ERROR;
回复
niuzk0411 2009-11-14
嗯,好的方式还是没有,不过还是感谢yjailj热心回复,暂时用你说到这个方案,不过不是最好的解决方案
散分
回复
yjailj 2009-11-13
拿你上面的代码说明吧:

我并没有要求你在 saveOrUpdate.action 请求处理 Action 中添加 validate 方法.

addNews.jsp 有这么一个 <s:action name="slectNewsClass" /> 标签
此标签执行了 slectNewsClass.action 中的方法

我要求的只是你去为 slectNewsClass.action 请求添加 validate 方法.和 savaOrUpdate 请求没有任何关系

你的 saveOrUpdate 请求 input 回 addNews.jsp 后, <s:action name="slectNewsClass" /> 这个标签还是会执行的,只是这个请求的 validate 方法执行完后,发现有错就不再往下执行了

所以你需要做的也只是添加 validateSelectNewsClass 而已!!!

不和任何包含它的页面有任何的关系,管它什么 addNews.jsp, delNews.jsp 等等等等.

它就是它自己,可以独立存在.不需要任何引用它的页面来填充数据,靠自己的 validate 方法


是我表达能力有问题还是怎样 ?


最后说一句: LZ 校验用的是配置文件,我再就什么也不说了.很烦配置文件. 看到一堆的 xml 就头疼
只有 struts 2 还在用配置是因为它的注解完全是代码污染, 用配置能使用通配符还更简洁方便些.
我现在的项目一般: spring 一个 xml, hibernate 一个 xml, sitemesh 一个 xml, jdbc 一个 properties, log4j 一个 properties, email 一个 properties. struts 2 分模块使用配置文件.每个人管好自己模块的 struts 配置.其他一个也不要多. 要知道,读取 配置文件的时候,有一个过程叫 解析
回复
yjailj 2009-11-13
以前确实是没用过 s:action 标签.之前确实也是没注意看过.今天特意看了下那个图

失策啊.

刚刚把 s:action 大致看了一下.. 细想下来,我之前说的还是对的

举个例子:

访问 index.action 不进行任何处理直接跳到 /WEB-INF/demo/index.jsp .
此页面有一个 <s:action name="demo" id="de" executeResult="false" />
看了下 LZ 上面的代码,看来只是想执行 action 里面的方法.所以没有 id

demo.action 的主要目的就是填充 下拉框等等之类公共的数据
<action name="demo" class="com.web.DemoAction" method="demo">
<result>/WEB-INF/jsps/demo.jsp</result>
</action>

DeomAction :
public String demo() {
// 填充数据
list = login.getAll();
}


/WEB-INF/demo/index.jsp 页面还没完.此页面有一个 表单
<s:fielderror><s:param>show</s:param></s:fielderror>
<form action="show">
<input type="submit" value=" 提 交 " />
</form>


<action name="show" class="com.web.DemoAction" method="show">
<result>/WEB-INF/demo/.....jsp</result>
<result name="input">/WEB-INF/demo/index.jsp</result>
</action>

Action:
public String show() {
// 做相关处理....
return "success";
}
public void validateShow() {
addFieldError("show", "故意弄了一个错误");
}


如果执行的话,当回到原 /WEB-INF/demo/index.jsp 页面时,
此页面的 <s:action name="demo" ... /> 将不再执行.

究其原因.我仔细看了下.还是 input 跳转传值的问题. 进入 s:action 标签中指定的请求前,
后台默认的跳转形式为了保留值.可能用的是 chain 的形式进行的中转.
具体是不是我不敢保证.要去看标签库原码才能肯定
如果是这样的话, s:aciton 中的请求其实还是访问到了的,
只是有了 fielderror 或 actionerror 错误,执行不到 demo 方法了而已.

解决的办法也很简单,添加 validate + Demo 方法(驼峰命名规则), demo 方法不再执行逻辑操作:
public String validateDemo() {
// 在 validate 处来填充数据,原先的 demo 方法中填充数据的去掉
list = login.getAll();
}


还是在公司闲一点,要不还真没时间来特意看这个问题...
回复
niuzk0411 2009-11-13
[Quote=引用 52 楼 yjailj 的回复:]
LZ 误以为 validateDemo() 这个方法只是为某一个请求专门设立的.它是 webwork 框架自动会调用的

哎,悲剧啊...

正如大多数人只知道 完成逻辑代码 跟 实现功能, 却忽略了更为重要的 校验 和 测试 一样

多数的流程都是按他了解的流程来执行,一旦改变流程或 输入有问题.结果全变了.

哎,这就是现在的中国呀
[/Quote]
呵呵,(LZ以为 validateDemo() 这个方法只是为某一个请求专门设立的)这个流程我还是熟悉的,webwork的工作机制也清楚
还是谢谢你的热心回复~~~
还是针对我现在这个问题来说,(引用:页面的那些下拉框为什么没有值,就是因为 fielderror 或 actionerror 中有了值,没有进 method 方法)这个也是对的
具体我是把我的公共视图填充写到一个action里 然后在struts.xml里配置,类似你写的在一个action写多个方法 在struts.xml里用method配置action 然后在添加新闻jsp页面<s:action 引入这个公共视图的这个action,提交saveOrUpdate这个action校验失败后跳转到这个addNews.jsp页面
你说的意思我也明白就是将公共显示的下拉列表读出放到public void validateSaveOrUpdate(){……}这个方法里面,不是重复代码吗?
解决方式是有的,可好的解决方案到现在没有想出来
我后台校验是写在了xml文件里面,具体校验失败还是返回input视图




回复
yjailj 2009-11-13
LZ 误以为 validateDemo() 这个方法只是为某一个请求专门设立的.它是 webwork 框架自动会调用的

哎,悲剧啊...

正如大多数人只知道 完成逻辑代码 跟 实现功能, 却忽略了更为重要的 校验 和 测试 一样

多数的流程都是按他了解的流程来执行,一旦改变流程或 输入有问题.结果全变了.

哎,这就是现在的中国呀
回复
yjailj 2009-11-13
哎, 我把 struts2 (还不如说 webwork) 的流程说一下吧:

用户提交表单, struts.xml 配置 method 执行顺序为:
validateMethod (此为 Java 反射实现) -->
validate (此 action 类中的所有请求都会执行此方法,为了类的重用,最好不要重写这个方法)

说明 : 在执行 validateMethod 前,会先进行类型转换,若转换出错,会在 filederror 中添加一条数据.
执行完 validate 之后,会检查 fielderror 或 actionerror 中是否有值
若有,则跳至 配置文件中的 input 视图不再向下执行

若未发现 fielderror 或 actionerror , 则进入 method 方法进行逻辑处理.
(没有配置 method 则进入 execute 方法)
此方法返回一个字符串. 通过返回的 字符串在 配置文件中找到相应的 视图进行跳转

这么讲了,你是不是能够明白一些了 ?

页面的那些下拉框为什么没有值,就是因为 fielderror 或 actionerror 中有了值,没有进 method 方法

所以,只需要把 要在页面显示的公共数据,下拉框等等放在 validateMethod 这里进行赋值,其他的流程不变.

当有错误时,页面还是能够获取到下拉框的值等等.

我上面的 list= login.getAll(); 只是一个例子, list 里面就是一个下拉框的值
回复
niuzk0411 2009-11-13
[Quote=引用 48 楼 yjailj 的回复:]
晕了.这怎么会有很多重复代码了呢 ?


现在才发现我上面的例子写错了一个地方 ,validateDemo 这个方法不需要返回值, String 改成 void

你只要改 <s:action name="demo" /> 这个 action 的一个地方就可以了.

就像我上面说的,你在public void validateDemo() 方法(没有返回值, 请改成 void ,要不我就误人子弟了)这里写了填充 list 的数据,在 demo() 里面就不需要再给 list 赋值

如果 demo.action 这个请求仅仅只为了加载下拉框的数据,你甚至可以把public String demo() 方法删除
只留 validateDemo() 方法就可以了.

这会出现很多重复代码吗 ?

看来 LZ 没把 struts 2 的流程完全弄明白

[/Quote]
首先感谢yjailj你的热心回复!

你不觉的这样做的话是不是每个需要引用demo的地方 都需要给action的
public void validate(){//视图填充业务逻辑}
这个方法加入你代码中所谓的list= login.getAll(); (ps:填充视图的列表)这个不是重复代码,况且我的填充视图的业务逻辑代码也没有这么简单的一句代码list= login.getAll()吧
回复
yjailj 2009-11-13
严重声明: 45 楼 Java code 有错误

!!! validate 方法不需要设置返回类型 !!!



// 此处不需要返回任何东西. void 即可
public void /* String 是错的 */ validateDemo() {
// 在 validate 处来填充数据,原先的 demo 方法中填充数据的去掉
list = login.getAll();
}
回复
yjailj 2009-11-13
晕了.这怎么会有很多重复代码了呢 ?


现在才发现我上面的例子写错了一个地方 ,validateDemo 这个方法不需要返回值, String 改成 void


你只要改 <s:action name="demo" /> 这个 action 的一个地方就可以了.

就像我上面说的,你在public void validateDemo() 方法(没有返回值, 请改成 void ,要不我就误人子弟了)这里写了填充 list 的数据,在 demo() 里面就不需要再给 list 赋值

如果 demo.action 这个请求仅仅只为了加载下拉框的数据,你甚至可以把public String demo() 方法删除
只留 validateDemo() 方法就可以了.

这会出现很多重复代码吗 ?

看来 LZ 没把 struts 2 的流程完全弄明白
回复
gjsong 2009-11-13
<result name="input">addNews.jsp </result>

struts2校验失败不一定要返回Input视图的
你可以手动return一个字符串和你action里面的result里配置的name一致
它就返回到你自己定义的那个页面去了吧
回复
niuzk0411 2009-11-13
[Quote=引用 45 楼 yjailj 的回复:]
以前确实是没用过 s:action 标签.之前确实也是没注意看过.今天特意看了下那个图

失策啊.

刚刚把 s:action 大致看了一下.. 细想下来,我之前说的还是对的

举个例子:

访问 index.action 不进行任何处理直接跳到 /WEB-INF/demo/index.jsp .
此页面有一个 <s:action name="demo" id="de" executeResult="false" />
看了下 LZ 上面的代码,看来只是想执行 action 里面的方法.所以没有 id

demo.action 的主要目的就是填充 下拉框等等之类公共的数据
XML code<actionname="demo" class="com.web.DemoAction" method="demo"><result>/WEB-INF/jsps/demo.jsp</result></action>
DeomAction :
Java codepublic String demo() {// 填充数据 list= login.getAll();
}

/WEB-INF/demo/index.jsp 页面还没完.此页面有一个 表单
HTML code<s:fielderror><s:param>show</s:param></s:fielderror><formaction="show"><inputtype="submit" value=" 提 交 "/></form>

XML code<actionname="show" class="com.web.DemoAction" method="show"><result>/WEB-INF/demo/.....jsp</result><resultname="input">/WEB-INF/demo/index.jsp</result></action>
Action:
Java codepublic String show() {// 做相关处理....return"success";
}publicvoid validateShow() {
addFieldError("show","故意弄了一个错误");
}

如果执行的话,当回到原 /WEB-INF/demo/index.jsp 页面时,
此页面的 <s:action name="demo" ... /> 将不再执行.

究其原因.我仔细看了下.还是 input 跳转传值的问题. 进入 s:action 标签中指定的请求前,
后台默认的跳转形式为了保留值.可能用的是 chain 的形式进行的中转.
具体是不是我不敢保证.要去看标签库原码才能肯定
如果是这样的话, s:aciton 中的请求其实还是访问到了的,
只是有了 fielderror 或 actionerror 错误,执行不到 demo 方法了而已.

解决的办法也很简单,添加 validate + Demo 方法(驼峰命名规则), demo 方法不再执行逻辑操作:
Java codepublic String validateDemo() {// 在 validate 处来填充数据,原先的 demo 方法中填充数据的去掉 list= login.getAll();
}

还是在公司闲一点,要不还真没时间来特意看这个问题...
[/Quote]
感谢yjailj 你的回复,这种方式是可以的,但这样会出现很多重复代码,毕竟很多地方需要调用这个。。我试过若是不返回input视图即可,但struts2校验框架校验失败后默认会返回input视图,请问有没有好的解决方案?
回复
哈哈.楼主强人呀.
给个解决办法:
action里添加一个方法searchList返回一个LIST或你调用类属性里的方法也一样
在JSP里这样写
<select name=xxx >
<s:iterator value="%{searchList()}">
<option value="${id}">${name}</option>
</s:iterator>
</select>
JSP可以直接调用ACTION里的方法和属性的
回复
J2EE_DOTNET_SU 2009-11-12
不明白

顶顶……
回复
niuzk0411 2009-11-12
[Quote=引用 35 楼 yjailj 的回复:]
把你想在页面显示的数据放在  validate()方法  去赋值.

都去 把 struts 2 规范补一补再来回答问题,好吧 ?

一个个都在那里想当然

警告 LZ ,使用了 struts 2 ,不到不得已, 不要在 Action 中操作 ServletActionContext .request.session 等

struts 2 采用的是 值栈的存储形式,即 后进先出,在 Action 赋值即可在页面取
且使用了 struts 2 就可以把 jstl 那一套给抛弃了,页面上要取值,尽量用  <s:property value="" />

有时候 sun 的规范也不是那么好. thinking in java 中 泛型也有提到. opensymphony 在这方面做得好多了
[/Quote]
谢谢你的建议,不过我现在的问题不知道你明白不?
回复
fhm727 2009-11-12
你的问题我也遇到了,没有直接解决而是换了个思路
思路一:
在jsp里直接获取数据
思路二:
自己在action里加验证,验证通不过时从数据库里获取数据

建议楼主放弃action标签,我以前的项目中用过,后来出问题了
回复
niuzk0411 2009-11-12

http://dl.javaeye.com/upload/picture/pic/49403/537fa52b-fdc0-3dcd-9f6d-077e70e8549b.jpg
回复
niuzk0411 2009-11-12
[Quote=引用 39 楼 sunyy007 的回复:]
 
struts:
  <action name="saveOrUpdate" class="mycrmCustomerFromAction" method="list">
          <result name="success">/WEB-INF/pages/addNews.jsp </result>
          <result name="error">/WEB-INF/pages/mainMenu.jsp </result>
  </action>

如果跳转页面需要引用方法,扩展名就是.html,如果不是就写.jsp


action:
    验证结果,看写方法,验证成功就是 return SUCCESS;    验证不符合要求就是error


页面很简单,你自己看吧


[/Quote]
把图给贴出来应该比较好理解,大家都应该不太明白我的意思

回复
niuzk0411 2009-11-12
[Quote=引用 38 楼 sidengc 的回复:]
哈哈.楼主强人呀.
给个解决办法:
action里添加一个方法searchList返回一个LIST或你调用类属性里的方法也一样
在JSP里这样写
<select name=xxx >
<s:iterator value="%{searchList()}">
<option value="${id}">${name} </option>
</s:iterator>
</select>
JSP可以直接调用ACTION里的方法和属性的

[/Quote]
sidengc
你这种方法是可以的,我也明白你的意思,具体不可能说我在所有的action里面都写这个方法吧,毕竟新闻分类可能在多处用到
我在页面直接调用<s:action这个标签来引用通用的新闻分类业务逻辑
晕。csdn不能贴图,很是郁闷!
回复
加载更多回复
相关推荐
发帖
Java EE
创建于2007-09-28

6.6w+

社区成员

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
申请成为版主
帖子事件
创建了帖子
2009-10-08 04:35
社区公告
暂无公告