3

Short version: How do I force the most matching on a servlet based on multiple selectors using Felix annotations for sling servlets?

I have a few servlets defined in an OSGI bundle. I'm using the org.apache.felix.scr.annotations.sling.SlingServlet annotations.

@SlingServlet(
   methods={GET},
   selectors {"v1"}
   ...
)
public class MyServlet extends SlingAllMethodsServlet {}

...

@SlingServlet(
   methods={GET},
   selectors {"v1","special"}
   ...
)
public class MySpecialServlet extends MyServlet {}

My problem is that I can not find a way to force MySpecialServlet to only handle requests when both selectors are present.

GET http://localhost/my/resource.v1.special.json

Sometimes it will handle requests for only the v1 selector.

GET http://localhost/my/resource.v1.json

It seems that after using posting a new jar through the felix webconsole, if I request the double selector resource.v1.special.json before any other resource, then MySpecialServlet will also continue to handle v1 only requests.

Is there a way I can force the more general servlet to handle the more general list of selectors using the current annotations? Am I missing some part annotation? I believe that this system might be using an older annotation. Perhaps it is worth migrating? I'm trying not to be too intrusive for this small task that I've been asked to do.

Bear with me if I've conflated parts of these technologies. I've just walked up to this problem and I'm still sorting it out. Please correct any misalignment of terms.

Marc
  • 415
  • 5
  • 16

1 Answers1

1

Register your MySpecialServlet by v1.special, like selectors = {"v1.special"}.

According to the documentation:

... The selectors must be configured as they would be specified in the URL that is as a list of dot-separated strings such as print.a4 ...

I understand that when registering the servlet by a list of selectors, Sling treats them individually (as within OR condition). So, in the case of registering your special servlet by selectors = {"v1","special"}, the doGet method will be called if you request:

  • http://localhost/my/resource.v1.special.json or
  • http://localhost/my/resource.special.json or
  • http://localhost/my/resource.v1.json
iusting
  • 7,850
  • 2
  • 22
  • 30
  • I could not find the part of the documentation that explicitly said that sling treats them as an OR condition. Does this mean that resource.v1.special.json and resource.special.v1.json are distinct? I have been looking at our code a bit more and it looks like someone is mangling the selectors in a Filter before we get to the resolution, so my problems can also be – Marc Apr 12 '18 at 16:33
  • I didn't mean that the DOC mentions the OR condition, rather that is something that we can verify ourself by running some tests. I've modified the response to make this clear. Sure, you can use a filter to preprocess the request, but strictly regarding the selector registration, I think you having "v1.special" (and "special.v1" if you are not sure about the order) would do the trick. – iusting Apr 13 '18 at 07:25
  • Yeah, the OR is what I had come to from my testing. Between unmangling the selectors in the filter and using "v1.special" I was able to get it to work. Whoever wrote the code I walked up to had made the assumption that the list was an AND. – Marc Apr 13 '18 at 14:47