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
Related
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.
We are starting a new project using Spring MVC, and we would like to move away from annotation-driven request/url mapping. We wish to implement the following use case:
Use Case A
User enters a URL.
The request mapping handler retrieves a list of mappings (e.g. from the DB), and based on this dynamic list of mappings, it calls the relevant controller.
This is because we want to be able to do the following as well:
Use Case B
We want to load a new Controller (perhaps a new reports module) into the web app without having to redeploy or do a server restart.
We will map this new Controller to a URL and persist it somewhere (most likely the DB).
We would like the Controller to be registered in the Spring app context (managed by Spring).
We would then like to use this new Controller in the request mapping.
We've taken an initial look at the different ways we can implement this, but we are unsure of the best architecture/method to go about this route. A couple of questions:
For Use Case A, how do we implement this within the Spring MVC framework (or if it's possible)?
For Use Case B, is there a good framework or way to be able to do dynamically loading and registering of this for web applications? We've taken a cursory look at OSGI but it seems to be advisable for use in non-web applications.
For Use case A :
Instead of DB you can keep the url mappings in a property file and then use property place holder to initialize beans using xml configuration on context up. This way remaining inside the spring framework, you can avoid annotations.
For Use Case B :
Tomcat supports dynamic reloading of classes but that to of only non structural changes in class file. But this has memory leaks as well as it doesnt cleans up old instance of class loader rather it creates a new instance.
Its quite achievable using spring-mvc-router API.
Please check below link
url-action mapping & routing in Spring MVC 3.0
Here the URL can be configured to controller.method using .conf file, but this can be achievable using java configuration, and i haven't tried so far.
Also if xml configuration chosen, then check out the property 'autoReloadEnabled', but its not adviceable for production use.
Hope this helps!!!
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
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.
We've got some Pure Servlets (pure Java classes following the Servlet API, no framework) that we'd like to include in a project that relies heavily on the Spring Framework.
What's the best way of including these servlets in the project, when all the new code we're writing is making heavy use of Spring 3 features?
your servlet container can run multiple servlets, spring is just one of them. why not just include your servlets in the web.xml and see if it works? it should work. spring is not that intrusive, yet (but obviously it already intruded the minds of many developers)
If you declare servlets in the web.xml, alongside the Spring front controller, it most certainly will work.
You just have to be careful when you declare which URLs map to the servlets. If you send "/*" to the Spring front controller, none of your requests will reach your other servlets. Be specific about what you need to send to each one.
As you might know, servlets cannot be configured as Spring beans. If your question is about colloborating with spring beans from a servlet, do refer this thread and also this
Spring provides a couple of classes to make this bridging easier.
ServletForwardingController
Spring Controller implementation that
forwards to a named servlet, i.e. the
"servlet-name" in web.xml rather than
a URL path mapping. A target servlet
doesn't even need a "servlet-mapping"
in web.xml in the first place: A
"servlet" declaration is sufficient.
Useful to invoke an existing servlet
via Spring's dispatching
infrastructure, for example to apply
Spring HandlerInterceptors to its
requests.
ServletWrappingController
Spring Controller implementation that
wraps a servlet instance which it
manages internally. Such a wrapped
servlet is not known outside of this
controller; its entire lifecycle is
covered here (in contrast to
ServletForwardingController).