1:基于注解的簡單MVC框架的實現
效果:1:用戶只需要定義一些普通的java類來做為M層,也就是STRUTS的action類,該類里包含1到 N個控制方法,每個方法需要的form數據,由注解@ActionForm聲明,根據聲明,每一個方法都可以同時被注入多個form類實例。(根據這一點,你可以將諸如hibarnate的entity對象作為一個form被注入到action的方法中去。省掉了form到orm實體對象的轉換過程。)
2:整個框架只需使用一個FILTER來作為web頁面和java程序傳輸數據的通道,所以上邊所謂的action實際上不用繼承任何類和實現任何接口,這樣為M層的控制帶來了很多方便。
3:整個系統的bean,包括上邊的action實例都用spring來管理,所以是否是單例還是多例都由你在spring里的配置來決定。
4:action方法的返回數據為一個IResultHandel類型的對象,這個對象在框架中有一系列默認的解決方法,包括JSON,頁面跳轉,excel等,當然,也可以自定義解決方法,只要實現這個接口,并定義兩個屬性一個data,一個view。前者是返回的數據,view是返回的頁面地址。使用這種方式的目的主要是利于單元測試,讓action方法更單純,更清晰一點。
5:說說整體流程,當頁面發送一個請求時,統一都交給一個FILTER對象來處理(注意整個框架就這一個filter對象),該對象根據請求地址,查找spring是否定義了對應的bean(也就是處理該請求的action),找到后,調用該bean的excute方法,在這個方法里,會查找請求上所對用的action參數,據此定位到bean里的對應方法上,再查找該方法是否含有AcationForm注解信息。如果有則根據注解聲明的form類,創建對應的實例,迭代查找實例含有的屬性,依據屬性名稱,獲取對應request參數值,再依據屬性的類型,綁定屬性編輯器,將request參數值轉換為對應的屬性值,以達到form注入的效果。如果action方法沒有聲明actionform,則直接執行方法,并返回IResultHandel。
以上就是一個簡單的mvc的框架的實現原理,他的目的是解決一個action方法注入多個form對象,和利于單元測試。
2:jquery,prototype,ajax傳輸亂碼問題的一點解決方法。
在上邊的框架,我解決ajax亂碼的過程是這樣的,在js中先用encodeURL給傳遞的參數編碼。如下
jquery: $.post(url, encodeURI(queryString),result,"text");
prototype: var myAjax = new Ajax.Request(
url,
{
method: 'post',
parameters: encodeURI($H(pars).toQueryString()),
onComplete: showResponse
});
在框架中,定義了一個@decode注解,這個注解可以在方法,屬性上聲明。在action方法上聲明時表示:該方法所注入的form對象需要解一次碼。其中@decode(index=“10”)表示第一個form需要解碼,第二個不需要,(index值,1表示需要解碼,0表示不需要。由index的位數來決定第幾個form需要解碼。)
在set方法或屬性上使用的時候,表示該類在需要解碼的時候僅這些字段或方法可以需要解碼,其它則沒必要。
解碼的函數很簡單。使用URLDecoder.decode(str, "utf-8");就可以,注意:URLDecoder一定是java.net包下的方可。
在有java返回給ajax 的時候,需要設置response.setContentType("text/html;charset=GBK");語句方可解決非utf-8編碼時產生的亂碼,這個時候最好朝前面的方法寫,若使用response.setCharacterEncoding("gbk"),一般還是會出現問題。
參看我的一個測試action代碼:其中JsonTool為我編寫的一個json處理工具,可以自動的將集合,數組,map,普通pojo自動轉換為json表達方式。
package com.sam.sammobiletest.action;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sam.jsontool.util.JSONTool;
import com.sam.sammobile.annotation.ActionForm;
import com.sam.sammobile.annotation.Decode;
import com.sam.sammobile.result.handle.ExcelResultHandle;
import com.sam.sammobile.result.handle.MyJsonHandler;
import com.sam.sammobile.result.handle.Query6ResultHandler;


