Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

SOLVED

Binding a servlet to a custom configured path

bandersen_hoodoo
Level 1
Level 1

Hi there,

 

I was wondering what best practice would be to bind a servlet to a custom path based on a config. This servlet is an API endpoint, so selectors won't help us too much. For example, I have a servlet at /bin/foo/files, and I'd like to be able to configure that path to be at /bin/bar/files, or even /bar/files, based on an OSGi config or something similar with the path inside.

1 Accepted Solution
Jörg_Hoh
Correct answer by
Employee
Employee

The best way is still to avoid hardcoding the path in a servlet. I would suggest another approach:

  1. Create sling resource type my/application/api/endpoint1
  2. Write a servlet which handles the POST/GET/... request to that resource type
  3. Build a template which uses my/application/api/endpoint1 as resourcetype OR
  4. Build a component which uses my/application/apo/endpoint as a resourcetype.
  5. Then create a page based  on that template or drop the component into a page.

 

Then you can create, remove, update, duplicate, ... this API endpoint during runtime. You can define ACLs on it (if you require the users of this API to authenticate). You don't need to reconfigure anything on OSGI level.

And you can even create a new "content tree" below /endpoints (who says, that pages can only reside below /content?)

 

View solution in original post

9 Replies
BrianKasingli
Community Advisor
Community Advisor

@bandersen_hoodoo,

I don't think there's an out of a box way to dynamically set the path of your servlet, however, a solution you can try is to utilise and configure Apache rewrite rules for your use case, PT flag. Have a look at this article, which explains the solution more in detail. 

https://sourcedcode.com/sugar-coating-servlet-scripts-and-paths

Example:

 

RewriteRule ^/api/files$ /bin/bar/files [PT,L]

 

With the example above, when you visit https://my-site/api/files, you will be internally passed through to serve the servlet that has been registered.

 

 

bandersen_hoodoo
Level 1
Level 1
Unfortunately our servlet isn't front-end facing, so a dispatcher isn't used. It's purely an author API.
BrianKasingli
Community Advisor
Community Advisor
Why are you trying to dynamically change the servlet path?
bandersen_hoodoo
Level 1
Level 1
We'd like the user of our API to be able to set the path elsewhere in case they don't have access to /bin/ or are expecting a specific path on AEM's side that isn't the default.
BrianKasingli
Community Advisor
Community Advisor
Why would you like your authors control the path of the servlet? What benefits would this provide to the authors?
BrianKasingli
Community Advisor
Community Advisor
/bin is An allowed path from the out of the box. For example if you write an custom management page that interacts with the JCR via Servlet.
Nikhil-Kumar
Community Advisor
Community Advisor

@bandersen_hoodoo 

You can try getting it from the query param in servlet as request parameter and then assign it to some servlet's varialble locally.
Then while defining the path for the servlet in Java, get this values as <Classname>.<vriableName>

String path;

path = request.getParameter("path");

"sling.servlet.paths="+<ClassName>.<path>




Arun_Patidar
Community Advisor
Community Advisor

Why dont you use AEM servlet as proxy servlet and use selector?

Jörg_Hoh
Correct answer by
Employee
Employee

The best way is still to avoid hardcoding the path in a servlet. I would suggest another approach:

  1. Create sling resource type my/application/api/endpoint1
  2. Write a servlet which handles the POST/GET/... request to that resource type
  3. Build a template which uses my/application/api/endpoint1 as resourcetype OR
  4. Build a component which uses my/application/apo/endpoint as a resourcetype.
  5. Then create a page based  on that template or drop the component into a page.

 

Then you can create, remove, update, duplicate, ... this API endpoint during runtime. You can define ACLs on it (if you require the users of this API to authenticate). You don't need to reconfigure anything on OSGI level.

And you can even create a new "content tree" below /endpoints (who says, that pages can only reside below /content?)

 

View solution in original post