如何在Ajax成功回调中设置Struts 2的<s:param>参数值?
问题根源与解决办法
兄弟,你遇到的这个问题其实是服务器端标签和客户端JavaScript执行时机不匹配导致的——Struts的<s:url>和<s:param>都是服务器端渲染的标签,它们在页面第一次加载的时候就已经被解析成对应的URL字符串了,而你的Ajax回调函数是在页面加载完成后,客户端浏览器里运行的,这时候Struts标签根本不会被重新解析,所以你把这些标签写在Ajax的success回调里,它们只会被当作普通的文本字符串输出,自然取不到json["fileName"]的值。
下面给你几个可行的解决方案:
方案一:客户端直接拼接URL
既然Struts标签只是帮你生成URL,那我们可以自己在JS里拼接这个URL。先提前用Struts标签渲染出基础的action路径,然后在Ajax回调里加上参数:
// 页面加载时先获取基础的action路径(服务器端渲染完成) var basePreviewUrl = '<s:url namespace="/mr" action="prevDasboard" />'; $.ajax({ url: "dataPp", type: 'POST', dataType : 'JSON', success: function (res) { table = $('table#dttable1').DataTable(); table.clear(); $.each(res.dokpp, function(i, item){ var json = res.dokpp[i]; // 拼接完整的预览URL,注意用encodeURIComponent处理参数避免特殊字符问题 var previewUrl = basePreviewUrl + '?file=' + encodeURIComponent(json["fileName"]); table.row.add( [ json["kodeDok"], json["fileNameUi"], json["depPenerbit"], json["createdDate"], json["tglBerlaku"], json["tglKadaluarsa"], json["urutRev"], '<a href="' + previewUrl + '" class="btn btn-default btn-xs">preview</a>' ]); console.log(json["fileName"]); }); table.draw(); } });
方案二:用模板替换占位符
如果想保留Struts生成URL的逻辑,可以在页面上提前准备一个带占位符的URL模板,然后在客户端替换参数:
首先在页面的某个位置(比如隐藏的script标签)定义模板:
<script id="previewUrlTemplate" type="text/template"> <s:url namespace="/mr" action="prevDasboard"> <s:param name="file">{fileNamePlaceholder}</s:param> </s:url> </script>
然后在Ajax回调里替换占位符:
$.ajax({ url: "dataPp", type: 'POST', dataType : 'JSON', success: function (res) { // 提前获取模板内容 var urlTemplate = $('#previewUrlTemplate').html(); table = $('table#dttable1').DataTable(); table.clear(); $.each(res.dokpp, function(i, item){ var json = res.dokpp[i]; // 替换占位符并处理参数编码 var previewUrl = urlTemplate.replace( '{fileNamePlaceholder}', encodeURIComponent(json["fileName"]) ); table.row.add( [ json["kodeDok"], json["fileNameUi"], json["depPenerbit"], json["createdDate"], json["tglBerlaku"], json["tglKadaluarsa"], json["urutRev"], '<a href="' + previewUrl + '" class="btn btn-default btn-xs">preview</a>' ]); console.log(json["fileName"]); }); table.draw(); } });
方案三:后端直接返回完整预览URL
如果你的后端Action可以修改,最省心的方式是在后端给每个dokpp对象生成好预览URL,前端直接拿来用就行。比如在后端的Java代码里:
// 假设你的Dokpp类新增一个previewUrl字段 for (Dokpp dok : dokppList) { // 用Struts的UrlHelper生成预览URL,或者直接拼接 String previewUrl = "/mr/prevDasboard?file=" + URLEncoder.encode(dok.getFileName(), "UTF-8"); dok.setPreviewUrl(previewUrl); } // 然后把dokppList返回给前端
前端代码就可以简化成:
$.ajax({ url: "dataPp", type: 'POST', dataType : 'JSON', success: function (res) { table = $('table#dttable1').DataTable(); table.clear(); $.each(res.dokpp, function(i, item){ var json = res.dokpp[i]; table.row.add( [ json["kodeDok"], json["fileNameUi"], json["depPenerbit"], json["createdDate"], json["tglBerlaku"], json["tglKadaluarsa"], json["urutRev"], '<a href="' + json["previewUrl"] + '" class="btn btn-default btn-xs">preview</a>' ]); console.log(json["fileName"]); }); table.draw(); } });
这三种方案都能解决你的问题,选哪种看你的项目场景和个人习惯就行~
内容的提问来源于stack exchange,提问作者amor - muammar
相关产品推荐
相关产品推荐

