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.
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?
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.
how if i want use ResquestDispatcher in GiftSevice. Thank
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.