编写BaseServlet(整合各个功能的Servlet为一个UserServlet)时 遇到的关于反射的问题
首先:UserServlet继承BaseServlet
以下为UserServlet
@WebServlet("/userServlet/*") // 可以匹配类似 /userServlet/aa 或者/userServlet/bc这样的方法
public class UserServlet extends BaseServlet {
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
protected void bc(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("baseServlet的service方法被执行了... " +
"因为UserServlet里默认继承BaseServlet里的service方法");
//完成方法分发
//获取请求路径
String requestURI = req.getRequestURI();
System.out.println("requestURI = " + requestURI);
//获取方法名称
String reqMethod = requestURI.substring(requestURI.lastIndexOf("/") + 1);
System.out.println("reqMethod = " + reqMethod);
//3.获取方法对象Method
//3.获取方法对象Method
//谁调用我?我代表谁
System.out.println(this);//this是一个UserServlet的对象 UserServlet@4903d97e
try {
//获取方法
// 改之前
//Method method = this.getClass().getMethod(reqMethod, //HttpServletRequest.class, HttpServletResponse.class);
//改之后 (将getMethod改为getDeclaredMethod)
Method method = this.getClass().getDeclaredMethod(reqMethod, HttpServletRequest.class, HttpServletResponse.class);
//4.执行方法
//暴力反射
method.setAccessible(true);
method.invoke(this,req,resp);
} catch (NoSuchMethodException e) {
}
}
}
如果采用protected 的UserServlet里的aa方法和bc方法 会出现以下错误 ,说是没有这个aa方法
于是选择将
this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
改为
this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
这个方法 可以暴力反射 获取对应的方法(这里是aa方法)
getDeclaredMethod是一种忽略访问权限修饰符(忽略public protected private之类的)去获取方法的方式
这个方法似乎解决异常了 但是并不是最佳做法 因为这种情况下 如果aa方法是protected 或者private都可以被暴力反射而被获取到 容易造成后续的bug
因此选择用另一种方法
即将aa方法和bc方法都改为public的方法 并把getDeclaredMethod改回getMethod ,并且也不需要暴力反射的 method.setAccessible(true);
如下
//protected
public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
//protected
public void bc(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
就解决了