【问题标题】:simplecaptcha image only served after reloadsimplecaptcha 图像仅在重新加载后提供
【发布时间】:2013-01-06 23:03:22
【问题描述】:

我正在使用SimpleCaptcha 来保护我们的联系表。它运行良好,但只有在重新加载页面后

Servlet 是nl.captcha.servlet.StickyCaptchaServlet,所以它不应该在重新加载后改变图像。但是当第一次打开页面时,图像只是没有加载。但是,重新加载后一切正常。

web.xml

验证码由在 /services 运行的应用程序提供。

<web-app>
  <servlet>
    <servlet-name>captcha</servlet-name>
    <servlet-class>nl.captcha.servlet.StickyCaptchaServlet<servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>captcha</servlet>
    <url-pattern>/captcha.png</url-pattern>
  </servlet-mapping>
</web-app>

html

<img src="/services/captcha.png">

服务器

我在带有Java 1.7.0_07Windows 7 64bit 机器上使用tomcat-7.0.34

问题

为什么图片只有在重新加载后才会显示?有什么想法吗?

【问题讨论】:

  • 您的StickyCaptchaServlet 配置为/captcha.png 而您在html 页面中使用/services/captcha.jpg 这是真实的还是只是拼写错误?你还有其他的Servlet 这个应用程序吗?你的&lt;load-on-startup&gt; 配置是什么?
  • 我的错,我复制错了...在问题中对其进行了编辑。我还有另外两个 servlet,都用于联系表单,都检查验证码是否已解决。目前没有&lt;load-on-startup&gt;配置。
  • 尝试添加 &lt;load-on-startup&gt; 并为您的验证码服务器设置比使用该验证码的其他 servlet 更大的值
  • 我试过了,但是不行。即使我直接访问 servlet(例如 localhost:8080/services/captcha.png),它也需要重新加载才能显示验证码。

标签: java servlets captcha simplecaptcha


【解决方案1】:

检查web.xml 是否有captcha.png,而HTML 指的是captcha.jpg

这能解决问题吗?

【讨论】:

  • 不,抱歉。我只是把html部分复制错了(它指向captcha.png)。
【解决方案2】:

问题是 StickyCaptchaServlet 正在为会话创建新的验证码图像。当您向页面发出初始请求时,您没有会话 ID,因此 StickyCaptchaServlet 无法将您连接到为特定会话创建的任何图像。

在第一次请求主 servlet 后,为您创建会话并将某种sessionId 发回给您。通过下一个请求(也重新加载),您发送到服务器请求并收到之前收到的sessionId,所以现在您的StickyCaptchaServlet 可以为您的会话收集验证码图像,因为它知道您在任何会话中。

你明白这个解释吗?对你有帮助吗?

在您提出问题后添加以解决此问题。

您可以添加到将实现HttpSessionListener 的网络应用程序类。然后,在方法@​​987654325@ 中,您可以使用刚刚创建的sessionIdStickyCaptchaServlet 添加请求。根据StickyCaptchaServlet doc,您只需使用传递的 sessionId 键调用它的doGet 方法。之后 - 当您页面上的浏览器请求 url /services/captcha.png 时,它应该作为响应图像在您的 HttpSessionListener 实现之前创建和准备。

另一种方法是使用客户端脚本,在页面加载后,根本没有图像,只需重新加载它 - 作为这种内部重新加载,例如 JavaScript,浏览器将知道 sessionId 并将其传递给验证码请求图片。重新加载是指仅重新加载图像,而不是整个页面。

这些建议中的任何一个都可以解决您的问题吗?给我一个反馈。

【讨论】:

  • 这个解释似乎解决了我真正的问题。但是有什么解决办法吗? (即,我可以通过第一页调用生成具有相应sessionId 的会话吗?)
  • 感谢您的建议。我尝试在客户端重新加载图像(重新设置src 属性,添加一个虚拟值以强制重新加载),但这不起作用。重新加载整个页面对我来说似乎不可行。 HttpSessionListener 的东西听起来很有趣,但我无法让它调用 StickyCaptchaServletdoGet 方法。
【解决方案3】:

您可以遵循以下几个步骤:

1> 修改 web.xml 添加扩展 nl.captcha.servlet.StickyCaptchaServlet 类的 servlet

 <servlet>   
    <description></description>    
    <display-name>CustomCaptchaServlet</display-name>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <servlet-class>org.example.servlets.CustomCaptchaServlet</servlet-class>    
 </servlet>    
  <servlet-mapping>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <url-pattern>/CustomCaptchaServlet</url-pattern>    
  </servlet-mapping>

2> CustomCaptchaServlet.java

package org.example.servlets;    
import static nl.captcha.Captcha.NAME;    

import java.io.IOException;    

import javax.servlet.ServletException;    
import javax.servlet.http.HttpServlet;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
import javax.servlet.http.HttpSession;    

import nl.captcha.Captcha;    
import nl.captcha.servlet.CaptchaServletUtil;    
import nl.captcha.servlet.StickyCaptchaServlet;    

public class CustomCaptchaServlet extends StickyCaptchaServlet {    
    private static final long serialVersionUID = 1L;    

    /**
     * @see StickyCaptchaServlet#StickyCaptchaServlet()
     */
    public CustomCaptchaServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

        String _width = getServletConfig().getInitParameter("width");    
        String _height = getServletConfig().getInitParameter("height");    
        HttpSession session = request.getSession();    
        Captcha captcha;    
        if (session.getAttribute(NAME) == null) {    
            captcha = new Captcha.Builder(Integer.parseInt(_width), Integer.parseInt(_height))    
            .addText()    
            .gimp()    
            .addBorder()    
                .addNoise()    
                .addBackground()    
                .build();    
            session.setAttribute(NAME, captcha);    
            CaptchaServletUtil.writeImage(response, captcha.getImage());    
            return;    
        }    
        captcha = (Captcha) session.getAttribute(NAME);    
        CaptchaServletUtil.writeImage(response, captcha.getImage());    
    }    


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

    }    

}    

【讨论】:

    【解决方案4】:

    这样就可以绕过emka86所说的。

    <img src="/services/captcha.png" style="display:none"> (Duplicate part to fix the issue)
    
    <img src="/services/captcha.png"> (The actual one)
    

    希望这对未来的开发者有所帮助。

    【讨论】:

    • 虽然我最终自己修补了 SimpleCaptcha(而且我忘记了我到底做了什么),但这是一个我非常喜欢的非常简单的解决方案。谢谢!
    • @Nilindra,如果我使用的是 怎么办?这里“captchaImage”映射到 web.xml 中的一个 servlet,它返回实际的验证码图像。我也面临类似的问题。任何帮助将不胜感激
    猜你喜欢
    • 2020-08-30
    • 2021-06-01
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    相关资源
    最近更新 更多