【问题标题】:AEM - URL does not change with RequestDispatcher forwardAEM - URL 不会随着 RequestDispatcher 转发而改变
【发布时间】:2015-08-18 21:18:00
【问题描述】:

当我使用 RequestDispatcher 进行转发时.. 结果页面加载但 URL 没有改变。

我们开始向 PostServlet 提交数据的 URL:http://localhost:4502/content/en/postformtest.html

最终结果 URL 应为:http://localhost:4502/content/en/postformtestresult.html

但是是:http://localhost:4502/services/processFormData

我错过了什么?欣赏任何想法。

代码 sn-ps..

HTML 表单:

    <form name="userRegistrationForm" method="post" action="/services/processFormData">
<input type="submit" title="Submit" class="btn submit btn-success" value="Submit" tabindex="25" name="bttnAction">
</form>

POST Servlet

@SlingServlet(
label = "Common POST Servlet",
metatype = true,
methods = { "POST" },
name="com.commons.service.servlets.TPostServlet",
paths = { "/services/processFormData" }
)
public class TPostServlet extends SlingAllMethodsServlet{
@Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {

    final SlingHttpServletRequest syntheticRequest = new SyntheticSlingHttpServletGetRequest(request);
    final RequestDispatcherOptions options = new RequestDispatcherOptions();
    options.setReplaceSelectors("");
    options.setForceResourceType("cq/Page");

    request.getRequestDispatcher("/content/en/postformtestresult.html", options).forward(syntheticRequest, response);     
}    
}

包装器 Servlet:

public class SyntheticSlingHttpServletGetRequest extends      
SlingHttpServletRequestWrapper {
private static final String METHOD_GET = "GET";

public SyntheticSlingHttpServletGetRequest(final SlingHttpServletRequest request) {
    super(request);
}

@Override
public String getMethod() {
    return METHOD_GET;
}
}

【问题讨论】:

    标签: aem sling


    【解决方案1】:

    正如 RequestDispatcher 的 javadocs 所表明的那样,RequestDispatcher 和 forward 方法作为资源的包装器,本质上允许将进一步处理委托给资源。可以说这是在幕后完成的,因此请求的 URL 不会改变 - 它不是重定向。

    根据您的问题内容,​​我认为您要完成的是传统形式的 POST 到页面。这实际上是在 AEM 中实现的一种相当繁琐的模式,通过异步提交表单然后根据响应进行重定向,您很可能会得到更好的服务。

    如果您只需要在表单处理后进行简单的重定向,这可以通过调用响应的sendRedirect 方法来实现。

    但是,如果您确实需要 POST 到一个页面,然后该页面将同时处理表单处理和页面呈现,您可以使用类似于 OOB 表单组件的方法。 OOB com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet 被实现为 Servlet 和请求级过滤器。作为过滤器,它在处理之前捕获到 POST 请求到页面,使用 RequestDispatcher 将其转发到其 Servlet 特性,然后 Servlet 能够处理请求然后转发它,再次使用 RequestDispatcher,将请求包装为类似于您上面所做的 GET 请求后到页面。有点迂回,但如前所述,这是一个难以实现的模式。

    【讨论】:

    • 感谢您的详细解释。我试图实现的模式是 POST-REDIRECT-GET,我认为这种模式很少见,并且与 REST/Stateless 概念背道而驰。但我想试试是否有办法解决,如果 Adob​​e 的 OOB 组件肯定会使用。您可以发送示例实现或指向我的任何网址吗?我确实在 GitHub 中找到了该类的示例 github.com/ooyala/Ooyala-AdobeCQ/blob/…
    【解决方案2】:

    您看过 ACS Commons Forms 吗?他们确实支持 PRG 作为标准表单处理过程。查看http://adobe-consulting-services.github.io/acs-aem-commons/features/forms.html

    您最终可能会按原样使用该功能,或者会得到一些实施提示。

    相同的git链接是https://github.com/Adobe-Consulting-Services/acs-aem-commons

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      相关资源
      最近更新 更多