Enabling/disabling servlet in a way other than web.xml - java

i wonder if there's a way to enable or disable servlets (or at least mappings for servlets) other than web.xml. I have multiple kinds of servers which use the same web.xml (i can't change this) so this is why another way of enabling/disabling servlets would be useful.
Thanks,
Teo

You could use #WebServlet annotation with servlet 3.0 onwards, not sure if this will work for your requirement, please comment if this isn't the way you want to
#WebServlet("/hello")
public class HelloServlet extends HttpServlet {
// code code code
}

As far as i am aware there is no such thing as programmatic disabling of servlets other that the deployment descriptor.
The way that i would approach such an issue is the following:
-I would add an if statement in each of my servlets service() method that i would like to control access to such as:
if(MyCustomSecurity.isServletAccessible(request)){
//here is your code that you have right now
}else{
//redirect request to an error page maybe
}
-Create this method isServletAccessible() in MyCustomSecurity class that would return a boolean on weather the user is allowed to acceess the servlet or not

If you are using Tomcat 7.x / Servlet 3.0 you can programmatically add a servlet filter to dynamically enable/disable access to some of your servlets without touching your web.xml file nor your application code.

I'd just create a web filter that reads some kind of configuration and passes or redirects on specific, configured paths.
Another option is to block paths on security layer e.g. Spring Security (actually it uses something like described above).

what about creating a Filter (a class that implements javax.servlet.Filter), then in a xml or properties file or even in database, you can add the servlets' names that the user can access or can't access.

Related

Tomcat web.xml: restrict access to specific methods of a servlet

I'm running a web application under Tomcat server. Different servlets are configured using Tomcat's web.xml.
I'm looking for a convenient way to restrict access to specific METHODS of specific URLS so that only these METHODS can be accessed using an Authorization header while others can be accessed without any restriction.
For instance, for url http://localhost:8080/my/servlet1 - GET and OPTIONS can be accessed by any user, while POST and PUT must be authorized with a username and a password, but for url http://localhost:8080/my/servlet2- all methods are open.
How can I implement that?
Thanks
The most low level API that allows you to do all sorts of filtering based on the context of the HTTP request in the javax/servlet/Filter
You implement a filter class that can restrict on the basis of HTTP method and any other criteria you choose. You register the filter on your web.xml and you add rules for which paths it is filtering.
Here is an walk through on applying such a filter.
If you happen to be using more than just a naked Tomcat for your application and you are using Spring Boot on top of it you could use their flavor of filters. This is an example for that case.

Configuring servlet url-patterns without web.xml

I know this can be done in servlet 3.0 with the #Webservlet annotation where you just assign the url-patterns and not have to do any configurations within a web.xml. Is there a way to programmatically assign a servlets url-pattern for applications running servlet 2.5?
I am creating a library which multiple applications will depend on and trying to make it so each of these applications do not have to explicitly configure any servlet url mappings for the servlets in the library I am creating within their respective web.xml file.
Thanks,
Since the web.xml and #Webservlet are both mechanisms for the server to know where to route requests by examining the war, you would have to be able to manipulate the server if you wanted to do it in code. This is at least theoretically possible, since the server could offer for example a JMX endpoint for configuration or you could go directly into the innards of the server.
However while it might be possible, it would be a non-standard way and you would have to write different tricks for all the servers you want to support. That's not something you want to do.
Finally, if you're creating a library, why does it have servlets in it? It shouldn't be the responsibility of the library to create servlets or decide which urls they're assigned to.

Changing servlet location on Init()

Is it possible to change the init parameters so that the servlet is created at a different path? I need to create a servlet at a certain path. Furthermore, would it be possible to artificially pass the path inside the init parameters?
As already shown in other answers, the servlet mapping is not controlled by the servlet, therefore you can't change that from within a servlet instance.
However, you can work around this by introducing a level of indirection (something like a "dispatcher" servlet): map your servlet to a wildcard pattern (like /app/*) and inside your servlet decide the actual action based on the request url path: /app/X will trigger some X action, while /app/Y will trigger Y.
Lots of web frameworks will provide the full functionality out of the box: you can have a look at Spring MVC's DispatcherServlet and its HandlerMapping concept, for instance.
Servlets aren't created at a certain path. They are Java objects that the servlet container Java application creates. If you are running Tomcat, for example, your application will run from the /webapps directory. The most you can do is change the Tomcat configuration to run it from some other path, but you'll have to do this before actually starting the application.
Short answer - you can't change anything related to servlet path mapping in init, since servlet container has already read mapping from web.xml.
Longer answer - you may want to look at servlet loader in Tomcat for example, perhaps it's possible to either invoke it's methods through JMX or do something else.
If you just want to have several mappings and choose which one to serve depending on configuration - use Servlet Filter

Dynamically add classes to Guice through reflection

Is it possible with Guice (and even in Java in general) to iterate over all classes in a particular package and add them to Guice?
The underlying problem: I'd like to be able to route all traffic to /admin/* to a single servlet which redirects accordingly. Then I'd like to be able to just add servlets to the same package and have them get picked up automatically. E.g. If I navigate to /admin/showCompanyDetails, I'd like that to redirect to a servlet called showCompanyDetails.java in the admin package.
Furthermore, I'd like this to work in such a way that all I have to do to add further admin functions is to drop a new class into the admin package. I.e. No factory methods to update and no containers to add to.
So far, the closest I've come is to have the redirect servlet create a Guice injector with a module that contains all the admin servlets. But as I said, I'd like to avoid having to update a Guice module.
Also, I'd like this to be possible in AppEngine.
And I want a pony.
There are some possibilities:
Use Servlet 3 #WebServlet annotations on your servlet classes, so they get picked up by a Servlet 3 web container. Then you can use Guice to inject dependencies, see here for an example.
Use guice-automatic-injection to bind your servlet classes in your classpath (they must contain their path similar to Servlet 3 via annotations or provide an accessor for it). Then you can create a Guice servlet module which retrieves all those servlets from Guice and registers them as servlets to their provided paths.
Both ways may be usable in AppEngine, but I haven't got experience with it.
Getting a pony is easy if you use just Object as its base class ;p

Spring MVC REST : static files unaccessible because of url-pattern

My Spring Dispatcher servlet url-pattern is /* (as spring MVC REST suggests)
Now all the request are resolved by this Servlet. even CSS/JS/Images also get resolved and handled by servlet..
So, Spring MVC tries to find controller.. :(
How to bypass this? Is there any standard way out of this problem??
& Don't want to change url-pattern to /rest/* (so, other static resources get accessed by /css/ or /js etc.)
You can map your controllers to a smaller set of URLS (i.e. /app/*), and then rewrite the URLs that your users actually see so that they don't even know about. Have a look at the mvc-basic webapp sample, particularly web.xml and urlrewrite.xml to see how this is done.
Map the Spring dispatcher to some subsection of the URL space, and use Tuckey to rewrite URLs the user deals with.
http://www.example.org/app/controller/action -> http://www.example.org/controller/action
Just a heads-up update on this: the default rewrite configuration as defined in the Spring sample did not work out of the box for me. The rewrite rules for stylesheets, scripts, etc. were still processed to the /app/* rule, and subsequently handled by the DispatchServlet, which is not desirable.
I had to add the last="true" attribute to the styles/scripts/images rules to indicate that other rules should not apply, and I had to use the FreeMarker Spring URL macro in any CSS/JS include paths.
Just in case someone encounters the same problem.

Categories