JSP页面添加表格行按钮触发JS请求ChangeRepresentativeAction技术咨询
我来给你拆解这个请求流程,同时聊聊这个Struts2+原生JS组合里最容易踩的技术坑——毕竟我已经帮很多开发者排查过类似的问题了。
先理清楚完整请求链路
你的这套流程是典型的前端异步请求 + Struts2后端处理的组合,完整路径是:
- JSP页面点击按钮 → 触发JS脚本创建XHR对象
- JS通过
request.open("POST", "changeRepresentative.action", true)发起异步POST请求 - Struts2框架根据配置映射到
ChangeRepresentativeAction类 - Action类借助
ServletRequestAware/ServletResponseAware获取请求/响应对象,处理业务逻辑 - 处理完成后返回数据,JS接收响应并完成页面(表格新增行)的更新
常见技术问题与解决方案
1. 如何给Action传递表格行的参数?
如果要把新行的表单数据传给后端,需要按Struts2能解析的格式传递参数:
- 前端JS里拼接表单格式参数(适配Struts2默认参数解析规则):
// 从页面输入框获取新增行的参数,记得编码避免乱码 var repName = encodeURIComponent(document.getElementById("repName").value); var repId = encodeURIComponent(document.getElementById("repId").value); var formData = `repName=${repName}&repId=${repId}`; // 设置请求头,告诉后端参数格式 request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(formData);
- 后端Action类添加对应属性和getter/setter:
public class ChangeRepresentativeAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { private String repName; private String repId; // 必须生成getter和setter,Struts2才能自动注入参数 public String getRepName() { return repName; } public void setRepName(String repName) { this.repName = repName; } public String getRepId() { return repId; } public void setRepId(String repId) { this.repId = repId; } // 业务逻辑方法 @Override public String execute() throws Exception { // 这里可以直接使用repName、repId参数处理业务 return null; // 不需要跳转页面,直接返回数据给前端 } }
2. Action怎么返回数据给JS?
因为你实现了ServletResponseAware,可以直接往响应流写数据:
@Override public String execute() throws Exception { // 处理新增代表的业务逻辑,比如写入数据库 JSONObject result = new JSONObject(); result.put("status", "success"); result.put("msg", "代表新增成功"); // 设置响应格式和编码 response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(result.toString()); return null; // 不要返回Struts2的result跳转,直接输出响应 }
前端JS监听响应完成事件,更新表格:
request.onreadystatechange = function() { if (request.readyState === 4 && request.status === 200) { var res = JSON.parse(request.responseText); if (res.status === "success") { // 给表格新增一行 var table = document.getElementById("repTable"); var newRow = table.insertRow(); // 填充单元格内容 newRow.insertCell(0).textContent = document.getElementById("repName").value; newRow.insertCell(1).textContent = document.getElementById("repId").value; } } };
3. 请求报404错误怎么办?
这是最常见的问题,排查方向:
- 检查
struts.xml的Action配置是否正确:
<package name="default" namespace="/" extends="struts-default"> <action name="changeRepresentative" class="com.yourpackage.ChangeRepresentativeAction"> <!-- 因为是异步请求,不需要配置跳转页面的result --> </action> </package>
- 确认Action类的包路径和
struts.xml里的class属性完全一致 - 如果JSP页面不在项目根路径,要使用相对路径或者完整上下文路径,比如
request.open("POST", "${pageContext.request.contextPath}/changeRepresentative.action", true)
4. 中文乱码怎么解决?
- 前端用
encodeURIComponent编码参数(前面的示例已经覆盖) - 后端在
web.xml配置Struts2编码过滤器:
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
5. Action里的ServletRequest/ServletResponse是null?
因为你实现了ServletRequestAware/ServletResponseAware,但要确保Struts2的拦截器栈包含servletConfig拦截器——默认的defaultStack已经包含,如果你自定义了拦截器栈,必须手动添加:
<interceptor-stack name="customStack"> <interceptor-ref name="servletConfig"/> <interceptor-ref name="params"/> <interceptor-ref name="validation"/> <!-- 其他需要的拦截器 --> </interceptor-stack>
内容的提问来源于stack exchange,提问作者Dat Nguyen
相关产品推荐
相关产品推荐

