2

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 translate 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?

4 Answers 4

2

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().

Sign up to request clarification or add additional context in comments.

2 Comments

The benefit of a filter is, that you can use it together with servlets that are not mapped by the front controller. Wicket uses this approach.
That would be a MVC "patch" to existing servlet based apps, not a fullfledged MVC framework.
2

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.

6 Comments

Pathinfo isn't available in filters.
pathinfo is available after casting ServletRequest to HttpServletRequest.
I didn't mean that :) It will always return null in filters.
Maybe I remember something wrong with casting here, but I've written a filter that dispatches requests based on the path.
For that normally request URI/URL is been used (and yes, from the downcasted HttpServletRequest).
|
0

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.

1 Comment

Oops, I forgot to mention that my code so far is implemented as a servlet.
0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.