如果一个请求对应一个 Servlet 的话,工程大了, Servlet 的类就会很多,不方便管理。 虽然可以使用条件判断将多个请求处理写到一个 Servlet 类中,但这样代码太不美观。
Servlet 的请求是由 service 方法接收,然后再根据请求的类型转给 doGet 和 doPost 等方法。今天看到一种基于反射的写法:这种写法覆盖了 service 方法,在 Service 方法中利用 Java 反射的机制改变请求的转向。
贴代码:
package com.hack4b.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 封装 Servlet ,完成对任意用户的请求进行处理
*/
public class BaseServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = -1521560009181973222L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
//定义用户请求参数
String v =req.getParameter("v");
//定义响应的方法
Method method = null;
try {
//得到方法
method = this.getClass().getMethod(v, HttpServletRequest.class,HttpServletResponse.class);
} catch (NoSuchMethodException | SecurityException e) {
System.out.println("反射错误!程序已退出!");
e.printStackTrace();
return;
}
try {
//获取方法的执行结果
String result = (String)method.invoke(this,req,resp);
//处理结果
if(result!=null&&!result.trim().isEmpty()){
int index = result.indexOf(":");
String param = result.substring(0,index);
String path = result.substring(index+1);
if(param.equals("f")){
req.getRequestDispatcher(path).forward(req, resp);
}else if(param.equals("r")){
resp.sendRedirect(path);
}
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
System.out.println("方法执行失败!");
e.printStackTrace();
}
}
}
其他的Servlet就继承这个类,在访问 Servlet 的时候加上参数,例如: http://localhost:8080/users.do?v=queryId 其中, queryId 是继承上述代码的一个子类中的方法。
按照这么写的话,这样子实际上是使用 Java 的反射机制去调用了子类的方法。
于是我自写了一个 Demo , Demo 中由两个类,一个是 Base 基类,一个是继承 Base 的 Sub 派生类,然后再进行反射机制的调用,结果发现使用 Java 反射不能去调子类的方法。 抛出异常: java.lang.NoSuchMethodException: com.hack4b.test.Base.testSubMethod() 意思就是说找不到 Base 子类的方法。
我就纳闷了,,既然反射不能去调派生类的方法,那么那个用反射实现的 Servlet 怎么可以?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.