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就可以實現多個請求處理。
部分資料來源網絡