Dynamically add a servlet to the servletConfig

2020-02-10 05:25发布

问题:

I have a Java web application that uses a plugin architecture. I would like to know if anyone has a solution where by one could add a servlet, with serlvet mapping to the servletconfig while the web app is running? The idea being that a class could be added to the /WEB-INF/classes folder and be made active as a servlet without restarting the web app. By the same nature, if the user chooses to remove the "plugin" then have the code remove the class from the the servletconfig.

回答1:

There is no standard Servlet API to accomplish this.

You can do this in Tomcat. In your webapp, your master servlet (the one creates others) must implements ContainerServlet so you can get hold of the Wrapper object. Once you have your class file installed, you can make following calls,

Context context = (Context) wrapper.getParent();
Wrapper newWrapper = context.createWrapper();
newWrapper.setName(name);
newWrapper.setLoadOnStartup(1);
newWrapper.setServletClass(servletClass);
context.addChild(newWrapper);
context.addServletMapping(pattern, name);

These calls create a servlet on the fly. You need to find way to persist this information. You can do this by updating web.xml or write to your own file.



回答2:

Adding and removing classes to/from a running application is hard. You may want to look at JRebel for a commercial solution.

If your users don't have very long running conversations/sessions, possibly a restart of your Web app can be quick enough that they won't notice. If this will do it for you, then the problem becomes pretty easy.

Assuming you're running Tomcat, you can configure your server with reloadable=true and it will restart your app whenever you throw a new web.xml into the webapps directory. You can add new classes to the WEB-INF/classes directory and then update web.xml, that should work fine. Removing classes may be harder if those classes are in use. You may want to do a 2 step process where you first deploy a web.xml that no longer routes to a given servlet class, then wait a bit for class users to go away, and then delete the class and redeploy an updated web.xml again.



回答3:

I don't think you can do that dynamically, but you might try making the servlet active or inactive using a filter that's preconfigured. Make the filter check for a value that you can alter dynamically, in either a database or the file system, and tell it how to reroute the request if the servlet is "turned off."

I think it'd be rude to simply turn off a servlet without giving users some kind of feedback.