BaseServlet
一個請求寫一個Servlet太過復雜和麻煩,我們希望在一個Servlet中可以有多個處理請求的方法。
客戶端發送請求時,必須給出一個參數,用來說明要調用的方法
方法的結構和service()方法的結構一樣
初始版
當我們訪問Servlet時,發生了那些操作?
首先是通過<url-pattern>找到<servlet-name>,通過<serlvet-name>最終找到<servlet-class>,也就是類名,在通過反射得到Serlvet對象。
再由tomcat調用init()、service()、destroy()方法,這一過程是Servlet的生命周期。在HttpServlet里有個service()的重載方法。ServletRequest、ServletResponse經過service(ServletRequest req,ServletResponse resp)方法轉換成Http格式的。再在service(HttpServletRequest req,HttpServletResponse resp)中調用doGet()或者doPost()方法。
路徑:http://localhost:8080/baseservlet/base?method=addUser
public class BaseServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getParameter("method");//獲取要調用的方法,其中的value="method"是自己約定的
if("addUser".equals(method)){
addUser(req,resp);
}
if("deleteUser".equals(method)){
deleteUser();
}
}
private void deleteUser() {
System.out.println("deleteUser()");
}
private void addUser(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("add()");
}
}
改進版
很顯然,上面的代碼不是我們想要的。
public class BaseServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("method");//獲取方法名
if(name == null || name.isEmpty()){
throw new RuntimeException("沒有傳遞method參數,請給出你想調用的方法");
}
Class c = this.getClass();//獲得當前類的Class對象
Method method = null;
try {
//獲得Method對象
method = c.getMethod(name, HttpServletRequest.class,HttpServletResponse.class);
} catch (Exception e) {
throw new RuntimeException("沒有找到"+name+"方法,請檢查該方法是否存在");
}
try {
method.invoke(this, req,resp);//反射調用方法
} catch (Exception e) {
System.out.println("你調用的方法"+name+",內部發生了異常");
throw new RuntimeException(e);
}
}
}
在項目中,用一個Servlet繼承該BaseServlet就可以實現多個請求處理。
部分資料來源網絡
