25、Struts 插件:CAPTCHA 与 Tiles 的使用指南

Struts 插件:CAPTCHA 与 Tiles 的使用指南

1. CAPTCHA 插件

CAPTCHA 结果类型基于 CaptchaResult 类,该类继承自 StrutsResultSupport 。为了便于在应用程序中使用该结果类型,需要将其打包为插件,并在 struts-plugin.xml 中进行注册。

以下是 struts-plugin.xml 文件的示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="captcha-default" extends="struts-default">
        <result-types>
            <result-type name="captcha"
                    class="com.brainysoftware.captcha.CaptchaResult"
            />
        </result-types>
    </package>
</struts>

创建 JAR 包的步骤如下:
1. 切换到 struts-plugin.xml 所在的目录,该目录也包含 com 目录。
2. 输入以下命令并按回车键:

jar -cvf captchaplugin.jar *

这样就会创建一个名为 captchaplugin.jar 的 JAR 包,这就是你的插件。

使用 CAPTCHA 插件

要使用 CAPTCHA 插件,需要将 captchaplugin.jar brainycaptcha.jar 文件复制到应用程序的 WEB-INF/lib 目录中。

app23b 应用程序中,定义了三个动作: Login_input Login GetCaptchaImage 。动作声明如下:

<package name="app23b" extends="captcha-default">
    <action name="Login_input">
        <result>/jsp/Login.jsp</result>
    </action>
    <action name="Login" class="app23b.Login">
        <result name="success">/jsp/Thanks.jsp</result>
        <result name="input">/jsp/Login.jsp</result>
        <param name="hashCookieName">hashCookie</param>
    </action>
    <action name="GetCaptchaImage">
        <result type="captcha">
            <param name="hashCookieName">hashCookie</param>
            <param name="wordLength">6</param>
            <param name="imageWidth">90</param>
            <param name="imageHeight">25</param>
        </result>
    </action>
</package>

Login 类的代码如下:

package app23b;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.brainysoftware.captcha.CaptchaUtil;
import com.opensymphony.xwork2.ActionSupport;

public class Login extends ActionSupport
        implements ServletRequestAware {
    private String userName;
    private String password;
    private String word;
    private String hashCookieName = "hash";
    private HttpServletRequest httpServletRequest;
    public void setServletRequest(HttpServletRequest
            httpServletRequest) {
        this.httpServletRequest = httpServletRequest;
    }
    // getters and setters not shown

    public String execute() {
        Cookie[] cookies = httpServletRequest.getCookies();
        String hash = null;
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(hashCookieName)) {
                hash = cookie.getValue();
                break;
            }
        }
        if (hash != null
                && userName.equals("don")
                && password.equals("secret")
                && CaptchaUtil.validate(word, hash)) {
            return SUCCESS;
        } else {
            addActionError("Login failed.");
            return INPUT;
        }
    }
}

Login.jsp 页面的代码如下:

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Login with CAPTCHA</title>
<style type="text/css">@import url(css/main.css);</style>
</head>
<body>
<div id="global">
    <h3>Enter your user name, password, and the image word</h3>
    <s:actionerror/>
    <s:form action="Login">
        <s:textfield name="userName" label="User Name"/>
        <s:password name="password" label="Password"/>
      <tr>
          <td><img src="GetCaptchaImage.action"/></td>
          <td><s:textfield theme="simple" name="word"
    value=""/></td>
      </tr>
      <s:submit value="Login"/>
    </s:form>
</div>
</body>
</html>

Thanks.jsp 页面的代码如下:

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Thank you</title>
<style type="text/css">@import url(css/main.css);</style>
</head>
<body>
<div id="global">
You're logged in.
</div>
</body>
</html>

要测试该应用程序,在浏览器中访问以下 URL:

http://localhost:8080/app23b/Login_input.action
2. Tiles 插件

Web 应用程序通常需要一致的外观,可以通过使用相同的布局来实现。传统的 JSP 包含方式存在一些缺点,例如修改布局时需要修改所有的 JSP 文件。Tiles 插件可以克服这些问题,并提供更多的功能,使页面布局更加容易和灵活。

Tiles 布局和定义

Tiles 解决了 JSP 包含在定义页面布局时的问题,涉及两个概念:布局和定义。

  • 布局页面 :布局页面是一个模板 JSP,用于定义布局。可以根据需要创建多个布局 JSP,每个需要使用布局的 JSP 只需间接引用布局 JSP。如果需要更改整个应用程序的布局,只需更改一个文件,即布局 JSP。

