如何通过Sightly及JS获取Servlet返回的officeJson办公详情数据?
解决方案
先修正代码里的基础错误
你当前的Servlet代码有个拼写错误:request.setAtrribute应该是request.setAttribute——这个错误会导致officeDetail属性根本无法正确存入request,很大概率是你之前尝试失败的原因之一。修正后的Servlet代码:
request.setAttribute("officeDetail", officeJson); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(officeJson);
另外你提供的JSON示例存在语法问题:字符串值需要加双引号,内部对象的逗号也要正确闭合,修正后的标准JSON结构:
{ "officeSummary": { "officeName": "abc", "officeId": 124, "officeAddress": { "country": "us", "state": "niantic" }, "phoneNumber": "986542160" } }
在Sightly(HTL)中获取办公详情
Sightly可以直接读取request属性,但officeDetail是JSON字符串,需要先解析成可直接访问的对象,推荐两种方式:
方式1:用Java模型类解析(更规范)
- 写一个简单的Sling Model类,把JSON字符串转成Map对象:
package com.yourproject.models; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.SlingObject; import java.util.Map; @Model(adaptables = SlingHttpServletRequest.class) public class OfficeModel { private Map<String, Object> officeData; public OfficeModel(@SlingObject SlingHttpServletRequest request) { String officeJson = (String) request.getAttribute("officeDetail"); ObjectMapper mapper = new ObjectMapper(); try { officeData = mapper.readValue(officeJson, Map.class); } catch (Exception e) { e.printStackTrace(); } } public Map<String, Object> getOfficeData() { return officeData; } }
- 在HTL模板中引入这个模型,直接渲染数据:
<sly data-sly-use.officeModel="com.yourproject.models.OfficeModel"/> <div class="office-card"> <h2>${officeModel.officeData.officeSummary.officeName}</h2> <p>办公ID:${officeModel.officeData.officeSummary.officeId}</p> <p>地址:${officeModel.officeData.officeSummary.officeAddress.country} - ${officeModel.officeData.officeSummary.officeAddress.state}</p> <p>联系电话:${officeModel.officeData.officeSummary.phoneNumber}</p> </div>
方式2:直接在HTL中注入JSON(快速方案)
如果不想写Java类,也可以把JSON字符串直接注入到页面,后续用JS解析,但这种方式适合需要前端处理的场景,服务器端渲染还是推荐方式1:
<sly data-sly-test.officeJson="${request.getAttribute('officeDetail')}"> <script> const officeData = JSON.parse('${officeJson @ context="scriptString"}'); // 这里可以直接写渲染逻辑,或者给外部JS用 </script> </sly>
@ context="scriptString"是HTL的安全处理,防止XSS攻击,必须加上。
在JS文件中访问officeJson并渲染到HTML
分两种场景处理:
场景1:Servlet是独立的JSON接口(AJAX请求)
如果你的Servlet专门用来返回JSON数据,前端可以通过fetch请求接口获取数据,再渲染到页面:
// 替换成你的Servlet实际URL fetch('/path/to/your-servlet') .then(res => res.json()) .then(data => { const container = document.getElementById('office-container'); container.innerHTML = ` <h3>${data.officeSummary.officeName}</h3> <p>ID: ${data.officeSummary.officeId}</p> <p>地址: ${data.officeSummary.officeAddress.country}, ${data.officeSummary.officeAddress.state}</p> <p>电话: ${data.officeSummary.phoneNumber}</p> `; }) .catch(err => console.log('获取数据失败:', err));
对应的HTML容器:
<div id="office-container"></div>
场景2:Servlet渲染页面时注入全局变量
如果你的Servlet是用来转发到HTL页面的,可以在HTL中把JSON注入为全局JS变量,外部JS直接访问:
- 在HTL模板中注入全局变量:
<sly data-sly-test.officeJson="${request.getAttribute('officeDetail')}"> <script> window.officeData = JSON.parse('${officeJson @ context="scriptString"}'); </script> </sly> <script src="/path/to/your-external-script.js"></script>
- 在外部JS文件中使用:
document.addEventListener('DOMContentLoaded', () => { if (!window.officeData) return; const container = document.getElementById('office-container'); const htmlContent = ` <h3>${window.officeData.officeSummary.officeName}</h3> <p>办公ID:${window.officeData.officeSummary.officeId}</p> <p>地址:${window.officeData.officeSummary.officeAddress.country} ${window.officeData.officeSummary.officeAddress.state}</p> <p>电话:${window.officeData.officeSummary.phoneNumber}</p> `; container.innerHTML = htmlContent; });
内容的提问来源于stack exchange,提问作者Abhinay Gidugu
相关产品推荐
相关产品推荐

