Java Web - Create a dispatch Servlet to execute model's method

本篇主要是說明如何建立一個簡單的分派Servlet,來達到web.xml減少設定Servlet進入點的

目的。要達到這樣的目的,需要用到的技術為前端頁面useBean物件的建立(sessionScope)及

傳送至後端的方法名稱配合Java Reflection及Polymorphism。

一般來說,針對一個網頁如果有多個功能,可能會在各個頁面傳送至後端的程式設置各自的

進入點程式(Servlet),雖然可以以JSP來取代,但是JSP程式內夾雜著Java的寫法並不好維

護,也缺乏架構。因此在這邊我們會建立一個統一的分派Servlet來當作一個指揮的角色,

並透過所有後端程式的父類別(AbstractModel)做為型態,相對的子類別Model為實體來進行

相對應method的呼叫達到目的。

參考架構圖


前端片段程式

首先宣告一model實體並儲存在session內
  1. <c:remove var="execModel" scope="session"/>
  2. <jsp:useBean id="execModel" class="com.grid.action.EmployeeModel" scope="session"/>

這段程式主要為ExtJS的Store元件,撈取後端所組成的JSON Data,在此需設定好action的name

,如此一來才可以呼叫到model程式內對應的method。

  1. // create the Data Store
  2. var store = new Ext.data.Store({
  3. // load using HTTP
  4. url: "<%=request.getContextPath()%>/ActionServlet?action=composeGridData",
  5. // 此讀取器可以解析JSON DATA, 並轉換成Record. Record需定義其欄位名稱與型別
  6. reader: new Ext.data.JsonReader({
  7. root: 'rows',
  8. id: 'EmployeeID',
  9. totalRecords: 'totalRows'
  10. },rawDataFormat)
  11. });


後端程式 - ActionServlet

設定web.xml

  1. protected void action(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. response.setContentType("text/html; charset=UTF-8");
  3. response.setHeader("Cache-Control", "no-cache");
  4. response.setCharacterEncoding("UTF-8");
  5. AbstractModel model = (AbstractModel)request.getSession().getAttribute("execModel");
  6. model.setResponse(response);
  7. String action = request.getParameter("action");
  8. model.setAction(action);
  9. try {
  10. model.execute(request);
  11. } catch (NoSuchMethodException e) {
  12. // TODO Auto-generated catch block
  13. e.printStackTrace();
  14. } catch (SecurityException e) {
  15. // TODO Auto-generated catch block
  16. e.printStackTrace();
  17. }
  18. }

ActionServlet在doPost及doGet內共同呼叫一個action method,由於前端的程式可能會用Get或

POST方法,如上面的片段Store程式即是利用GET來傳值。

這時取得session內的model實體,並由父類別AbstractModel來設置相關的變數(response及

action),最後再呼叫execute method來進行下一步,即呼叫該支model內method的動作。

後端程式 - AbstractModel

這支程式為所有Model程式的父類別,定義為抽象類別
  1. public void execute(HttpServletRequest request) throws NoSuchMethodException, SecurityException{
  2. Class amodel = this.getClass();
  3. Method m = amodel.getDeclaredMethod(action, HttpServletRequest.class);
  4. try {
  5. m.invoke(this, request);
  6. } catch (IllegalAccessException e) {
  7. // TODO Auto-generated catch block
  8. e.printStackTrace();
  9. } catch (IllegalArgumentException e) {
  10. // TODO Auto-generated catch block
  11. e.printStackTrace();
  12. } catch (InvocationTargetException e) {
  13. // TODO Auto-generated catch block
  14. e.printStackTrace();
  15. }
  16. }

如上,this所代表的為EmployeeModel實體,再透過Java Reflection來呼叫action所設定的method

如下:

  1. public class EmployeeModel extends AbstractModel {
  2. public void composeGridData(HttpServletRequest request){
  3. ...
  4. ...
  5. outputResponse(jsonData.toString());
  6. }
  7. }

最後再透過AbstractModel內定義的outputResponse來進行response輸出
  1. public void outputResponse(String resp){
  2. System.out.println("Response Content:"+resp);
  3. try {
  4. getResponse().getWriter().println(resp);
  5. } catch (IOException e) {
  6. // TODO Auto-generated catch block
  7. e.printStackTrace();
  8. }
  9. }

留言