以下是一个布局 JSP 的示例 MyLayout.jsp

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<html>
<head>
<title><tiles:getAsString name="pageTitle"/></title>
<style type="text/css">@import url(css/main.css);</style>
</head>
<body>
    <tiles:insertAttribute name="header"/>
    <tiles:insertAttribute name="body"/>
    <tiles:insertAttribute name="footer"/>
</body>
</html>

insertAttribute 标签的属性如下表所示:
| 属性 | 类型 | 描述 |
| ---- | ---- | ---- |
| name | String | 要插入的属性名称,如果 value 属性存在,则忽略该属性。 |
| value | String | 要渲染的属性对象。 |
| flush | boolean | 值为 true 时,在插入之前刷新当前页面输出流。 |
| ignore | boolean | 值为 true 时,表示如果 name 属性指定的属性找不到,不会抛出异常,默认值为 false 。 |
| role | String | 指定当前用户必须属于的角色才能执行此标签。 |
| preparer | String | 准备器的完全限定名称。 |

getAsString 标签的属性如下表所示:
| 属性 | 类型 | 描述 |
| ---- | ---- | ---- |
| name | String | 指定属性名称的必需属性。 |
| ignore | boolean | 值为 true 时,表示如果 name 属性指定的属性找不到,不会抛出异常,默认值为 false 。 |
| role | String | 指定当前用户必须属于的角色才能执行此标签。 |

  • Tiles 定义 :定义是布局页面和使用该布局的 JSP 之间的一层。在 Struts 中,Tiles 定义对应于一个视图,通常是一个 JSP,但也可以使用 Velocity 或 FreeMarker。

Tiles 定义在 tiles.xml 文件中定义,该文件位于 Struts 应用程序的 WEB-INF 目录中。以下是一个 tiles.xml 文件的示例:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
    "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
    "http://struts.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>
    <definition name="Product" template="/jsp/MyLayout.jsp">
        <put-attribute name="pageTitle" value="Product Input"/>
        <put-attribute name="header" value="/jsp/Header.jsp"/>
        <put-attribute name="footer" value="/jsp/Footer.jsp"/>
        <put-attribute name="body" value="/jsp/Product.jsp"/>
    </definition>

    <definition name="Thanks" template="/jsp/MyLayout.jsp">
        <put-attribute name="pageTitle" value="Thank You"/>
        <put-attribute name="header" value="/jsp/Header.jsp"/>
        <put-attribute name="footer" value="/jsp/Footer.jsp"/>
        <put-attribute name="body" value="/jsp/Thanks.jsp"/>
    </definition>
</tiles-definitions>
使用 Struts Tiles 插件

要在 Struts 应用程序中使用 Tiles 插件,需要执行以下步骤:
1. 将 Tiles JAR 文件( tiles-core-VERSION.jar tiles-api-VERSION.jar tiles-jsp-VERSION.jar )和 struts2-tiles-plugin-VERSION.jar 文件复制到 WEB-INF/lib 目录中。
2. 在 web.xml 文件中注册 StrutsTilesListener

<listener>
    <listener-class>
        org.apache.struts2.tiles.StrutsTilesListener
    </listener-class>
</listener>
  1. 在包中扩展 tiles-default 包,或者定义以下内容:
<result-types>
    <result-type name="tiles"
        class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
  1. 在动作中使用 tiles 结果。
Struts Tiles 示例

app24a 应用程序有两个动作: Product_input Product_add 。动作声明如下:

<package name="app24a" extends="tiles-default">
    <action name="Product_input">
        <result name="success" type="tiles">Product</result>
    </action>
    <action name="Product_add">
        <result name="success" type="tiles">Thanks</result>
    </action>
</package>

这些动作的结果类型为 tiles ,它们将转发到定义而不是 JSP。 Product Thanks 定义在 tiles.xml 文件中定义。

通过使用 CAPTCHA 插件和 Tiles 插件,可以增强应用程序的安全性和页面布局的灵活性。

Struts 插件:CAPTCHA 与 Tiles 的使用指南(续)

3. 总结与实践建议
3.1 CAPTCHA 插件总结

