如何在AEM Servlet中读取OSGi配置值并实现排序返回
问题分析与解决方案
问题原因
你的Servlet执行到输出a1后停止,是因为调用property.get("Name1").toString()时触发了NullPointerException——OSGi配置元数据生成的属性键并非Java接口中的Name1,而是会自动转换为小写形式(如name1),用Name1作为键获取不到值,自然会抛出空指针异常,导致代码中断。
另外,直接使用ConfigurationAdmin读取配置并非AEM中获取OSGi服务配置的最佳实践,因为你已经封装了MyProjectServ服务,直接引用该服务会更简单、更安全。
解决方案一:修正ConfigurationAdmin的属性键名
如果你坚持使用ConfigurationAdmin,需要将属性键改为OSGi实际存储的名称(通常是方法名的小写):
@Override protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain"); PrintWriter writer = resp.getWriter(); try { Configuration config = MYPROJECT_CONFIG.getConfiguration(MY_PROJECT); Dictionary<String, Object> properties = config.getProperties(); writer.write("a1"); // 使用小写的键名获取配置值,增加空值判断避免空指针 String first = properties.get("name1") != null ? properties.get("name1").toString() : "Abhinay"; String second = properties.get("name2") != null ? properties.get("name2").toString() : "Pavan"; String third = properties.get("name3") != null ? properties.get("name3").toString() : "Ram"; writer.write("a2"); writer.write(first); writer.write("a3"); String[] names = {first, second, third}; Arrays.sort(names); // 正确输出数组内容,替代默认的数组对象toString() for (String name : names) { writer.write(name + " "); } } catch (Exception e) { // 添加异常捕获,便于排查问题 writer.write("Error: " + e.getMessage()); e.printStackTrace(); } }
解决方案二:直接引用MyProjectServ服务(推荐)
这是AEM中获取OSGi配置的标准方式,无需手动处理配置键名,直接通过服务调用获取值:
修正后的Servlet代码
package com.demo.training.core.servlets; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import javax.servlet.Servlet; import javax.servlet.ServletException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.demo.training.core.services.MyProjectServ; @Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Practice Servlet", "sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.paths=/bin/myproject", "sling.servlet.extensions=" + "txt" }) public class MyProjectServlet extends SlingAllMethodsServlet { private static final long serialVersionUID = 1L; // 直接引用你的OSGi服务 @Reference private MyProjectServ myProjectServ; @Override protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain"); PrintWriter writer = resp.getWriter(); try { // 从服务中直接获取配置值 String first = myProjectServ.getNAME1(); String second = myProjectServ.getNAME2(); String third = myProjectServ.getNAME3(); writer.write("a2"); writer.write(first); writer.write("a3"); String[] names = {first, second, third}; Arrays.sort(names); // 输出排序后的名称,用逗号分隔便于AJAX处理 writer.write(String.join(",", names)); } catch (Exception e) { writer.write("Error: " + e.getMessage()); e.printStackTrace(); } } }
补充说明
- 添加
resp.setContentType("text/plain")确保响应类型正确,避免AJAX解析问题 - 增加异常捕获,便于排查运行时错误
- 使用
String.join替代数组默认的toString(),输出更友好的字符串格式,方便前端AJAX处理
内容的提问来源于stack exchange,提问作者Abhinay up
相关产品推荐
相关产品推荐

