Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

AEM 6.3 Dispatcher Cache and SlingHttpServletRequest set/getAttribute()

Avatar

Level 3

I've seen posts about issues using an HttpSession object for setting/getting attributes with AEM.  Do those same issues apply to setting/getting attributes for a SlingHttpServletRequest?  One post (non-Adobe) mentioned it affected Dispatcher caching, but not sure how reliable the source was.  Another post mentioned receiving a new HttpSession on every request.

From a javax.servlet.Filter, we call slingHttpsServletRequest.setAttribute(), and from a Model class we call slingHttpServletRequest.getAttribute("key"), which is then accessed by HTL.

For instance, in the Filter:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

            throws IOException, ServletException {

        SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;

       slingRequest.setAttribute("key", stringData);

...

And in the Model:

@Model(adaptables = SlingHttpServletRequest.class)

public class MyModel {

    @Inject

    private SlingHttpServletRequest request;

    public String getMyData() {

        String myData = (String) request.getAttribute("key");

...

Everything works fine accessing both Author and Publish directly (and of course, on our developer Author sandboxes).  However, on Dispatcher, we don't see the attribute data.  We've cleared Dispatcher cache twice, and are preparing to dig into the logs.  But if there are known issues using request attributes, we can find another approach.  Thanks for taking the time to look at this, and any helpful advice you can offer is much appreciated.

-Nestor

1 Accepted Solution

Avatar

Correct answer by
Level 3

We did away with the Filter completely.  In the sling model class, we @Inject SlingHttpServletRequest, use a @PostConstruct method to start our custom logic.  Going to mark this complete as the scope of the question grew too large.  Thanks for providing ideas.

View solution in original post

6 Replies

Avatar

Level 4

If I could understand it correctly you are using this servlet(??) for Authenticated user? If yes please tell me then I can provide something.

one thing i believe is you cant cache the java object's data and with each request it will be refreshed.

Avatar

Level 3

Hi navinkaushal, thanks for replying.  Please let me know if you need additional details.

On Dispatcher, it's for anonymous users.  On Author and Publish, we must authenticate to access links.

We aren't using a servlet.  The filter already has access to the request and response.  A SlingModel injects a SlingHttpServletRequest into the model.  It uses that injected request to read an attribute set by the filter.

1. In Filter's doFilter() method, Filter calls slingHttpServletRequest.setAttribute("some_key", "some_string_value");

2. The SlingModel receives that same request, and obtains the value via slingHttpServletRequest.getAttribute("some_key");

So it's all occurring in the same request.  It works fine on Author and Publish, but fails on Dispatcher.

Avatar

Level 10

Each time the page loads - do you want the page or a cached version. If you configure Dispatcher properly - the page should load and the HTL components should still execute property.

Avatar

Level 3

Hi smacdonald2008 .  Thanks for your response.  Based on that, we updated our dispatcher.any file.  We set it for everything to go through uncached, and it works as expected, but that is obviously too extreme.

    /rules

        {

        /0000

          {

          # the globbing pattern to be compared against the url

          # example: *            -> everything

          #        : /foo/bar.*    -> only the /foo/bar documents

          #        : /foo/bar/*    -> all pages below /foo/bar

          #        : /foo/bar[./]* -> all pages below and /foo/bar itself

          #        : *.html        -> all .html files

          /glob "*"

          /type "deny"

          }

The htl code is in a partial named sample.html. This partial is reused in many other htl pages.  Here's the code it uses to access the data from the Model:

<sly data-sly-use.mymodel="com.somecompany.slingmodels.MyModel"

    data-sly-test="${mymodel.myData}">

Is there a more granular way to target only the htl-related code from being cached?  We have googled quite a bit and looked through dispatcher documentation but haven't found a solution yet.  Is there an attribute like a selector we can add to our Model's annotation, or somewhere in the htl, where we can target it within the dispatcher.any file?

Thanks for any additional advice you can offer.

Avatar

Correct answer by
Level 3

We did away with the Filter completely.  In the sling model class, we @Inject SlingHttpServletRequest, use a @PostConstruct method to start our custom logic.  Going to mark this complete as the scope of the question grew too large.  Thanks for providing ideas.

Avatar

Level 2

Hi @nesfel_aem ,

 

I am facing the same issue. Have you set the session Attribute in init() method of model class.

Please let me know how you have solved the above issue.

 

Thanks,