用注解和pojo支撐起來的輕量級REST框架--T2

openkk 12年前發布 | 42K 次閱讀 REST Web框架

 

用注解和pojo支撐起來的輕量級REST框架--T2

Written by Tony@tokyo

 

1.    前言

T2是以java5注解為支撐的輕量級Web框架。

T2不是簡單的form提交,而對Ajax請求,RIA客戶端等多種多樣的前臺技術的支持。

T2的目標:

2  無論什么類型的客戶端都可以訪問的Web服務器端框架

2  提供盡量簡約,輕量級,易于維護和可擴展的架構

2  支持無狀態,Rest風格的技術架構

2  提供plugin接口,可輕易擴展業務層架構

 

T2架構草圖

用注解和pojo支撐起來的輕量級REST框架--T2

 

  T2homepage: http://code.google.com/p/t-2/

1.    T2sample code

T2的運行需要的JREWeb容器

JRE1.6以上

Web容器:實現了Servlet2.5JSP2.0的JavaEE標準

 

T2運行時必要的jar文件

T2.jar

Commons.jar                   Apache的共通類庫

slf4j-api.jar                     logging用類庫

 

T2必要的設定

Web.xml中的設定

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
        <filter>
                <filter-name>t2</filter-name>
                <filter-class>org.t2framework.t2.filter.T2Filter</filter-class>
                <init-param>
                        <param-name>t2.rootpackage</param-name>
                        <param-value>sample.page</param-value>
                </init-param>
        </filter>
        <filter-mapping>
                <filter-name>t2</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

</web-app>


 

http請求由T2Filter接受,這里是T2框架的入口
  [t2.rootpackage]指定了所有后臺頁面程序的根目錄,Web容器啟動以后,到這個目錄下面,將所有@Page注解的Java程序實例化。
  T2框架本身有自帶的IOC管理器—SimpleContainerAdapter
  當然也可以通過以下配置,將instances的管理交由專業框架。
<init-param>
                        <param-name>t2.container.adapter</param-name>
                        <param-value>org.t2framework.t2.adapter.S2Adapter</param-value>
                </init-param>
                <!-- 設定ファイルの読み込み -->
                <init-param>
                        <param-name>t2.config</param-name>
                        <param-value>app.dicon</param-value>
                </init-param>


 

接受http請求的后臺類
@Page("/helloworld")
public class HelloPage {

        @Default
        public Navigation index() {
                String message ="HelloWorld";
                return SimpleText.out(message);
        }
}


 

以上,@Page用來聲明這個后臺類對外公開的URL@Default聲明默認的http請求的處理函數。
假設,Web工程的contentroot是/sample的話,上面的后臺類能夠用以下url訪問
http://localhost:8080/sample/helloworld
 
T2框架可執行的SampleCode可以由以下取得
http://code.google.com/p/t-2/wiki/Samples

 

3.    T2的運行原理

用注解和pojo支撐起來的輕量級REST框架--T2

T2MVC
     T2的核心在于,一個url對應一個Page類。
     Page類和View分離,達到可以自由更換View層技術。
     Page類中,http request的接受,http response的組裝,Token的獲得,Session的獲得,業務層service的對象的組裝都可以由注解來完成。
     比如,拿官方的sample舉例
@RequestScope
@Page("login")
public class LoginPage {

    private static Logger logger = Logger.getLogger(LoginPage.class);

    protected LoginService loginService;

