I'm writing a very simple web framework using Java servlets for learning purposes. I've done this before in PHP, and it worked by consulting the request URI, then instantiating the appropriate class and method.
This worked fine in PHP, as one can do something like $c = new $x; $x->$y;
. I'm unsure however of how to tra开发者_如何学运维nslate this to Java, or even if this is an appropriate way to go about it.
So far, I've tried:
Router router = new Router(request.getPathInfo());
String className = router.route(); //returns com.example.controller.Foo
Class c = Class.forName(className);
Object x = c.newInstance();
Foo y = (Foo) x;
y.doSomething();
This seems fine for a couple of routes, but doesn't seem like it would scale well, nor would it allow for sourcing routes from a configuration file.
How should I make it work?
Get hold of actions in a Map<String, Action>
where the String
key represents less or more a combination of request method and request pathinfo. I've posted similar answer before here: Java Front Controller
You can fill such a map either statically (hardcoding all actions) or dynamically (convention over configuration, looking up classes in a certain package, or scanning the entire classpath for classes with a certain annotation or implementing a certain interface).
And just stick to Servlet. The Filter isn't there for. At highest use it to forward the request to the controller Servlet. In the Servlet, just implement HttpServlet#service()
.
I would use a Servlet Filter as Front Controller. The router would connect paths with request dispatchers. In the doFilter method you would convert ServletRequest to HttpServletRequest, extract the request path and match it against the registered mappings. The result of this mapping is a request dispatcher you would dispatch the request with.
In pseudo code:
doFilter(ServletRequest request, ServletResponse response) {
httpServletRequest = (HttpServletRequest) request;
path = httpServletRequest.getRequestURI();
dispatcher = router.getTarget(path);
dispatcher.dispatch(request, response);
}
Depending on your need the default routing mechanism of the Servlet API could be sufficient.
Not quite sure what you're after but you might want to take a look at Java servlets. Granted many web frameworks are abstracted above plain servlets, but it's a jolly good place to start learning about Java web apps if you ask me (which indirectly you did ;) )
Download the Java servlet specification here: Java Servlet Spec - it's quite interesting.
How should you make it work? However you want it to. If you're just doing it for learning purposes, whatever you do will be fine.
I would suggest having all your actions implement the same interface though (maybe extend Servlet) so that you don't have to compile in all different classes.
Then you can essentially do what you're doing, except that your cast to Foo
becomes a cast to Servlet
and then you don't have to have a special case for all your different classes.
You can then also load up the routes from configuration (maybe an XML file).
Essentially what you're doing is implemented by the Struts 1 framework so it might be worthwhile reading up on that (it's open-source so you can also look at the source if you want).
精彩评论