十分棘手的问题,郁闷

05-09-20 一剑封喉
jsp1.jsp跳转到一个Action中,然后forward到jsp2.jsp(此页面向ArrayList对象添加一个元素并显示)中
问题:当这时每刷新一次jsp2.jsp时,ArrayList中的元素就增加一个,郁闷ing,怎样才能让刷新jsp2.jsp时不增加ArrayList的对象?
或者在这个页面屏蔽刷新的代码怎么写?

谢谢了

banq
2005-09-20 21:52
刷新一次jsp2.jsp实际是刷新这个Action,这两个东东实际是我们以前的一个JSP(包含Java代码)。

调整你的"ArrayList对象添加一个元素"激活位置吧,可以爱jsp1.jsp处激活,利用request的scope来传递对象。

一剑封喉
2005-09-21 14:29
谢谢banp,你的意思是不是想个办法在Action之前把ArrayList元素添加进去。
如果这样的话,那就是要在jsp中添加了阿,这样好像行不通。
我还用session.setAttribute("","");这种方法试验了一下,也不行

banp大哥能不能给我一些简单的代码阿,或者更具体的思路阿?

谢谢了

cats_tiger
2005-09-21 22:36
这属于重复提交的问题,每次刷新都执行action。
我记得可以通过RequestToken...解决,作为线索你再查查。

cats_tiger
2005-09-21 22:41
想起来了

// 在此输入java代码
if (isTokenValid(request, true)) { 

   // your code here 

   return mapping.findForward("success"); 

  } else { 

   saveToken(request); 

   return mapping.findForward("submitagain"); 

  }  


<p class="indent">

一剑封喉
2005-09-23 13:49
有一个比较耗内存的方法:
在session中设置变量来控制请求是从哪来的(经测试,正确)。

楼上的朋友你说的那个方法还是比较好(不耗内存),但是:
1 你所说的RequestToken类是那个包下面的?
2 你的这段代码报错:Cannot resolve the method:isTokenValid(request, true))?
求助?

luowei
2005-09-28 17:58
朋友你的那种在SESSION放东东的方法和struts的令牌是一个思路!只不过一个是由自己编程实现,一个是由struts的api实现!
在转到你的提交页面之前,你要先在action创建一个令牌!转到提交页面之后你的<html:form>标记会生成一个包含令牌信息的隐藏域!――――
peng居然不知道struts有这样的功能!震惊!!!!!!!!!!!!!!!!!

banq
2005-09-28 21:39
我不是百科全书,也有不懂的地方,不过我还不明白这句话:
"转到提交页面之后你的标记会生成一个包含令牌信息的隐藏域"
能否详细解释一下?我也学习一下。

luowei
2005-09-29 10:08
关于struts重复提交的问题――令牌
进入页面

<html:link page="/tokentest.do">进入struts令牌测试</html:link>
<p class="indent">

进入页面对应的action

