2

我在 jsp 中使用jspservlet,方法类型为 POST 。但是在插入记录后再次刷新页面创建新记录。任何人都可以帮助我在 php 中使用替代标题吗?

或任何其他解决方案,我尝试了很多,但我的问题没有解决,所以再次发布这个问题。

谢谢

4

3 回答 3

4

假设有 3 页

(1) Registration.jsp :具有注册表<form action="AddUser.jsp" >,用户可以在其中输入数据。

(2) AddUser.jsp(或者更好的是servlet):接受“Registration.jsp”提交的数据。

(3) Welcome.jsp : 注册后会出现这个页面。

所以在page2(AddUser.jsp)中写下如下代码

  • 接受来自“ Request ”对象的注册表单变量
  • 建立数据库连接并将值存储到数据库中
  • 执行response.sendRedirect("Welcome.jsp")

由于浏览器 URL 将被更改。因此,如果用户刷新页面,那么它也不会创建重复的条目。

于 2013-08-15T11:59:34.563 回答
2

如果我理解你的话:

  • 浏览器发送POST /insertdatawww.mypage.com
  • 数据被插入,服务器响应OK 200
  • 当用户刷新页面时,再次启动插入重复数据的过程

您可以通过这样的重定向来避免它:

 response.sendRedirect("http://www.mypage.com/insertsuccessful");

将此代码放在处理 POST 的 servlet/JSP 的末尾。这将发生:

注意:状态码 (302) 和位置标头由该sendRedirect方法自动设置。

现在,当用户刷新页面时www.mypage.com/insertsuccesful,它将不再发布重复数据。

www.mypage.com/insertfailed如果您在 POST 处理程序中捕获异常,您还可以创建页面并重定向到它。

教程

更新 2

为了跟进@JB Nizet 的评论(感谢您的小心),我们假设您的 web 应用程序使用上下文路径部署,例如www.mypage.com/webapp,并查看以下场景:

  1. 插入页面的 URL ( http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful) 包含一个查询字符串参数redirectOnOk,该参数定义成功插入后客户端将重定向到的位置 ->http://www.mypage.com/webapp/insertsuccessful
  2. webapp 使用URL 重写
  3. 您正在使用Session进行登录控制

第一种情况

首先要注意的是这http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful不是一个有效的 URL。这是无效的,因为您不希望/在问号 ( ) 后出现斜线 ( ?):

scheme://domain:port/path?query_string#fragment_id

有效的 URL 可以包含英文字母、数字、点 ( .)、连字符 ( -)、下划线 ( _) 和波浪号 ( ~)。其他一些标点符号是保留的,并且每个其他字符(有时甚至是保留字符)都必须是URL 编码的

http://www.mypage.com/webapp/insertdata?redirectOnOK=%2Finsertsuccessful

由于在保留/字符问号 ( ?) 之后不需要保留字符斜线 ( ),因此必须对其进行编码。这是第一种情况的解决方案:

String redirectRelativeUrl = new URLDecoder().decode(request.getParameter("redirectOnOk"),"UTF-8");
response.sendRedirect(request.getContextPath() + redirectRelativeUrl)

如果您在形成查询字符串时使用非英文字母字符,则键和值应始终为URL 编码

String safe = new UrlEncoder().encode("ž@Š","UTF-8");

第二种情况

URL 重写是一种基于正则表达式映射 URL 的机制。换句话说,浏览器请求:

http://www.mypage.com/webapp/resource/someName/12

如果上下文根目录下有一个 JSP 页面resource.jsp,那么可以定义一个 URL 重写规则来将上面的内容映射到:

http://www.mypage.com/webapp/resource.jsp?name=someName&count=12

因此,如果您以编程方式从您的 serlvet/JSP 重定向,您还必须应用(出站)URL 重写规则。在上面的示例中,入站规则是:

  • /someName/12->?name=someName&count=12
  • /webapp/resource->/webapp/resource.jsp

从服务器以编程方式重定向时需要应用出站规则:

  • name=someName&count=12->/someName/12
  • /resource.jsp->/resource

为了简单起见,规则以这种方式呈现,实际上并不是正则表达式。这种情况下的解决方案是:

response.sendRedirect(response.encodeRedirectURL(request.getRequestURI() + "?" + request.getQueryString())

第三种情况

启动HTTP 会话非常简单:

Session session = request.getSession();

这样做的结果是它设置了一个JSESSIONID cookie

jsessionid=9ADABC18DB58C4DA99896C6261D2DD25

如果浏览器禁用了 cookie,则在程序化重定向时,用户将不再被验证,这意味着他将不得不再次登录。这种情况下的解决方案是:

String relativeRedirectUrl="/insertSucessful";
response.sendRedirect(response.encodeURL(request.getContextPath() + relativeRedirectUrl));
  • encodeURL如果 cookie 被禁用,则附加;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25到输入
  • 浏览器被重定向到/webapp/insertSucessful;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25

结论

  • 由无效 URL 语法产生的错误很难调试,也很难注意到。在重定向到 URL 之前记录 URL 是一种很好的做法。
  • 最好使用相对 URL,因为这样您就可以将 webapp 部署在具有不同域名的多台服务器上,以及不同的上下文路径上,而无需更改某些属性文件中的源代码或值
于 2013-08-15T11:32:49.490 回答
1

我认为您已经通过“linski”和“Rakesh”详细说明了答案的最重要部分。为此,我对他们都投了赞成票。

然而,我想指出一件事。

两个答案中都提到了已经存在一段时间的 PRG(Post-Redirect-Get)模式。这将解决大多数重复发布问题,但失败的一个领域是存在“服务器滞后”。如果您的后端工作在启动重定向之前有一些明显的滞后时间,则用户可能会通过再次单击提交按钮(假设您正在使用发布数据的按钮)来启动多个发布操作。

一个简单的前端解决方案是在第一次单击后暂时禁用按钮(或您用来启动发布操作的任何按钮)。

您当然可以在后端发挥创意,以确保同一用户在重定向发生之前不会发布重复的帖子,但这需要更多的工作。

于 2013-08-15T19:47:27.877 回答