    /**
     * 
     * {@.en }
     * 
     * <br />
     * 
     * @param request
     * @return
     */
    @Default
    public Navigation index(final HttpServletRequest request) {
        TokenUtil.saveToken(request, Constants.TOKEN_KEY);
        String token = TokenUtil.getToken(request, Constants.TOKEN_KEY);
        request.setAttribute(Constants.TOKEN_KEY, token);
        return Forward.to("WEB-INF/pages/login.jsp");
    }

/**
     * 
     * {@.en }
     * 
     * @param context
     * @return
     * @since 0.5.1
     */
    @Ajax
    @POST
    @ActionParam
    public Navigation login(WebContext context) {
        final String contextPath = context.getRequest().getContextPath();
        final Map<String, String> map = CollectionsUtil.newHashMap();
        String next;
        if (TokenUtil.isTokenValid(context.getRequest().getNativeResource(),
                Constants.TOKEN_KEY) == false) {
            map.put("errorMessage", Functions.nls("login_token_invalid"));
            next = "/login";
        } else {
            final String user = context.getRequest().getParameter("user");
            final String pass = context.getRequest().getParameter("pass");
            if (StringUtil.isEmpty(user)) {
                map.put("errorMessage", Functions.nls("login_userid_empty"));
                next = "/login";
            } else if (StringUtil.isEmpty(pass)) {
                map.put("errorMessage", Functions.nls("login_password_empty"));
                next = "/login";
            } else {
                final boolean logined = loginService.login(user, pass, 0);
                if (logined == false) {
                    logger.debug("Login error");
                    map.put("errorMessage", Functions.nls("login_auth_failed"));
                    next = "/login";
                } else {
                    context.getSession().setAttribute(Constants.AUTH_KEY,
                            System.currentTimeMillis());
                    next = "/employee/list";
                }
            }
        }
        map.put("url", contextPath + next);
        return Json.convert(map);
    }


 

整個類最高層有兩個注解,@RequestScope@Page
@RequestScope聲明本頁面所有的變量只能存續在一次請求中
Index方法上的@Default聲明了它是初期化函數
HttpServletRequest的變量是由框架組裝實例化。
 
Login方法上的@Ajax@POST@ActionParam。分別聲明了該方法支持Ajax請求,接受post方法請求,用來檢查本方法和form的名字是否統一
 
前臺JSP中提交的form如下
<form action="${t:url('/login')}" method="post">
        <div class="x">
        <span id="error" class="err">${message}</span>
        <c:if test="${message != null}"><br /></c:if>
        <span id="errorMessage" class="m">${t:nls('login_init_message')}</span>
        <br/>
        <fieldset id="loginFieldset" class="loginfieldset" title="${t:nls('login_init_message')}">
            <legend>Login</legend>
            <table>
                <tr>
                    <td class="z">${t:nls('login_userid')}</td>
                    <td class="v">
                        <input type="text" id="user" name="user" maxlength="32" style="width: 100px;"/>
                    </td>
                </tr>
                <tr>
                    <td class="z">${t:nls('login_password')}</td>
                    <td class="v">
                        <input type="password" id="pass" name="pass" style="width: 100px;"/>
                    </td>
                    <td>
                </tr>
                <tr>
                    <td colspan="2" align="right">
                        <input type="submit" id="login" name="login" value="${t:nls('login_loginbutton')}" class="submit"/>
                    </td>
                    <td></td>
                </tr>
            </table>
        </fieldset>
        </div>
    </form>


 

Form中定義的
t:url('/login')是用到了T2自定義的標簽,簡單說來就是將請求發給了Login.javalogin函數。
 
T2的擴展
     作為一個高擴展的框架,T2提供了注解自定義,函數攔截,入口參數封裝等等擴展接口。

Navigation

Navigation是用來forward,redirect畫面的接口。可以自定義擴展,比如在畫面跳轉之前,將數據封裝成json等等。

ContainerAdapter

用來連接DI容器的適配器,可以自定義到任意到現有的DI框架。

Plugin

XXXPlugin這種class可以用來攔截http請求,封裝參數對象等等。具體說起來就是在T2Filter將請求轉發給XXXPage之前就加以處理

AnnotationResolverCreator

可以用來生成和解釋自定義的標簽

FormResolver

用來自定義form參數解釋器。
 
#以上#

 轉自:http://blog.csdn.net/nanjingjiangbiao/article/details/7680702

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!