public class TokenAction
    extends Action {
  public ActionForward execute(ActionMapping actionMapping,
                               ActionForm actionForm,
                               HttpServletRequest servletRequest,
                               HttpServletResponse servletResponse) {
    //创建一个令牌把它放倒session中
    this.saveToken(servletRequest);
    return actionMapping.findForward("success") ;
  }
<p class="indent">

转到测试页面

<html:form action="addone.do">
  <html:text property="aa"/>
  <html:submit/>
</html:form>
<p class="indent">

对应action

  public ActionForward execute(ActionMapping actionMapping,
                               ActionForm actionForm,
                               HttpServletRequest servletRequest,
                               HttpServletResponse servletResponse) {
    AddActionForm addActionForm = (AddActionForm) actionForm;
    HttpSession session = servletRequest.getSession();
    if (session.getAttribute("aalist")==null){
      List list = new ArrayList();
      session.setAttribute("aalist",list);
    }
    List list = (List)session.getAttribute("aalist");
    if (isTokenValid(servletRequest, true)) { 
      list.add(addActionForm.getAa());
      System.out.println("正常提交!");
    }else {
      saveToken(servletRequest);
      System.out.println("重复提交!");
    }
    System.out.println("list中共有"+list.size()+"个元素!");
    return actionMapping.findForward("success");
  }
<p class="indent">

测试一下效果!就知道了!
请仔细看一下测试页面<html:form>生成的html代码

<form name="addActionForm" method="post" action="/struts/addone.do"><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="11b3309f8eac855c816cab6cccfd17f9">
<p class="indent">

有一隐藏域存储令牌信息!提交令牌要和session中的令牌作比较的!如果一致再作处理!

luowei
2005-09-29 10:10
我要用jsp直接打开word,而不是在保存/打开的对话框中选择打开!
代码如下:

<%@page import="java.util.*"%>
<%@page import="java.io.*"%>
<%@page import="java.net.*"%>
<html>
<head>
<title>
qq
</title>
</head>
<body bgcolor="ffffff">
<%
  response.setContentType("application/ms-word");
  BufferedInputStream bis = null;
  BufferedOutputStream bos = null;
  try {
    bis = new BufferedInputStream(new FileInputStream("D:\\myjava\\iptest\\WebModule1\\aaa.doc"));
    bos = new BufferedOutputStream(response.getOutputStream());
    byte[] buff = new byte[2048];
    int bytesRead;
    while ( -1 != (bytesRead = bis.read(buff, 0, buff.length))) {
      bos.write(buff, 0, bytesRead);
    }
  }
  catch (final IOException e) {
    System.out.println("出现IOException." + e);
  }
  finally {
    if (bis != null)
      bis.close();
    if (bos != null)
      bos.close();
  }

%>
</body>
</html>
<p class="indent">

不好意思,程序没出来!
但是仍然弹出保存/打开对话,折腾了半天还是搞不定!
请大家帮忙。谢谢!

luowei
2005-09-29 13:02
各位高手高手高搞手回答一下吧!

一剑封喉
2005-09-29 13:43
to:luowei
灵牌问题:你的意思我了解。
但是,在这种情况下:
jsp2.jsp显示ArrayList对象(每个对象后面有“drop”,用来删除),当用户点击“drop”后转到RemoveItemAction,然后又Forward到jsp2.jsp.

jsp2.jsp----->RemoveItemAction
| |
| |
<--------------

在这种情况下,令牌在那里定义?
1 当令牌在RemoveItemAction中定义时,刷新和点击“drop”一样。
2 当令牌在别的Action中定义时,只能删除一个element。

不过你说的方法在添加一个element时,很有效(因为令牌定义和判断令牌在两个Action中)。

luowei
2005-09-29 15:18
上面的Addaction修改,成为一个不断添加的页面,如下:

public class AddAction
    extends Action {
  public ActionForward execute(ActionMapping actionMapping,
                               ActionForm actionForm,
                               HttpServletRequest servletRequest,
                               HttpServletResponse servletResponse) {
    
    AddActionForm addActionForm = (AddActionForm) actionForm;
    HttpSession session = servletRequest.getSession();

    System.out.println(session.getAttribute(Globals.TRANSACTION_TOKEN_KEY ));
    if (session.getAttribute("aalist")==null){
      List list = new ArrayList();
      session.setAttribute("aalist",list);
    }
    List list = (List)session.getAttribute("aalist");
    if (isTokenValid(servletRequest, true)) {
      list.add(addActionForm.getAa());
      System.out.println("正常提交!");
    }else {
      System.out.println("重复提交!");
    }
//无论是否正常提交都创建新的灵牌
    saveToken(servletRequest);
    System.out.println("list中共有"+list.size()+"个元素!");
//仍然返回本页面
    return actionMapping.findForward("success");
  }
<p class="indent">

页面将根据新的灵牌产生新的隐藏域,提交将和新的灵牌匹配,而刷新由于执行的是上个action的内容(久的令牌)所以部匹配!
――――――

一剑封喉
2005-09-29 18:28
你的这个程序估计没有调试把
不管3721,统统都是重复提交阿

一剑封喉
2005-09-29 18:41
想了一下,在这种情况下(上述),我觉得程序中就不可能控制。除非有什么方法可以获得点击刷新和正常进入的底层编号。
刷新是从Action开始执行,然后到jsp页面
而正常进入也是从Action开始,然后再到jsp页面

看了许多文章,都是在两个Action中的例子(一个Action定义令牌,另一个判断)

看来只有一个方法了:把一个Action切成两个。