CAPTCHA 插件主要用于增强应用程序的安全性,防止自动化脚本恶意登录或操作。通过将 CAPTCHA 结果类型封装为插件,我们可以方便地在不同的 Struts 应用中复用。以下是使用 CAPTCHA 插件的关键步骤总结:
1. 创建插件
- 基于 CaptchaResult 类扩展 StrutsResultSupport
- 在 struts-plugin.xml 中注册结果类型。
- 使用 jar 命令创建 JAR 包。
2. 使用插件
- 将 captchaplugin.jar brainycaptcha.jar 复制到 WEB-INF/lib 目录。
- 在 struts.xml 中定义相关动作和结果。
- 编写动作类处理登录逻辑,验证 CAPTCHA 输入。

在实际应用中,我们可以根据需要调整 CAPTCHA 的参数,如验证码长度、图片大小等,以提高安全性和用户体验。

3.2 Tiles 插件总结

Tiles 插件解决了传统 JSP 布局管理的难题,通过布局页面和定义的概念,实现了页面布局的复用和灵活管理。以下是使用 Tiles 插件的关键步骤总结:
1. 准备工作
- 复制 Tiles 相关的 JAR 文件到 WEB-INF/lib 目录。
- 在 web.xml 中注册 StrutsTilesListener
- 在 struts.xml 中扩展 tiles-default 包或定义 tiles 结果类型。
2. 创建布局和定义
- 编写布局 JSP 文件,使用 Tiles 标签定义插入点。
- 在 tiles.xml 文件中定义页面布局和属性。
3. 使用 Tiles 结果
- 在动作中使用 tiles 结果类型,指定要转发的定义名称。

在实际应用中,我们可以根据不同的页面需求创建多个布局和定义,提高页面的可维护性和一致性。

4. 流程图展示

以下是使用 CAPTCHA 插件的登录流程 mermaid 流程图:

graph TD;
    A[用户访问 Login_input.action] --> B[显示 Login.jsp 页面];
    B --> C[用户输入用户名、密码和验证码];
    C --> D[提交表单到 Login 动作];
    D --> E{验证 CAPTCHA};
    E -- 验证成功 --> F{验证用户名和密码};
    F -- 验证成功 --> G[显示 Thanks.jsp 页面];
    E -- 验证失败 --> H[显示错误信息,返回 Login.jsp 页面];
    F -- 验证失败 --> H;

以下是使用 Tiles 插件的页面渲染流程 mermaid 流程图:

graph TD;
    A[用户访问动作] --> B{动作结果类型为 tiles};
    B -- 是 --> C[查找对应的 Tiles 定义];
    C --> D[根据定义加载布局 JSP];
    D --> E[插入定义中的属性到布局 JSP];
    E --> F[显示最终页面];
    B -- 否 --> G[按常规方式处理结果];
5. 注意事项和常见问题
5.1 CAPTCHA 插件注意事项
  • Cookie 管理 :在验证 CAPTCHA 时,需要确保正确获取和使用存储验证码哈希值的 Cookie。
  • 安全性 :定期更新 CAPTCHA 的生成算法和参数,以防止被破解。
  • 兼容性 :确保 brainycaptcha.jar 文件与应用程序的其他依赖兼容。
5.2 Tiles 插件注意事项
  • JAR 文件版本 :确保 Tiles 相关的 JAR 文件版本一致,避免出现兼容性问题。
  • 定义文件路径 tiles.xml 文件必须位于 WEB-INF 目录下,否则可能无法正确加载定义。
  • 标签使用 :正确使用 Tiles 标签,注意标签的属性和作用范围。
5.3 常见问题及解决方法
问题 描述 解决方法
CAPTCHA 验证失败 用户输入的验证码正确,但验证结果仍为失败 检查 Cookie 是否正确设置和获取,确保 CaptchaUtil 方法调用正确。
Tiles 布局未生效 页面未按预期显示布局 检查 tiles.xml 文件是否正确配置,确保 StrutsTilesListener 已注册。
JAR 文件冲突 应用程序启动时出现类冲突错误 检查 JAR 文件版本,排除重复或不兼容的依赖。

通过遵循上述步骤和注意事项,我们可以顺利地在 Struts 应用中使用 CAPTCHA 插件和 Tiles 插件,提高应用程序的安全性和页面布局的灵活性。在实际开发中,我们可以根据具体需求对插件进行定制和扩展,以满足不同的业务场景。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值