OSGI R6 servlet paths list property | Community
Skip to main content
Level 4
August 13, 2018
Solved

OSGI R6 servlet paths list property

  • August 13, 2018
  • 16 replies
  • 10864 views

I am trying to use multiple paths in servlet. I am able to achieve this using below syntax:

@Component(service=Servlet.class,

name="Sample Servlet",

property={

"sling.servlet.methods=" + HttpConstants.METHOD_POST,

"sling.servlet.paths="+ "/bin/path1",

"sling.servlet.paths="+ "/bin/path2"

})

Is there a way to improve above annotation so that I don't have to define paths multiple time.Instead I should be able to set it as a list or with REGEX pattern?

I tried below syntax but seems it is not working:

@Component(service=Servlet.class,

name="Sample Servlet",

property={

"sling.servlet.methods=" + HttpConstants.METHOD_POST,

"sling.servlet.paths="+ "/bin/path*"

})

@Component(service=Servlet.class,

name="Sample Servlet",

property={

"sling.servlet.methods=" + HttpConstants.METHOD_POST,

"sling.servlet.paths="+ "[/bin/path1,/bin/path2]"

})

Please share the various options for above.

Thanks,
Rajeev

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by joerghoh

You clearly need to separate the client-side part from the server-side part. On the client-side you need to know which endpoint to call in what situation, but this is the case for both approaches. In your case I even wonder if you need to have 2 distinct URLs, but you should be able to handle the details of the submission based on request parameters.

You need to map a servlet to a Sling resource via the sling:resourceType property. Then you don't need to hardcode any path in the servlet annotations itself.

I don't know if you can combine path-based bindings and selectors/extensions (haven't tried it). But you can always use URL parameters with path-based bindings (and cacheability isn't a topic here).

But still, I recommend to use resourcetype-based binding. Because then your form can be self-contained in a way, that

GET /.../form.html

will render the form, while

POST /.../form.submission

will invoke the handling of the form submission. When you build the form, you don't need to hardcode any knowledge about other functions (like the path to the submission servlet) into the form rendering logic. Also if you annotate the form which kind of submission you want to use, this can be easily determined by the submission servlet. In most cases this means that all settings regarding the form and the submission logic applying to this specific form instance can and should be made on the form itself. Without any duplication.

(Maybe I should do a blog post about it ...)

16 replies

Level 4
August 13, 2018

Does same holds true for sling.servlet.methods?? If want to define array of methods?

smacdonald2008
Level 10
August 13, 2018

I have never tried that. I would think so however - if you can define different paths - you should be able to define different sling.servlet.methods and then use both a GET or POST.

joerghoh
Adobe Employee
Adobe Employee
August 14, 2018

That's not possible.

Also please be aware that binding servlets to paths is not best practice. For me it seems that you want to react differently based on the actual path, and that's an excellent usecase for "bind a servlet to a resourcetype"! (best practice btw)

Imagine, that you want to bind your servlet to

/content/countryA/endpoint

/content/countryB/endpoint

/content/countryC/endpoint

Then just create "endpoint" as nt:unstructured nodes and add a property "sling:resourcetype" with the value "myapp/endpoint" (you probably can come up with a better name). Then bind your servlet to that resource type "myapp/endpoint" and voila, everything works. Within the servlet you can use "request.getResource()" to get the "/content/countryX/endpoint" resource and react accordingly. It's even dynamic and you can limit access with ACLs on a JCR level.

Without knowing more about your usecase, that's a perfect match.

Jörg

Level 4
August 14, 2018

Hi Jorg,

Below is the use case:

We have two identical forms  with slight differences. We want to call same servlet from both the forms. Both forms will use the common code in servlet and then will execute separate logic based on from which form the request was received. Eg. Form 1 might save data in cookie while form 2 may skip the logic of setting cookie.

Now in this case how can we map submit button click to servlet with resourcetype? I think path is the only option irrespective of whether the request is traditional form submission or ajax submission. Now if we use single path mapping in servlet then selectors and extensions can't be used as these are supported only for resourceTypes. Therefore we are trying to use different paths and then based on request path trying to execute separate logic.

joerghoh
Adobe Employee
joerghohAdobe EmployeeAccepted solution
Adobe Employee
August 15, 2018

You clearly need to separate the client-side part from the server-side part. On the client-side you need to know which endpoint to call in what situation, but this is the case for both approaches. In your case I even wonder if you need to have 2 distinct URLs, but you should be able to handle the details of the submission based on request parameters.

You need to map a servlet to a Sling resource via the sling:resourceType property. Then you don't need to hardcode any path in the servlet annotations itself.

I don't know if you can combine path-based bindings and selectors/extensions (haven't tried it). But you can always use URL parameters with path-based bindings (and cacheability isn't a topic here).

But still, I recommend to use resourcetype-based binding. Because then your form can be self-contained in a way, that

GET /.../form.html

will render the form, while

POST /.../form.submission

will invoke the handling of the form submission. When you build the form, you don't need to hardcode any knowledge about other functions (like the path to the submission servlet) into the form rendering logic. Also if you annotate the form which kind of submission you want to use, this can be easily determined by the submission servlet. In most cases this means that all settings regarding the form and the submission logic applying to this specific form instance can and should be made on the form itself. Without any duplication.

(Maybe I should do a blog post about it ...)

Level 4
August 15, 2018

Hey Jorge,

This was really helpful. Having a separate blog for these scenarios would be a nice idea. I guess there are many who agrees to resource type mapping but need some reference it blog with example for this kind of scenario.

Thanks,

Rajeev