Simple URL routing in Servlet

I have made a simple URL routing using servlet in Java. Using MainServlet as the front controller, then decide which service to call.

I have defined MainServlet.java as the Front controller, Service.java as the parent base of service, then GiftService.java for the actual service that will be carried out for action. MainServlet.java will be able to examine the URL, for example by the form of /Gift/send , it will call GiftService class and send method in the GiftService.java. Before that it calls the init method inside Service.java to transfer some instance that maybe used by the Services classes, such as HttpServletRequest, HttpServletResponse, and etc.

MainServlet.java

package com.fyhao.test;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MainServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String path = request.getPathInfo();
        try {
            String[] parts = path.split("/");
            if(parts.length >= 2) {
                try {
                    Class iClass = Class.forName("com.fyhao.test." + parts[1] + "Service");
                    Method init;
                    Constructor con;
                    Object myClass;
                    try {
                        init = iClass.getMethod("init", new Class[] {HttpServlet.class, HttpServletRequest.class, HttpServletResponse.class, String[].class});
                        con = iClass.getConstructor(new Class[] {});
                        myClass = con.newInstance(new Object[] {});
                        init.invoke(myClass, new Object[]{this, request, response, parts});
                    } catch (NoSuchMethodException ex) {
                        System.err.println("Please define init method on " + parts[1] + "Service");
                        return;
                    } catch (Exception ex) {
                        System.err.println("init exception");
                        return;
                    }
                    Method m;
                    if(parts.length >= 3) {
                        try {
                            m = iClass.getMethod(parts[2], null);
                            m.invoke(myClass);
                        } catch (NoSuchMethodException ex) {
                            try {
                                m = iClass.getMethod("main", null);
                                m.invoke(myClass);
                            } catch (Exception exc) {
                                System.err.println("Please define a main service method on " + parts[1] + "Service");
                                return;
                            }
                        } catch (Exception ex) {
                            System.err.println("service method exception");
                            return;
                        }
                    } else {
                        try {
                            m = iClass.getMethod("main", null);
                            m.invoke(myClass);
                        } catch (Exception exc) {
                            System.err.println("Please define a main service method on " + parts[1] + "Service");
                            return;
                        }
                    }
                } catch (ClassNotFoundException ex) {
                    defaultAction(request, response);
                }
            } else {
                defaultAction(request, response);
            }
        } catch (NullPointerException ex) {
            defaultAction(request, response);
            return;
        }
        //serviceclass("Gift", "send");
    }
    public void defaultAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("default action here: " + request.getPathInfo());
    }
    // leave for reference
    public void serviceclass(String c, String service) {
        try {
            Class iClass = Class.forName("com.fyhao.test." + c + "Service");
            Method init = iClass.getMethod("init", null);
            Method m = iClass.getMethod(service, null);
            Constructor con = iClass.getConstructor(new Class[] {});
            Object myClass = con.newInstance(new Object[] {});
            m.invoke(myClass);
        } catch( Exception ex) {}
    }
}

 

Service.java

package com.fyhao.test;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Service {

    HttpServlet servlet;
    HttpServletRequest request;
    HttpServletResponse response;
    String[] parts;
    public void init(HttpServlet servlet, HttpServletRequest request, HttpServletResponse response, String[] parts) {
        this.servlet = servlet;
        this.request = request;
        this.response = response;
        this.parts = parts;
    }
}

GiftService.java

package com.fyhao.test;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GiftService extends Service {

    public void main() {
        System.out.println("default main methods: ");
    }
    public void send() {
        System.out.println("sending");
    }
}

 

All right, this is the coding done by me during first learning of using java reflection API, which is the great API to directly find the class by the full name, and dynamically initializes and calling its methods. However, I think it would have other better ways of doing this. Please tell me if you know. Thanks.

Author: fyhao

Jebsen & Jessen Comms Singapore INTI University College Bsc (Hon) of Computer Science, Coventry University

4 thoughts on “Simple URL routing in Servlet”

  1. I’m trying implement same functional. But before use reflection and call Class.forName() i wont check rules in route Array/hashmap? so check if these url path valid and exists in application.
    Any sugestion how implement this?

  2. Hi.
    Yes, you can, store rules in Array / HashMap, which stores the URL Path request, and then your Controller class, for each entry. But most probably you still need Reflection to call the methods on Controller class.
    For example, this request path /gift/send?id=1
    You may still need to call Gift.send() dynamically. In Java, you store these rules like
    key: “/gift/send”
    value : “Gift.send”
    You then use Reflection to route the Gift class and its send method.

  3. You still can use RequestDispatcher on HttpServletRequest as usual.The GiftService object is constructed every times the new request come in and in its Parent Class Service has set local variable HttpServletRequest and HttpServletResponse.

Leave a Reply