2010年6月25日 星期五

小型 Web Demo 專案

說明:
使用 serverlet/jsp/EL 與 MVC 模型, 完成一個抽象的 User Query 應用程式, 並能在
後端作查詢而完成簡單的 job 送出工作.

圖示: 前端- User 要求一個網頁

User
|
Form
|
web.xml
| (par1, par2)
-------------------------
| FormServlet | <----- Role: Controller
| parl, par2 |
--------------------------------
^ | |
| V |
-------- ---------
App. | Applist | <--Model | Form.jsp | view
txt -------- -----------



元件:
Servlet (FormServlet) 目的:
當作控制者, 平衡在 Model 與 View 元件之中, 將參數帶到 Model 並得到 Model 回傳值,當所有的回傳值都準備好了, 就可以給 View 用不同的方式去顯示值. 且 Servlet 不作任何
有關的處理, 相關的處理都交給 Model 層.

Model (AppList) 目的:
Model 就像一般的物件, 主要能提供像作些查詢, 運算等工作, 並能回傳值給 Controller

View (Form.jsp) 目的:
主要顯示值, 而 java 中用 jsp 來完成, 並可用 EL 來完成, 在 java 中要用 jstl.jar Jsp Standard Tag Library(JSTL).

目錄:
[root@t-ap188 Learn]# tree -L 4 .
.
|-- Form.jsp
|-- WEB-INF
| |-- classes
| | |-- controller
| | | |-- FormServlet.class
| | | `-- FormServlet.java
| | `-- model
| | |-- AppList.class
| | |-- AppList.java
| | |-- AutoDock4Handler.class
| | |-- AutoDock4Handler.java
| | |-- BlastHandler.class
| | |-- BlastHandler.java
| | |-- Handler.class
| | |-- Handler.java
| | |-- HandlerFactory.class
| | |-- HandlerFactory.java
| | |-- RHandler.class
| | `-- RHandler.java
| |-- lib
| | `-- jstl.jar
| `-- web.xml
|-- abc.jsp
|-- app.txt
`-- hello.jsp

程式碼:
Controller Package:
FormServlet.java
{{{
package controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.AppList;

/// bring the parameter and send modle then and finally send resutl to view

public class FormServlet extends HttpServlet {


private static final long serialVersionUID = 1111L;
public static final String SUCCESS_PAGE = "Form.jsp";

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException{

AppList list = new AppList("/opt/apache-tomcat-5.5.27/webapps/Learn/app.txt");
List appList = list.getApps();

req.setAttribute("appList", appList);
RequestDispatcher view = req.getRequestDispatcher(SUCCESS_PAGE);
view.forward(req, resp);
}
}
}}}
使用 doGet 接收參數, 並查出所有 application name, 在傳給 view 作顯示.



/// Model Package ////
*AppList.java
{{{
package model;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class AppList {

List app_list;

public AppList( String file_path ) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(
file_path) );
String app = null;
app_list = new ArrayList();
while ((app = br.readLine()) != null) {
app_list.add(app);
}
}

public List getApps() {
return app_list;
}
}

}}}


/////////// View Level ///////////
* Form.jsp
{{{
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>








}}}
其中會接收 appList 從 servlet 來, 並用 foreach 去取出值放到 app, 在顯示到html.


app.txt
{{{
AutoDock4
R
Blast
}}}

* web.xml
{{{





form_servlet
controller.FormServlet



form_servlet
/Form



}}}


整個文件說明:
1. 學到 Controller/Model/View 的關係建立在互相分工與連結, Controller 當成橋粱, Model 當成 POJO class, View 作 jsp / html 顯示作用.


2. web.xml 定義 servelet 的基本位置和目的.像 servelet mapping 和
使用者可以連結到 https://t-ap188.grid.sinica.edu.tw:8443/Learn/Form
url-pattern 是 /Form 給使用者作網址的,
servlet-class 是要作處理的 class 位置.
{{{

form_servlet
controller.FormServlet



form_servlet
/Form

}}}

3. 學到 java EL 網頁顯示功能, 使用 ${} 當參數, 會從 serverlet 接到 applist會作 app,
且 view 會用到大量 html tag, 如此才像 tag 方式.
{{{



}}}

4. Java web 程式的目錄架構有 WEB-INF.
有 classes lib web.xml
其中 classes 放自己寫的 class 或 servletclass,
而此處 classes 中有 controller 與 model 兩個 package.
而 lib 放程式碼 jar 檔案.

結論:
而這些主要目的是為了讓各層只專注在本身的語法,
概念, 邏輯. 以便為來程式能分層, 且這範例還點出好處, 為來只要在 app.txt
加入新的應用程式, 其它 code 部份不用更動就可完成任務.



//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
圖示: 後端- User 送出一個表格到呼叫底下流程
當使用者將 Request 傳到 abc.jsp

Request
|
---------------
| abc.jsp | <----- 處理者
| |
---------------
|
-----------------
| factor(工廠) | <--- 透過她來產生底下的應用程式處理單元
| |
-----------------
|
------------------
| handler | <----- Model
------------------
| | ......
---- --------
| R | | Blast | <---- Individual application porting to grid
---- ---------


說明: 當一個使用者送出所選擇要執行的應用程式後, 會被傳到 factor 去產生對應的工作
處理者 (RHandler, BlastHandler), 並回傳 Hndler 物件.


程式碼:
abc.jsp
{{{
<%@ page import="model.*"%>



<%
String appName = request.getParameter("appName");
try {
Handler h = HandlerFactory.newInstance(appName);
out.println(h.handle());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
out.println(e);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
out.println(e);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
out.println(e);
}
%>



}}}


HandlerFactor.java (使用 Reflecting 完成工作)
{{{
package model;

public class HandlerFactory {
@SuppressWarnings("unchecked")
public static Handler newInstance(String appName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class c = Class.forName("model." + appName + "Handler");
Handler h = (Handler)c.newInstance();
return h;
}

public static void main(String[] args){
try {
Handler h = HandlerFactory.newInstance(args[0]);
System.out.println(h.handle());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}}}


Handler.java
{{{
package model;

public interface Handler {
public String handle();
}

}}}

RHandler.java
{{{
package model;

public class RHandler implements Handler{

@Override
public String handle() {
// TODO Auto-generated method stub
return "Submit R job to VQS" ;
}

}
}}}







沒有留言:

張貼留言