AEM自定义POST Servlet调用时getParameterMap返回空如何解决
问题根因
getParameter()、getParameterMap() 等方法仅能读取请求头Content-Type为application/x-www-form-urlencoded(表单提交默认格式)的参数。你当前前端提交的是application/json格式的JSON请求体,这类参数不会被Servlet容器解析到Parameter集合中,所以调用相关方法返回空/Null是正常现象,不需要新增额外的OSGi配置,修改代码即可解决。
修复方案
方案1:后端适配JSON请求(推荐)
直接读取请求体的JSON字符串,反序列化为对象后取值,修改后的Servlet代码示例:
import com.google.gson.Gson; import org.apache.commons.lang3.StringUtils; 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 javax.servlet.Servlet; import java.io.IOException; import java.util.Map; @Component( service=Servlet.class, property={ Constants.SERVICE_DESCRIPTION + "=Custom Servlet", "sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.paths=" + "/apps/myapp/customServlet" } ) public class CustomServlet extends SlingAllMethodsServlet{ private static final Gson GSON = new Gson(); @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { // 读取JSON请求体 Map<String, Object> requestBody = GSON.fromJson(request.getReader(), Map.class); String foo = (String) requestBody.getOrDefault("foo", StringUtils.EMPTY); response.setStatus(SlingHttpServletResponse.SC_OK); response.setContentType("application/json;charset=UTF-8"); response.getWriter().print(GSON.toJson(Map.of("response message", foo))); } }
注意:AEM环境默认已内置Gson依赖,无需额外引入第三方包。
方案2:前端修改为表单格式提交(无需改后端)
如果不想修改后端代码,可以把前端请求的Content-Type改为application/x-www-form-urlencoded,并按表单格式拼接请求体:
修改后的postData方法示例:
async function postData(url, data){ // 拼接表单格式参数 const formData = new URLSearchParams(); Object.keys(data).forEach(key => formData.append(key, data[key])); const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formData }); return response.json(); }
补充安全建议
你当前直接在CSRF过滤中移除所有POST方法的校验存在安全风险,生产环境建议还原该配置,仅将你的自定义Servlet路径/apps/myapp/customServlet加入Adobe Granite CSRF Filter的Excluded Paths排除列表即可。
内容的提问来源于stack exchange,提问作者watopin
相关产品推荐
相关产品推荐

