【问题标题】:What is alternate of php header in jsp and servlet applicaiton to stop duplicacyjsp和servlet应用程序中php标头的替代方法是什么?
【发布时间】:2013-08-17 13:26:06
【问题描述】:

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

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

谢谢

【问题讨论】:

  • 您能告诉我们“php 中的标头”是什么意思吗?懂jsp的人不少,php懂的也不小。
  • 我的朋友正在研究 php,他向我展示了 php 中的解决方案,因为在执行插入查询后,页面被重定向为 header("Location:abc.php?message=1");跨度>
  • 就知道PHP而言,我是php的菜鸟。我只是很想看到一个例子——比如作为关键字或线索——来做更多的研究。
  • @AnkitKumar 以前版本的答案包含虚假信息。请查看我已验证所有示例的更新答案。

标签: jsp servlets


【解决方案1】:

如果我理解你的话:

  • 浏览器将POST /insertdata发送到www.mypage.com
  • 数据被插入,服务器回复@987654321@
  • 当用户刷新页面时,再次启动插入重复数据的过程

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

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

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

  • 浏览器将POST /insertdata发送到www.mypage.com
  • 数据被插入,服务器响应@987654322@,标头Location: @987654323@
  • 浏览器自动发送GET /insertsuccesfulwww.mypage.com

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

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

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

tutorial

更新 2

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

  1. 插入页面的 URL (@987654326@) 包含一个 query string 参数 redirectOnOk,它定义了成功插入后客户端将重定向到的位置 ->@987654328@
  2. webapp 使用URL rewriting
  3. 您正在使用Session 进行登录控制

第一种情况

首先要注意的是@987654331@ 不是valid URL。这是无效的,因为您不希望在问号 (?) 后出现斜杠 (/):

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

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

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

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

String redirectRelativeUrl = new URLDecoder().decode(request.getParameter("redirectOnOk"),"UTF-8");
response.sendRedirect(request.getContextPath() + redirectRelativeUrl)
  • @987654335@%2F 解码为 /
  • 需要@987654336@ 才能返回/webapp(在第一种情况下,由于没有上下文路径,它将返回一个空字符串)
  • /webapp/insertsuccessful进入@987654337@方法
  • 浏览器被重定向到/webapp/insertsuccessful

如果您在形成查询字符串时使用非英文字母字符,则keys and values 应始终为URL encoded

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

第二个场景

URL 重写是一种基于regular expressions 映射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())
  • @987654341@ 返回/webapp/resource.jsp
  • @987654342@ 返回name=someName&count=12
  • @987654343@ 有输入 /webapp/resource.jsp?name=someName&count=12
  • 浏览器被重定向到/webapp/resource/someName/12

第三种情况

Initiating HTTP session 真的很简单:

Session session = request.getSession();

这导致它设置了一个JSESSIONIDcookie

jsessionid=9ADABC18DB58C4DA99896C6261D2DD25

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

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

结论

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

【讨论】:

  • 为什么不直接使用response.sendRedirect()
  • 然后不需要设置 Location 标头,完全正确! thx,将在几秒钟内更新 :)
  • 你不应该在 URL 中硬编码主机和上下文,你应该使用 encodeRedirectURL 是必须支持 URL 重写:response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/somePage"))
【解决方案2】:

假设有 3 页

(1) Registration.jsp : 有注册表单

以及用户可以在哪里输入数据。

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

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

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

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

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

【讨论】:

  • 如果 webapp 使用上下文路径部署,则步骤 3.3 将不起作用 - 请参阅我的答案中的更新
  • 如果 URL 不是绝对的,它会相对于当前 URL 进行重定向。如果 URL 以 / 开头,则相对于上下文根重定向,否则重定向到当前 url
  • 没错! “如果位置是相对的,没有前导 '/',则容器将其解释为相对于当前请求 URI。如果位置是相对于前导 '/',则容器将其解释为相对于 servlet 容器根。”赞成。
  • 如果 Welcome.jsp 不在 webapp 根目录中。此类陈述需要更多上下文,我撤回我的第一条评论。
【解决方案3】:

我想你已经得到了答案中最重要的部分,“linski”和“Rakesh”已经详细说明了。为此,我对他们俩都投了赞成票。

不过,我想指出一件事。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-19
    • 2011-06-29
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多