1.很多人在struts都有防止重复提交的方法
在google里搜 struts 防止重复提交  
2.可能你先把内容提交给了一个action处理过,而处理过可能超过了一个request的范围;
建议先用session试试,再考虑解决方案

解决方案 »

  1.   

    <bean:write name="user" propery="firstname" />
    希望这不是你的原文:property!
      

  2.   

    第一个问题可以参考:
    http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=12998
    文中提到的第3个解决方案便是。第二个问题我觉得你走进了一个误区,也就是说,不该用这种方式来实现你的目的:
    “通不过Bean的validate方法又返回到这个页面提示内容不能为空”你想想Struts的处理流程:1。JSP页面上表单提交,发送请求到ActionServlet
    2。ActionServlet用JSP提交的表单数据填充ActionForm
    3。ActionServlet将请求发送给Action
    4。Action获取ActionFrom的数据进行下一步处理
    5。省略按照你的想法,ActionForm的validate()方法实际上在第2步就执行了,但是Action中
    request.setAttribute("user",user);是在第5步以后才执行,那么此时从validate()返回原来的页面,肯定不存在user实例了。你想想是不是这个道理?建议你对Struts还是了解的深入一点好。
      

  3.   

    关于第二个问题的解决方案,我建议你采用Struts Validator框架。
      

  4.   

    你的第一个问题产生的根本原因:
    你在struts-config中addComment这个action的forward肯定设为redirect="false"或是没有设置(没有设默认为redirect="false")。所以你的当前页面还是停留在这个addComment上,每刷新一次又执行一次提交,所以重复插如值,解决的办法是让redirect="true"或是按楼上有人说的方法防止重复提交!至于第二个问题,我觉得不应该出现问题,你查看下你action的scope是否是request!
      

  5.   

    非常感谢大家的帮忙,重复提交的问题已经解决了。但是现在我有个新的疑惑。
    比如我的页面由三部分组成,header,leftmenu,和main
    (以csdn的默认BLOG那种样子为例,main部分里列出了文章的标题)其中header的内容由<bean:write name="header" property="..."/>显示
    leftmenu部分的内容由<bean:write name="leftmenu" property="..."/>显示
    main部分的内容由<bean:write name="main" property="..."/>显示
    我都是通过
    request.setAttribute("header", header);
    request.setAttribute("leftmenu", leftmenu);
    request.setAttribute("main", main);
    的方式把内容写进去的。现在我仅仅要改变页面中main部分的内容,(比如一个点击查看某篇文章ViewArticleAction),这时我不得不就要在ViewArticleAction里疲于奔命的又去数据库里把leftmenu,header里的内容又查出来一次,然后
    request.setAttribute("header", header);
    request.setAttribute("leftmenu", leftmenu);
    要不然肯定会出现Cannot find bean header in any scope的错误
    我总觉得有点不对劲,但是又不知道更好的办法,我总不能把什么东西都放在session里吧??
      

  6.   

    TO pcdll(.net):我在Action里设置了scope="request"的
      

  7.   

    你刚提的那个问题有一个很好的办法解决,就是你要用到header,leftmenu,和main的action,让他们共同继承一个类,该类继承Action,申明一个abstract方法,该方法就是要在你的各action中实现的方法(替换掉你的action中的execute)在其中的execute方法中分别获得header,leftmenu,然后调用并返回你的那个abstract方法即可!
      

  8.   

    我现在是这样做的:(大家可以对照自己CSDN的BLOG)
    访问首页时,我是
    getHeader.do--->getLeftmenu.do--->getMain.do 的方法显示出来。
    点某篇文章查看时,我是
    ViewArticle.do--->getHeader.do--->getLeftmenu.do 但是实际操作中有很多麻烦。
    现在我访问首页的时候是在浏览器里这样输:
    http://127.0.0.1:8080/blog/header.do?username=swiminthesea
    然后在getHeader.do里通过String username=request.getParameter("username");
    得到username,然后在数据库查出和这个user相关的信息。
    当现在我要点击查看某篇文章,这时进入ViewArticle.do的以后,我不得不先去查出这篇文章的作者,然后request.setAttribute("username", username);
    这时再在getHeader.do里来一句username=(String)request.getAttribute("username");获取这个user的相关信息,才能顺利的执行下去。要不然又会出现
    Cannot find bean header in any scope错误的
    大家明白我的意思了么?我是不是有什么地方没弄对?有这么麻烦吗?
      

  9.   

    大概明白你的意思,这样最好不判断参数作为form里的一个属性。
      

  10.   

    To wingtrace:关于第二个问题,我的request.setAttribute("user",user);是读取这个表单页面的时候就已经执行的。
    这样说吧,
    现在我的页面是这个样子的。
    <bean:write name="user",proterty="firstname"/>
    <bean:write name="user",proterty="lastname"/>
    <html:form.........>
    ..........
    ..........
    ..........
    </html:form>
    提交现在通不过validate()方法又返回到这个页面时,就说Cannot find bean user in any scope,就是说我上次在<bean:write name="user",proterty="firstname"/>
    ,<bean:write name="user",proterty="lastname"/>写的东西已经没有了。
      

  11.   

    难道通不过验证,我就要自己在返回页面之前来一句request.setAttribute("user",user);才能正常嘛??
      

  12.   

    request.setAttribute("user",user)的生命周期就是一次request。如果通不过validate,可以在validate方法里面产生一个ActionErrors以及相关的ActionError,然后返回到输入页面,在输入页面里输出ActionErrors通知用户出现了什么错误,应该如何改正之类的信息。在ActionServlet调用Action类前,它会调用validate(),如果返回的ActionErrors不是null,则ActinForm会根据错误关键字将ActionErrors存储在请求属性列表中。如果返回的不是null,而且长度大于0,则根据错误关键字将实例存储在请求的属性列表中,然后ActionServlet将响应转发到配置文件<action>元素的input属性所指向的目标。知道Struts的处理流程之后你才能设计一个合理的基于Struts的webapp。
      

  13.   

    “如果通不过validate,可以在validate方法里面产生一个ActionErrors以及相关的ActionError,然后返回到输入页面,在输入页面里输出ActionErrors通知用户出现了什么错误,应该如何改正之类的信息。”我也想这样啊。关键是,<bean:write name="user",proterty="....."/>里的东西已经没有了耶,返回到这个页面就出错了。我接触struts没多久,也没时间仔细看书,所以只好摸着石头过河。
      

  14.   

    TO wingtrace:http://community.csdn.net/Expert/topic/3235/3235523.xml?temp=.8205683还记得吧?
    现在我做了一半了,觉得很失败 ,功能没多少,倒是已经写了28个类+10多个jsp页面,现在有股强烈的挫折感
      

  15.   

    呃,数据库怎么办?
    MYSQL的数据库拷过来可以直接用么?
      

  16.   

    “关键是,<bean:write name="user",proterty="....."/>里的东西已经没有了”
    -----------------------------------------你的想法是这样吗?:如果校验后发现用户提交的信息有误,就返回输入页面,但是用户原来提交的东西需要保留,返回给用户作进一步修改。如果是这样的话,确实可以把user保存到session里,只是这样比较麻烦,我以前做Struts项目的时候似乎并没有作特别的处理,只是利用浏览器的缓存功能,按一下回退键,回到原来的页面,用户输入的信息还是被保留的。
      

  17.   

    数据库可以使用MySQL-Front工具导出SQL脚本给我,如果没有现成的就先搁下吧,我看看代码先。
      

  18.   

    正在发送,数据库脚本也也在里面。
    代码写得很乱,而且大量剽窃csdn的BLOG的界面,不好意思了,麻烦你了。
      

  19.   

    呃,把struts-config.xml里的
    <action
                attribute="commentForm"
                input="/user/article.jsp"
                name="commentForm"
                path="/addComment"
                type="com.blog.struts.action.AddCommentAction"
                scope="request"
                validate="false">
                <forward name="success" path="/getContent.do" />
                <forward name="error" path="/getContent.do" />
                <forward name="submitagain" path="/getContent.do"/>
            </action>的validate="false"改成true就会出问题
      

  20.   

    郁闷了,刚才不小心在Eclipse的workspace下把我的BLOG文件夹移动了一下,现在eclipse就没办法重新打开它了。我import了一下,又出错了,5555555555
      

  21.   

    早上运行了一下你的工程,首先就是以下错误:
    -----------------------------------------
    2004-8-28 9:59:16 org.apache.commons.digester.Digester error
    严重: Parse Error at line 171 column 61: Attribute "redirect" must be declared f
    or element type "action".
    org.xml.sax.SAXParseException: Attribute "redirect" must be declared for element
     type "action".
    -----------------------------------------
    当然这不严重,可以改正。然后是根本无法进入文章浏览页面,一点“文章”包括其它许多连接,就跑到csdn的blog上去了。尝试直接进入其它的jsp页面,得到的都是“找不到bean”的错误。这个错误是不应该的。其它的我看看代码再说吧。
      

  22.   

    在JSP里使用一个bean或其它的对象之前,应该用<logic:present>或者<logic:notPresent>标签先作判断,然后再进行其它的操作。否则,用户得到的将是一堆对他们来说莫名其妙的东西。这一类经验性的东西Struts的开发包提供了许多的实例,可供参考。
      

  23.   

    目前发现的一些问题及建议:1。从降低层间耦合的角度出发,Action里面不应该执行任何sql操作,应该把sql操作封装到DAO层至少是业务逻辑层,也就是说,Action里面不应该包含业务逻辑,更不应该包含数据访问。2。在JSP里使用一个bean或其它的对象之前,应该用<logic:present>或者<logic:notPresent>标签先作判断,然后再进行其它的操作。否则,用户得到的将是一堆对他们来说莫名其妙的东西。还有页面上另外一些标签的使用也不甚合理,最好参照Struts的标签库手册来使用Struts标签。3。你设置的字符集编码过滤器实际上并未起作用,解决字符集编码问题包含三个方面,一是数据库字符集编码,二是Java内部字符集编码,三是页面显示字符集编码。相关的经验总结性文章网上很多,自己搜索一下就可以找到。4。数据库设计方面,感觉存在一些不甚合理的地方,无法一一指出,建议你多多参考其它类似项目的数据库设计。另外,在你目前的项目中似乎缺少了权限管理这一模块。5。我没有在你的项目中找到完整的错误校验功能,每一个表单提交的数据都要经过客户端和服务端的各层面校验之后才允许进入数据库,这个功能是不可缺或的,似乎我建议过你用Struts Validator框架来解决数据校验问题,当然不用Struts Validator也可以,解决方案是很多的。6。从整个项目总的设计来看,感觉对MVC设计模式的理解和把握不到位,对Struts的理论和实践不熟悉。具体的代码修改是很容易的,但是一个项目的结构性缺陷往往是无可救药的,建议趁早重构,呵呵。。同时也参考一下大家的意见吧。暂时就想到这么多,呵呵。。
      

  24.   

    TO wingtrace:“你的想法是这样吗?:如果校验后发现用户提交的信息有误,就返回输入页面,但是用户原来提交的东西需要保留,返回给用户作进一步修改”不是这个意思。
    比如页面是这样的:
    <bean:write name="user",proterty="firstname"/> ----->这是页面上其他地方的内容,
    <bean:write name="user",proterty="lastname"/>        并不属于下面那个表单<html:form.........>
    ..........
    ..........
    ..........
    </html:form>
    <bean:write name="user",proterty="....."/>
    是我在读取这个页面时就request.setAttribute("user",user)进去了。所以第一次进入这个页面时是正常的,但是当我提交表单出错以后,返回这个页面,就出现找不到Bean user的错误。
      

  25.   

    当然这不严重,可以改正。然后是根本无法进入文章浏览页面,一点“文章”包括其它许多连接,就跑到csdn的blog上去了。尝试直接进入其它的jsp页面,得到的都是“找不到bean”的错误。这个错误是不应该的。其它的我看看代码再说吧。-------------------------------------------------------------------------呃~不好意思,文章管理这部分我还没有开始做,所以上面的链接都还指着csdn的BLOG。
    管理部分我只做了链接管理,选项管理,还有评论管理。
    “提示找不到Bean”?
    在我机器上登录进去都是正常的啊
      

  26.   

    谢谢你的建议,下次用struts做webapps我会好好规划的。
    1 我也看过一本书上建议Action里面不应该包含业务逻辑,最开始做的时候我也考虑过封装,采用hibernate,但是为了图快(毕竟是要交作业),而且学习DAO,Hibernate都需要时间。加上没有好的例子参考,所以我顾不得那么多了。3 我觉得我的过滤器有作用啊。以前我提交表单出错,返回页面的时候页面上的中文就变成了问号,虽然在我页面上有
    <%@ page language="java"  contentType="text/html;charset=GB2312"%>(我觉得struts提交表单出错返回页面总会出这样那样的问题)但是加了过滤器就没事了。不过我确实搞不清那么多编码,你看我程序里面编码转过去转过来,是要好好去查查资料。
    4 呃,数据库设计方面,确实很粗糙。开始的时候表还多一点,但是做的时候为了程序里方便,我把有的表合并,有的字段删除,又加些字段,所以现在面目全非5 这个我也意识到了。下次做webapps时我会一开始就考虑进去。6 我有同感。现在改动一个地方很困难,很多时候我都不知道*.do到哪里去了。类越写越多,而感觉却是大量的重复代码。我觉得我用struts是把显示和模型分离了,但是显示和模型里都写得非常混乱。这次就当吸取经验了。
    再次感谢你的建议。
      

  27.   


    在第一次表单提交页面,你看一下浏览器的地址栏是什么。是某某JSP对吧。提交数据,重返这个页面以后,你再看一下浏览器的地址栏是什么?应该是某某.do。也就是这时地址指向的是提交表单的Action。你的Action用的不是redirect(重定向),而是forward,这导致浏览器的地址栏是不会刷新的,它会停留在最后一次请求的地址上。所以如果你点击浏览器的刷新,就等于直接向action再一次提交数据,而不是刷新表单JSP。所以,解决方案就是把“重返提交页面”的那个forward的定义在struts-config.xml中改成redirect。
      

  28.   

    to alienbat(亡灵法师):他原本确实是用redirect的,我看了他的原文件片断如下,
            <action
                attribute="linkCategoryForm"
                input="/pages/manager/EditCategory.jsp"
                name="linkCategoryForm"
                path="/addCategory"
                redirect="true"
                type="com.blog.struts.action.AddCategoryAction">
                <forward name="success" path="/getLinkCategory.do?action=category" />
                <forward name="error" path="/pages/manager/EditCategory.jsp" />
                <forward name="login" path="/login.jsp" />
            </action>但是tomcat在加载应用的时候解析到redirect="true"一句的时候报错如下,2004-8-29 0:06:04 org.apache.commons.digester.Digester error
    严重: Parse Error at line 171 column 61: Attribute "redirect" must be declared f
    or element type "action".
    org.xml.sax.SAXParseException: Attribute "redirect" must be declared for element
     type "action".----------------------------------------我只是帮他删除了redirect="true"一句而未作深究。
      

  29.   

    redirect应该定义在forword元素内的。楼主应该把返回注册页的那个forword增加redirect定义。
      

  30.   

    呃,我这样写的,不知道对不对
    <forward name="success" redirect="true" path="/getContent.do" />这样以后结果是,我提交表单以后什么也没插入,直接返回到输入页面了
      

  31.   

    其实这个问题可以不管了,因为我加了令牌,现在没有问题了。现在头痛的是这个问题:
    比如页面是这样的:
    <bean:write name="user",proterty="firstname"/> ----->这是页面上其他地方的内容,
    <bean:write name="user",proterty="lastname"/>        并不属于下面那个表单<html:form.........>
    ..........
    ..........
    ..........
    </html:form>
    <bean:write name="user",proterty="....."/>
    是我在读取这个页面时就request.setAttribute("user",user)进去了。所以第一次进入这个页面时是正常的,但是当我提交表单出错以后,返回这个页面,就出现找不到Bean user的错误。
    -------------------------------------------------------------
    实在不行我想直接加入java script判断好了。就不用提交到ActionServlet那里去了
      

  32.   

    好了,上面那个问题也解决了,我直接用java script在页面里就判断了,多谢大家了。