在Spring MVC应用程序中,我们有一个在调用JSP之前执行的Controller。 Controller将从数据库中预取一些值并在模型中设置它们并将控制转发给JSP。
如何在CQ 5中实现此功能?我希望在执行JSP之前执行SlingFilter。 JSP不是页面组件,而是侧面踢出的组件。
注意:
我可以通过编写自己的SlingSerlvet来做到这一点,它可以预取我需要的值并使用RequestDispatcher转发到JSP。 但是通过这种方法,我必须通过一个像" / bin /.*"这样的URL。 这又是一个页面级别我想在组件级别上使用这种功能。
答案 0 :(得分:1)
因此,要回答您的具体问题,如果您希望在调用组件之前执行过滤器,则会创建一个侦听组件级过滤器范围的过滤器。
请参阅 http://sling.apache.org/documentation/the-sling-engine/filters.html
然后,您的过滤器会将传入请求更改为SlingServletRequest,并确定目标资源是否是您要查找的资源。
但是,此过滤器将在页面上包含的每个组件上执行。可能对您有用的相反过程是ResourceDecorator。
http://sling.apache.org/documentation/the-sling-engine/wrap-or-decorate-resources.html
在servlet和过滤器调用之前识别资源时执行这些操作,这将允许您验证资源是否是您感兴趣的类型,然后允许您向资源对象添加其他信息。然而,这又是一个将应用于所识别的每个资源的服务。
但是,如果您要查找的是仅针对特定路径执行的过滤器,则为no。吊索并没有这样做。您提到Spring MVC和Spring MVC的工作原理完全不同于MVC的概念,然后是Slings版本的MVC。
修改强>
因此,在传统的Web应用程序中,servlet将处于固定位置,并且在调用该servlet之前应用所有过滤器。在Sling中,您可以动态地将servlet连接在一起以生成结果页面。因此,每次进入servlet并直接或间接调用请求调度程序时,它都会再次执行解析过程并在执行新servlet之前再次应用一系列过滤器 。
为了防止需要仅应用于每个内部调度上应用的主请求的高级过滤器,他们想出了上下文或在不同时间应用并与不同类型相关联的过滤器链包括。
这是一个基本过滤器,可以在消息被调用时记录消息。我是从记忆中做到这一点的,所以你需要用它来处理它。
@SlingFilter(scope = SlingFilterScope.COMPONENT, order = Integer.MIN_VALUE)
public class SampleFilter implements Filter {
private static final Logger LOG = LoggerFactory.getLogger(SampleFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
Resource res = slingRequest.getResource();
if (!(res == null || ResourceUtil.isNonExistingResource(res))) {
LOG.error("this servlet is called before resource {} at path {}", res.getName(),res.getPath());
}
chain.doFilter(request, response);
}
}
这一点的重要部分是 scope = SlingFilterScope.COMPONENT 看看我之前列出的页面并尝试不同的slignfilterscope组合,你就会看到它是怎样的'在不同的时间应用。 scope = SlingFilterScope.REQUEST 将在每页的基础上处于最高级别。
答案 1 :(得分:1)
就过滤器而言,JE Bailey的答案是正确的,但我怀疑你的问题可能会以更好地符合Sling世界观的不同方式解决。
Sling促进了OSGi服务用于业务逻辑,脚本应该是一个薄层。建议您将逻辑移至OSGi服务并从脚本中调用这些服务。
您可能还需要查看Sling Models,其中包括处理步骤(使用@PostConstruct
),然后才能启动渲染脚本。
答案 2 :(得分:0)
但是通过这种方法,我必须浏览类似"
/bin/.*
"的网址。
您还可以针对资源类型以及路径(例如,路径)注册servlet。 (from the Sling documentation):
@SlingServlet(
resourceTypes = "sling/servlet/default",
selectors = "hello",
extensions = "html",
methods = "GET")
public class MyServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
...
}
}
如果您删除"选择器","扩展程序"和"方法"注释上的参数,这个servlet将绑定对sling/servlet/default
的所有调用,而不需要绑定设置路径。