Struts2 在渐进增强后形成,无需 AJAX 即可工作
Struts2 forms following progressive enhancement to work without AJAX
我正在重新设计我的表单,以便它们可以在没有启用javascript的情况下工作,但也可以通过使用jquery和AJAX与javascript很好地配合使用。我正在使用支柱,事实证明它既有用又痛苦。没有javascript的表单处理是通过基本的struts功能来处理的,通过验证和执行操作并调度回用户所在的页面,但在表单html中设置了结果(actionMessage或actionError)。我有一个隐藏的输入,其中包含将以 bean 形式设置的页面 url,即支柱中的调度位置.xml
我的问题是我需要能够在一些增强功能(例如 JSON 序列化和 AJAX 请求)下拥有此功能,而我无法找到同时拥有两者的方法。以下是我对无脚本表单的配置和代码,可以正常工作。
支柱.xml文件
<struts>
<package name="default" extends="struts-default,json-default">
<action name="contact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
<result name="success">%{currentPage}</result>
<result name="input">%{currentPage}</result>
<result name="error">%{currentPage}</result>
</action>
</package>
</struts>
无脚本 JSP
<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<s:form id="contact_form" action="contact" method="post" cssClass="clearfix">
<label for="contact_user">Username / In-game name:</label>
<input type="text" id="contact_user" name="contactBean.username"
class="field" data-enter-click="sendbutton" maxlength="16"
size="16" />
<label for="contact_email">Email:</label>
<input type="text" id="contact_email" name="contactBean.email" class="field" data-enter-click="sendbutton" />
<label for="contact_message">Message:</label>
<textarea id="contact_message" name="contactBean.message" rows="5" cols="35"></textarea>
<input id="no_script" name="contactBean.currentPage" type="hidden" value="${pageContext.request.requestURL}" />
<div id="contact_response" class="response">
<s:if test="hasActionErrors()">
<s:actionerror id="contact_fail" cssClass="fail" />
</s:if>
<s:if test="hasActionMessages()">
<s:actionmessage id="contact_success" cssClass="success" />
</s:if>
</div>
<s:submit type="submit" id="sendbutton" value="Send" />
</s:form>
contactAction 类只是一个基本的操作类,其中包含必要字段的 ContactBean,并在未验证时添加 ActionErrors 或在成功时添加 ActionMessages。
现在,对于在此之上的jquery AJAX方法,我已经尝试了几件事。我安装了 struts2 jquery 插件,这是一个很棒的插件,我能够用它在表单上让 ajax 工作 fin,但不能使用上面示例中我的 struts 配置方式。对于以 struts.xml 为单位的结果的调度位置,我将其设置为如下所示的 jsp 页面:
<%@ taglib prefix="s" uri="/struts-tags"%>
<s:property value="response" escapeHtml="false"/>
我向操作类添加了一个名为响应的字段,该字段刚刚使用 actionError 或 actionMessage 字符串设置。jquery 插件能够从该 jsp 中获取结果,并将其很好地附加到目标位置。但这意味着,如果我对 javascript turn of 做同样的事情,一旦提交表单,用户将被调度到仅显示结果字符串的 jsp,而不是将它们调度到同一页面并在表单中设置消息。
我也尝试使用 struts2 json 插件(这也很棒),但这也适用于 jquery ajax,而不是在没有 javascript 的情况下。
关于如何让表单在两种设置中工作的任何想法?谢谢!
我在支柱拦截器的帮助下想通了。我做了一个自定义拦截器,它会检查堆栈参数是否存在"noScript"参数,如果存在,它将返回"noScript"的结果。noScript 结果的类型是"chain",然后在没有 javascript 时转发到处理表单响应的操作。noScript 参数是通过具有当前页面 url 的表单中的隐藏字段设置的。当页面加载时,jQuery将删除页面上任何位置的输入。因此,如果禁用了javascript,则不会删除noScript输入。这是我的新支柱.xml之后:
<struts>
<package name="default" extends="struts-default,json-default">
<interceptors>
<interceptor name="noScriptInterceptor"
class="org.deadmandungeons.website.NoScriptInterceptor"></interceptor>
<interceptor-stack name="noScriptStack">
<interceptor-ref name="noScriptInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="contact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
<interceptor-ref name="noScriptStack"/>
<result type="json" name="success" />
<result type="json" name="input" />
<result type="json" name="error"/>
<result type="chain" name="noScript">noScriptContact</result>
</action>
<action name="noScriptContact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
<result name="success">%{noScript}</result>
<result name="input">%{noScript}</result>
<result name="error">%{noScript}</result>
</action>
</package>
</struts>
下面是 NoScriptInterceptor 类:
public class NoScriptInterceptor implements Interceptor {
private static final long serialVersionUID = -1472114260682759961L;
@Override
public void destroy() {
}
@Override
public void init() {
}
@SuppressWarnings("unchecked")
@Override
public String intercept(ActionInvocation invocation) throws Exception {
final ActionContext context = invocation.getInvocationContext();
String actionName = Utils.toCamelCase(invocation.getAction().getClass().getName());
Map<String,Object> parameters = (Map<String,Object>)context.get(ActionContext.PARAMETERS);
Object noScriptParam = parameters.get(actionName + ".noScript");
if (noScriptParam != null) {
return Constants.NO_SCRIPT;
}
return invocation.invoke();
}
}
- 任何方式使AJAX调用Gmail API,而无需通过JS库
- 拖放文件上传无需AJAX,在前台同步
- AJAX下载后直接上传文件(无需存储)
- 使用 AJAX 获取 XML,然后将其解析为 JSON(无需服务器)
- j查询如何在加载了 load() 函数的页面上进行 POST/AJAX,而无需刷新页面
- 无需重新加载即可播放MySQL结果.AJAX 正在失败
- 无需ajax即可实时更改网页内容
- 使用ajax上传图像,无需使用表单
- 通过ajax和url更新页面,而无需重新加载页面(node.js)
- 使用Ajax插入Mysql表单php,无需重新加载页面
- JS/Ajax:抓取输入字段值,无需刷新或点击按钮
- AJAX文件上传/表单提交,无需jquery或iframes
- 未解决的 PHP 页面刷新而无需 Ajax
- 如何使用PHP和AJAX更新MySQL,而无需刷新页面
- 使用 jquery/ajax 加载页面中的页面,而无需刷新
- Ajax 发布到 httpost 操作方法,无需刷新特殊加载
- Ajax 查询,无需重新连接到数据库
- Struts2 在渐进增强后形成,无需 AJAX 即可工作
- 使用 Ajax 和 PHP 插入和更新页面而无需重新加载
- jQuery -通过单个请求提交多个表单,无需Ajax