struts的问题

本文介绍Struts框架中如何通过生成唯一标识符(Token)来防止表单重复提交的问题。详细解释了LoginAction类中get与login方法的工作流程,以及如何在登录页面动态生成并验证Token。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用token是为了防止重复提交,像灌水之类的.

LoginAction:

package com.web.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

public class LoginAction extends DispatchAction {
    
    
public ActionForward get(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
//保存令牌(保存在jsp动态生成的32位jsessionid)\
        this.saveToken(request);
        System.out.println(
"begin save");
        
return mapping.findForward("login");
    }

    
    
public ActionForward login(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
/**//*if(this.isTokenValid(request))
        {
            System.out.println("valid");
            this.resetToken(request);
            return mapping.findForward("ok");
        }
*/

        
//这个写法和上面注释部分一样效果
        if(this.isTokenValid(request,true))
        
{
            System.out.println(
"valid");
            
return mapping.findForward("ok");
        }

        
else
        
{
            System.out.println(
"invalid");
            
return mapping.findForward("error");
        }

    }

}

struts-config.xml:

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

<struts-config>
    
<data-sources />
    
<form-beans>
        
<form-bean name="loginForm" type="com.web.form.LoginForm"></form-bean>
    
</form-beans>
    
<global-exceptions />
    
<global-forwards />
    
<action-mappings>
        
<action path="/login" parameter="method" name="loginForm"
            type
="com.web.action.LoginAction">
            
<forward name="login" path="/login.jsp" />
            
<forward name="ok" path="/ok.jsp" />
            
<forward name="error" path="/error.jsp" />
        
</action>
    
</action-mappings>
    
<message-resources parameter="" />
</struts-config>


index.jsp:

<%@page contentType="text/html; charset=GBK"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<html>
  
<head>
    
<title>My Jsp</title>
  
</head>
  
<body>
  
<href="${ctx}/login.do?method=get">发言</a>
  
</body>
</html>


login.jsp:

<%@page contentType="text/html; charset=GBK"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<html>
  
<head>
    
<title>My Jsp</title>
  
</head>
  
<body>
  
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
  
<!-- 此处必须使用html标签,否则token不能用 -->
  
<html:form action="login.do?method=login" method="post">
    
<html:submit value="提交"></html:submit>
  
</html:form>
  
</body>
</html>


当你运行第一次的时候,会提示你"成功".
这时我们退到login.jsp查看一下源代码:

<html>
  
<head>
    
<title>My Jsp</title>
  
</head>
  
<body>
  
  
<form name="loginForm" method="post" action="/strutsToken/login.do?method=login">
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="d7484f95247cf242a6f35107a1c7ac25"></div>
    
<input type="submit" value="提交">
  
</form>
  
</body>
</html>

对比一下我们写的login.jsp多了一个隐藏域:

<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="d7484f95247cf242a6f35107a1c7ac25"></div>

此时生成了一个32位的唯一的JsessionID做为值.
与LoginAction中的get方法的saveToken(request)是一样的.
此句的作用就是把一个jsessionid保存到request范围里.

在我们后退重新调用:

if(this.isTokenValid(request,true))
        
{
            System.out.println(
"valid");
            
return mapping.findForward("ok");
        }

时,就会拿login.jsp里传过来的jsessionid和request的
进行比较,如果一样,说明不合法.因为我们的操作都是在一个请求会话里
操作的.说明你在重复提交.
如果不一样,说明重新生成了一个唯一的jsessionid(新开一个浏览器),
开启了一个新会话,重新提交,这是合法的.
这样就防止了表单重复提交问题.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值