能否在Struts 2中阻止特定Action的GET请求?
这个问题在Struts2开发里太常见了——框架默认不会限制触发Action的请求方法,哪怕你表单都用了<s:form method="POST">提交,构造个类似www.domain.com?method:Save¶m1=aa的GET请求照样能调用到Save Action。要解决这个问题,有几个实用的方案,你可以根据自己的场景选择:
方案一:在目标Action内部直接校验请求方法
这种方式最直接,不需要额外配置拦截器,就在你的Save Action的业务方法里先判断请求类型:public class SaveAction extends ActionSupport { public String save() { HttpServletRequest request = ServletActionContext.getRequest(); // 检查是否为GET请求 if ("GET".equalsIgnoreCase(request.getMethod())) { // 返回自定义的错误结果,记得在struts.xml里配置对应的错误页面 return "invalidRequest"; } // 执行正常的保存逻辑 return SUCCESS; } }适合只需要限制单个Action的场景,简单快捷。
方案二:自定义拦截器批量拦截指定Action的GET请求
如果有多个Action需要限制GET请求,自定义拦截器会更高效。你可以写一个拦截器来统一校验:public class BlockGetForActionsInterceptor extends AbstractInterceptor { // 可以配置需要拦截的Action名称列表,灵活扩展 private List<String> blockedActions; @Override public String intercept(ActionInvocation invocation) throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); String currentActionName = invocation.getProxy().getActionName(); // 如果是GET请求且当前Action在拦截列表中 if ("GET".equalsIgnoreCase(request.getMethod()) && blockedActions.contains(currentActionName)) { return "invalidRequest"; } return invocation.invoke(); } // 生成getter和setter方法,方便在struts.xml里配置blockedActions public List<String> getBlockedActions() { return blockedActions; } public void setBlockedActions(List<String> blockedActions) { this.blockedActions = blockedActions; } }然后在struts.xml里注册这个拦截器,并把它加到目标Action的拦截器栈中:
<struts> <package name="default" extends="struts-default"> <interceptors> <interceptor name="blockGet" class="com.yourpackage.BlockGetForActionsInterceptor"> <!-- 配置需要拦截的Action名称,比如这里的Save --> <param name="blockedActions">Save</param> </interceptor> <!-- 自定义包含该拦截器的栈 --> <interceptor-stack name="customStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="blockGet"/> </interceptor-stack> </interceptors> <!-- 给Save Action使用自定义拦截器栈 --> <action name="Save" class="com.yourpackage.SaveAction" method="save"> <interceptor-ref name="customStack"/> <result name="success">/success.jsp</result> <result name="invalidRequest">/error.jsp</result> </action> </package> </struts>方案三:使用Struts2注解限制允许的请求方法
如果你是用注解来配置Action,可以用@AllowedMethods注解指定该Action只接受POST请求:import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.AllowedMethods; import org.apache.struts2.convention.annotation.Result; import com.opensymphony.xwork2.ActionSupport; @Action(value = "Save", results = { @Result(name = SUCCESS, location = "/success.jsp") }) @AllowedMethods({"POST"}) public class SaveAction extends ActionSupport { public String save() { // 正常的保存逻辑 return SUCCESS; } }配置后,任何GET请求访问这个Action都会被框架直接拒绝,返回错误页面。
方案四:通过web.xml的安全约束底层拦截
这个是Servlet层面的限制,不管Struts2框架的配置,直接针对URL拦截GET请求。如果你的Save Action对应的URL是/Save.action,可以在web.xml里添加:<security-constraint> <web-resource-collection> <web-resource-name>Block Save GET Requests</web-resource-name> <url-pattern>/Save.action</url-pattern> <http-method>GET</http-method> </web-resource-collection> <!-- 空的auth-constraint表示拒绝所有用户访问 --> <auth-constraint/> </security-constraint>这种方式会直接返回403 Forbidden状态码,拦截层级更低,安全性也更高。
内容的提问来源于stack exchange,提问作者lucas999

