Building your own lightweight Java MVC Web Framework

Jan 4th 2015 (updated Apr 3rd 2023)

javadev

Existing Model-View-Controller web frameworks such as Spring require a certain amount of time to get initially up and running. They can also come with their own restrictions, a learning curve and what could be considered software "bloat".

I want to be able to develop simple web applications quickly but retaining full control over the software.

With a bit of common sense, knowledge of servlets and the help of a templating language library this is quite easily possible.

The Setup

  1. Controller - Servlet which loads a view and pushes a model (Java object instance) onto it
  2. View - A template (a file with template references in it) ready to receive the model
  3. Model - a map of Java objects ready to be pushed onto the view

Controller

I created a servlet class with an abstract method returning a ModelAndView object (similar to spring). The ModelAndView object is a basic class which holds a string (path to the view file) and model (a Map<String, Object>). The servlet loads the file from the view path and along with the Model, puts it through a templating engine (I chose Apache Velocity) and writes the result back to the request.

I load the view file object from the WEB-INF directory using the ServletContext getResourceAsStream method:

InputStream inputStream = getServletContext().getResourceAsStream("/WEB-INF/" + resourcePath);

The implementing code of my abstract servlet class is responsible for providing the path to the file and the object to put onto it, using this I can load the view using the above code, get the model instance and run it through the VelocityEngine as such:

1
2
3
4
5
6
7
8
9
10
11
//Get the Writer from the response object to write the output to
PrintWriter out = response.getWriter();   
//Create velocty engine
Velocity.init();
VelocityContext context = new VelocityContext();
//Loop through the Model map and push the objects onto the velocity context
for (Map.Entry<String, Object> entry : model.entrySet()) {
     context.put(entry.getKey(), entry.getValue());
 }
//Process the template
Velocity.evaluate(context, out, "LOG", new InputStreamReader(inputStream));

The above code can be modified to adjust velocity to your needs, for example you may want to set the template directory so you can reference other velocity templates in your view. Due to velocity using $ symbols I couldn't use jQuery $ references when I wanted to, so I additionally processed the file to escape jQuery dollars before running it through Velocity it.

In theory you can use whatever templating engine you want, you could even mix them up in your application (thought this isn't recommended).

Once I had put it all together I ended up with an extendable class, allowing me to create MVC Java web applications quickly: VelocityModelViewServlet