/** *//**
* 測試 sammobile框架。 必須的一個屬性: action 指定action的方法名稱
* decode注解的含義,如果方法上含有decode注解,則表示該方法的表單對象需要進行屬性解碼
* 如果decode中制定了index的值,該值為01代碼,其中每一位數字對應表單數組中的對應表單
* (一個控制方法上可能需要注入多個表單,所有構成了表單數組)。其中,0表示無需解碼,1:表示解碼
*
*
*
*/

public class TestAction
{
protected static final Log logger = LogFactory.getLog(TestAction.class);


/** *//**
* 單beanz注入測試 不解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@ActionForm(TestForm.class)
public Object query(Object forms, HttpServletRequest request,

HttpServletResponse response)
{
TestForm form = (TestForm) forms;

System.out.println(form.getName());
System.out.println(form.getDate());
System.out.println(form.getAge());
MyJsonHandler handler = new MyJsonHandler(form);
return handler;
}


/** *//**
* 多bean注入測試 都解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@Decode()

@ActionForm(
{ TestForm.class, TestForm2.class })
public Object queryTwo(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
TestForm form = (TestForm) forms[0];
TestForm2 form2 = (TestForm2) forms[1];
System.out.println(form.getName());
System.out.println(form.getAge());
System.out.println(form2.getAddress());
System.out.println(form2.getTestDate());
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("form1", form);
map.put("form2", form2);
String json = JSONTool.toJSON((Object) map);
return new MyJsonHandler((Object) map);
}


/** *//**
* 多bean注入測試 都解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@Decode(index = "11")

@ActionForm(
{ TestForm.class, TestForm2.class })
public Object query11(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
return queryTwo(forms, request, response);
}


/** *//**
* 多bean注入測試 第二個解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@Decode(index = "01")

@ActionForm(
{TestForm.class,TestForm2.class})
public Object query01(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
return queryTwo(forms, request, response);
}


/** *//**
* 多bean注入測試 第一個bean解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@Decode(index = "10")

@ActionForm(
{ TestForm.class, TestForm2.class })
public Object query10(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
return queryTwo(forms, request, response);
}


/** *//**
* 多bean注入測試 不注解的樣式
*
* @param forms
* @param request
* @param response
* @return
*/

@ActionForm(
{ TestForm.class, TestForm2.class })
public Object queryNo(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
return queryTwo(forms, request, response);
}


/** *//**
* 多bean注入測試 不解碼
*
* @param forms
* @param request
* @param response
* @return
*/
@Decode(index = "00")

@ActionForm(
{ TestForm.class, TestForm2.class })
public Object query00(Object[] forms, HttpServletRequest request,

HttpServletResponse response)
{
return queryTwo(forms, request, response);
}


/** *//**
* 測試頁面跳轉,利用了 query6的跳轉方式
*
* @param forms
* @param request
* @param response
* @return
*/
public Object gotoURL(Object forms, HttpServletRequest request,

HttpServletResponse response)
{
Query6ResultHandler handler = new Query6ResultHandler();
Object obj = new HashMap();
handler.setResultData(obj);
handler.setView("pages/"+request.getParameter("path"));
return handler;
}


/** *//**
* 測試導出數據,這個處理器還需優化。感覺action代碼太繁瑣。
*
* @param forms
* @param request
* @param response
* @return
*/
@ActionForm(TestForm.class)
public Object toExcel(Object forms, HttpServletRequest request,

HttpServletResponse response)
{
TestForm form = (TestForm) forms;
HashMap<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("fileName", "testdata");

String[] title =
{ "輸入表單", "姓名", "日期", "年紀" };
hashMap.put("title", title);
Object[][] data = new Object[1][3];
data[0][0] = form.getName();
data[0][1] = form.getDate();
data[0][2] = form.getAge();
hashMap.put("data", data);
ExcelResultHandle resultHandle = new ExcelResultHandle();
resultHandle.setResultData(hashMap);
return resultHandle;
}
}
