我正在尝试使用Struts 2实现SimpleCaptcha,到目前为止图像正在显示。但是,它显示在<s:form>
的顶部。
register.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<head>
...
<s:head />
</head>
<body>
<b>REGISTER</b>
<p>Please fill up the form below.</p>
<s:form action="register" method="post">
<s:textfield label="Enter username" key="userId" maxlength="25"
size="30" />
<s:textfield label="Enter email" key="userEmail1" type="email"
placeholder="someone@domain.com" size="30" />
<s:textfield label="Re-enter email" key="userEmail2" type="email"
placeholder="someone@domain.com" size="30" />
<s:password label="Enter password" key="userPassword1" size="30" />
<s:password label="Re-enter password" key="userPassword2"
size="30" />
<img src="<c:url value='simple-captcha.png' />" />
<br />
Cannot read? Refresh page for new CAPTCHA.
<s:textfield label="Enter CAPTCHA" key="captchaAnswer" size="30" />
<s:submit value="Register" />
</s:form>
</body>
如何让图片显示在代码中指定的 Enter CAPTCHA
文本字段上方?
答案 0 :(得分:1)
图像应由captcha
动作生成。然后,您在<img>
代码中提供此操作的网址。要在项目中实施验证码,请按照以下步骤进行操作
1)将jar添加到您的Web项目类路径:simplecaptcha-1.2.1.jar
。
通常位于web-inf/lib
文件夹内。
2)添加新的操作类RegisterAction
注意:以下代码使用约定插件来映射操作,为简单起见,DMI用于在提交表单时调用操作类的某些方法。要打开DMI,请使用struts.xml
中的常量:
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<强> RegisterAction.java
强>
public class RegisterAction extends ActionSupport {
private String userId;
private String userEmail1;
private String userEmail2;
private String userPassword1;
private String userPassword2;
private String captchaResponse;
private InputStream inputStream;
//getters and setters
public String create() {
//RegisterAction is the form bean of the current action and captchaResponse is the field of user input
String answer = (String) ActionContext.getContext().getSession().get("CorrectAnswer");
if (answer == null || getCaptchaResponse()==null || !answer.equals(getCaptchaResponse())){
addFieldError("captchaResponse", getText("error.captcha"));
}
return SUCCESS;
}
@Action(value = "captcha", results = {@Result(type="stream", params = {"contentType", "image/jpeg"})})
public String captcha() {
try {
Captcha captcha = new Captcha.Builder(200, 50).addText(new DefaultTextProducer()).gimp(new DropShadowGimpyRenderer()).build();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//write the image
CaptchaServletUtil.writeImage(outputStream, captcha.getImage());
//store the answer for this in session
ActionContext.getContext().getSession().put("CorrectAnswer", captcha.getAnswer());
//return image
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
RegisterAction.properties
包含错误键的以下值:
<强> RegisterAction.properties
强>
error.captcha=Invalid value of shown text!
所以我们检查成功通过或添加有关验证码的错误错误。
3)通常在register.jsp
web-inf\content
<强> register.jsp
强>
<!DOCTYPE html>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<b>REGISTER</b>
<p>Please fill up the form below.</p>
<s:form action="register" method="post">
<s:textfield label="Enter username" key="userId" maxlength="25"
size="30" />
<s:textfield label="Enter email" key="userEmail1" type="email"
placeholder="someone@domain.com" size="30" />
<s:textfield label="Re-enter email" key="userEmail2" type="email"
placeholder="someone@domain.com" size="30" />
<s:password label="Enter password" key="userPassword1" size="30" />
<s:password label="Re-enter password" key="userPassword2"
size="30" />
<tr><td>
<img id="captchaImg" src="<s:url action='captcha'/>" alt="Captcha Image" height="45">
<img src="<c:url value='/images/reload.jpg' />" alt="Reload" onclick="document.forms[0].captchaImg.src='<s:url action='captcha'/>'+'?id='+Math.random();" style="cursor:pointer"/>
<s:textfield label="Enter CAPTCHA" key="captchaResponse" size="30" requiredLabel="*"/>
<tr><td>
Cannot read? Refresh page for new CAPTCHA.
</td></tr>
<s:submit method="create" value="Register" />
</s:form>
</body>
</html>
这将构造Captcha和文本字段以输入值和Struts错误消息以显示captchaResponse
字段中的错误以及刷新图标。
注意:我们在这里使用的一个好方法是javascript Math.random()
函数,这样可以阻止像Firefox这样的某些浏览器缓存URL并继续发布相同的Captcha图像,这会强制它获取新值而不进行操作更多的努力。
以下是它的外观:
有关详情,请参阅网站:SimpleCaptcha
答案 1 :(得分:0)
这只是为了说明我如何解决这个问题。我不知道你可以将<tr><td>
放在<s:form>
内。感谢 Roman C ,我得到了CAPTCHA图像,以显示我想要的位置。
<强> register.jsp:强>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<head>
...
<s:head />
</head>
<body>
<b>REGISTER</b>
<p>Please fill up the form below.</p>
<s:form action="register" method="post">
<s:textfield label="Enter username" key="userId" maxlength="25"
placeholder="someone" size="30" />
<s:textfield label="Enter email" key="userEmail1"
placeholder="someone@domain.com" size="30" />
<s:textfield label="Confirm email" key="userEmail2"
placeholder="someone@domain.com" size="30" />
<s:password label="Enter password" key="userPassword1" size="30" />
<s:password label="Confirm password" key="userPassword2"
size="30" />
<tr>
<td></td>
<td>
<img src="<c:url value='simple-captcha.png' />" />
<br />
Cannot read? Press F5 to refresh.
</td>
</tr>
<s:textfield label="Enter code" key="captchaAnswer" size="30" />
<s:submit value="Register" />
</s:form>
</body>
<强> RegisterAction.java:强>
import nl.captcha.Captcha;
...
public class RegisterAction extends ActionSupport implements SessionAware, Message {
private static final long serialVersionUID = 1L;
private Map<String, Object> session;
private String userId;
private String userEmail1;
private String userEmail2;
private String userPassword1;
private String userPassword2;
private String captchaAnswer;
@Override
public String execute() throws Exception {
// business logic to insert user into database
return SUCCESS;
}
@Override
public void validate() {
Captcha captcha = (Captcha) session.get(Captcha.NAME);
if(!captcha.isCorrect(getCaptchaAnswer())) {
addFieldError("captchaAnswer", INCORRECT_CAPTCHA);
}
// other validations
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
// getters and setters
}
<强> struts.xml中:强>
<struts>
<constant name="struts.devMode" value="true" />
<package name="default" extends="struts-default">
<action name="register" class="com.mypackage.action.RegisterAction">
<result name="success">/login.jsp</result>
<result name="input">/register.jsp</result>
</action>
<!-- other actions -->
</package>
</struts>
<强>的web.xml:强>
(<init-param>
是可选的。)
<servlet>
<servlet-name>SimpleCaptcha</servlet-name>
<servlet-class>nl.captcha.servlet.SimpleCaptchaServlet</servlet-class>
<init-param>
<param-name>captcha-width</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>captcha-height</param-name>
<param-value>50</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SimpleCaptcha</servlet-name>
<url-pattern>/simple-captcha.png</url-pattern>
</servlet-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<强>输出:强>