要实现的效果。
浏览器输入 http://localhost:8080/TestServlet/login?username=zs&password=123 可以调用 TestServlet 类的 login 方法,并传参数。
基本步骤。
通过链接拿到 login 字段。
获取 servlet 的 login 反射方法。
获取反射方法的参数。
获取反射方法的返回值。
注意,反射方法获取参数名默认是 arg1,arg2…。在Preferences -> Build… -> Compiler -> Java Compiler -> Additional command line parameters 加入 -parameters,删除 out 文件夹,重新编译,才会拿到实际参数名。
// const 工具类
public interface ConstUtils {
String HTTP_SERVLET_REQUEST = "HttpServletRequest";
String HTTP_SERVLET_RESPONSE = "HttpServletResponse";
String INTEGER = "Integer";
String Double = "Double";
String FORWARD = "forward";
String REDIRECT = "redirect";
}
// Servlet 工具类,父类
public class DispatcherServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String actionName = getActionNameByServletRequest(request.getRequestURI());
if (!StringUtils.isEmpty(actionName)) {
// 找到 action 方法
Method method = getActionMethodByActionName(actionName);
Object[] args = actionMethodParam(method, request, response);
if (method != null) {
try {
Object invoke = method.invoke(this, args);
// 处理返回值
responseClient(invoke.toString(), request, response);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else {
System.out.println("没有定义【" + actionName + "】方法");
}
} else {
System.out.println("没写action");
}
}
// 获取反射方法的返回值。
private void responseClient(String result, HttpServletRequest request, HttpServletResponse response) {
String[] split = result.split(":");
String type = split[0];
String page = split[1];
if (ConstUtils.FORWARD.equals(type)) {
try {
request.getRequestDispatcher( request.getContextPath() + "/" + page).forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else if (ConstUtils.REDIRECT.equals(type)){
try {
response.sendRedirect(request.getContextPath() + "/" + page);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 获取反射方法的参数。
private Object[] actionMethodParam(Method method, HttpServletRequest request, HttpServletResponse response) {
Object[] args = new Object[method.getParameterCount()];
// 获取反射方法的所有参数
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
Object value = null;
if ("HttpServletRequest".equals(parameter.getType().getSimpleName())) {
value = request;
} else if ("HttpServletResponse".equals(parameter.getType().getSimpleName())) {
value = response;
} else {
// 获取链接value; ?key=value
value = parameterType(request.getParameter(parameter.getName()), parameter.getType());
if (value == null || "".equals(value)) {
// 是对象
try {
Class paraClass = parameter.getType();
Object instance = paraClass.newInstance();
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for(String key: keySet) {
try {
Field field = paraClass.getDeclaredField(key);
field.setAccessible(true);
// 获取属性类型名
String type = field.getType().getSimpleName();
if ("String".equals(type)) {
field.set(instance,parameterMap.get(key)[0]);
} else if("Integer".equals(type)){
field.set(instance,Integer.parseInt(parameterMap.get(key)[0]));
} else if ("Date".equals(type)) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
Date cDate = format.parse(parameterMap.get(key)[0]);
field.set(instance,cDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
value = instance;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
args[i] = value;
}
return args;
}
// 反射方法的参数类型
private Object parameterType(String parameter, Class<?> type) {
Object value = parameter;
if (type.getSimpleName().equals("Integer")) {
value = Integer.parseInt(parameter);
} else if (type.getSimpleName().equals("Double")) {
value = Double.parseDouble(parameter);
}
return value;
}
// 获得方法名
private String getActionNameByServletRequest(String requestURI) {
return requestURI.substring(requestURI.lastIndexOf("/") + 1);
}
// 获得反射方法
private Method getActionMethodByActionName(String actionName) {
// 获取当前类中的所有方法
Method[] methods = this.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(actionName)) {
return methods[i];
}
}
return null;
}
}
// 测试类
@WebServlet("/TestServlet/*")
public class TestServlet extends DispatcherServlet {
public void test() {
System.out.println("TestServlet.test");
}
public void login(String username, String password) {
System.out.println("username = " + username + ", password = " + password);
}
public void addEmp(Emp emp) {
System.out.println("emp = " + emp);
}
public void test2(HttpServletRequest req, HttpServletResponse res) {
System.out.println("req = " + req + ", res = " + res);
}
public String test3(Double price) {
System.out.println("price = " + price);
return ConstUtils.FORWARD + ":addUser.jsp";
}
public String test4() {
System.out.println("test4");
return ConstUtils.REDIRECT + ":addUser.jsp";
}
}
// 测试链接
http://localhost:8080/TestServlet/test
http://localhost:8080/TestServlet/login?username=zs&password=123
http://localhost:8080/TestServlet/addEmp?username=zs&password=123&age=13
http://localhost:8080/TestServlet/test2
http://localhost:8080/TestServlet/test3?price=27.4
http://localhost:8080/TestServlet/test4