<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-40  評論-66  文章-0  trackbacks-0
      2007年1月24日
    springside3背景struts2.1.2 spring2.5.6 Hibernate3.4GA


    1.struts2

    使用ZeroConfig + CodeBehind插件,實現約定大于配置的零配置文件風格.

    根本不用配置struts.xml文件





    這里就是action實現annotation  CodeBehind。
    如方法


    通過 /user/user!input.action訪問, 并轉到 /user/user-xxx.jsp頁面
    即namespace + action name + "-" + "xxx.jsp"


     另外其中 action中需要注入的 service 使用annotation ,在set方法前 加入@request 或 @ autowired 或 @resource
    注釋(具體是用那個暫時無法搞清楚,總之我用request 就不行,另外兩個都可以)



    有了這個代碼之后 就能注入spring 環境中的 id = userManager 的bean (我個人理解)

    而spring中  id = userManager 的bean  也是通過自動注入完成的

    主要代碼是 applicationContext.xml文件中的
    代碼:




    2.spring

    spring2.5.6的annotation特性用的比較泛濫。 新手剛開始看的一頭霧水很正常。

    xml文件中配置自動注冊bean,通過掃描包中的帶注解的類。即這個代碼:




    掃描到下面的類,就自動注冊成 id=userManager





    3.hibernate
    使用hiberante3 注解,不要XML配置,實體類注解不用多說。

    需要注意的是entity類的掃描配置




    看清楚是掃描包,不是掃描類! 所以實體類com.mylu.User是無法掃描到,要放在 com.mylu.xxx.User才能掃描到!




    下邊按照ss3風格做的例子,去掉spring security 框架的, 結構更清晰。

    下載:實例代碼


    附:
    類庫
    posted @ 2009-01-08 17:01 Super·shen BLOG 閱讀(1795) | 評論 (2)編輯 收藏

    在jsp中,其實jsp就是servlet,jsp和servlet也都是一個class:

    1 .request.getRealPath(),這個方法已經不推薦使用,在servlet后繼版本中將被取締。

    2.getServletContext().getRealPath("/")這個方法比較好用,可以直接在servlet和jsp中使用。

    3.request.getSession().getServletContext().getRealPath()也可以在jsp和servlet使用。

    4.this.getClass().getClassLoader().getResource("").getPath(),這個方法可以在任意jsp,servlet,java文件中使用,因為不管是jsp,servlet其實都是java程序,都是一個class。所以它應該是一個通用的方法。

    posted @ 2008-09-17 14:55 Super·shen BLOG 閱讀(504) | 評論 (0)編輯 收藏

    普遍的,簡單的權限系統要求:

    1.系統所有資源定義 [資源表]   ( 還可以分為更小的權限表,操作表,這里通叫資源表)
    2.定義角色 [角色表]
    3.給角色指定資源(一個角色可以管理多個資源) [角色-資源表]
    4.定義用戶組 [用戶表]
    5.給用戶組指定角色(一個用戶組可以擁有多種角色) [用戶組-角色表]
    6.給用戶指定角色(一個用戶可以擁有多種角色,可以直接指定角色,也可以繼承用戶組的角色)[用戶-角色表]

     


    查找權限時:

    根據用戶ID[用戶-角色表]或用戶組ID[用戶組-角色表],查到所有角色ID,再[角色-資源表]找到所有角色下的所有資源。

    此就是用戶擁有的資源。(資源一般為模塊,當然也可以分更細的定義為頁面,操作方法等)


    此權限設計適合于模塊化訪問系統,如OA


    當然很多系統因地而已,不可能完全滿足,按照自己系統需求設計是最合適的設計。



    posted @ 2008-08-18 16:17 Super·shen BLOG 閱讀(803) | 評論 (0)編輯 收藏
    提交頁面

    插入

    用戶:
    密碼:
    處理頁面add2.cgi 代碼 #include #include #include #include "sqlite3.h" #include "cgic.h" int cgiMain() { printf("Content-type:text/html\n\n"); printf(""); sqlite3 *db=NULL; char *zErrMsg = 0; int rc; rc = sqlite3_open("test.db", &db); if(rc){ printf("Can't open database\n"); //這里改了。要是按原先的,會提示stderr未定義,我不知道為什么。哪位朋友知道一定要告訴我哦。 sqlite3_close(db); exit(1); } else printf("open test.db successfully!\n"); char username[241]; cgiFormString("username", username, 241); fprintf(cgiOut, "username:
    \n");
    cgiHtmlEscape(username);
    fprintf(cgiOut, "
    \n"); char password[241]; cgiFormString("password", password, 241); fprintf(cgiOut, "password:
    \n");
    cgiHtmlEscape(password);
    fprintf(cgiOut, "
    \n"); char sql[300]={'\0'}; //不能用指針! //插入數據 sprintf(sql, "INSERT INTO \"user\" VALUES('%s', '%s');", username,password); //sql = "INSERT INTO \"user\" VALUES('username', 'password');" ; sqlite3_exec( db , sql , 0 , 0 , &zErrMsg ); printf(sql); printf("插入數據成功!\n"); int nrow = 0, ncolumn = 0; char **azResult; //二維數組存放結果 //查詢數據 /* int sqlite3_get_table(sqlite3*, const char *sql,char***result , int *nrow , int *ncolumn ,char **errmsg ); result中是以數組的形式存放你所查詢的數據,首先是表名,再是數據。 nrow ,ncolumn分別為查詢語句返回的結果集的行數,列數,沒有查到結果時返回0 */ char *sql2 = "SELECT * FROM user"; sqlite3_get_table( db , sql2 , &azResult , &nrow , &ncolumn , &zErrMsg ); int i = 0 ; printf( "row:%d column=%d
    " , nrow , ncolumn ); printf( "\nThe result of querying is : \n" ); for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ ) printf( "azResult[%d] = %s
    ", i , azResult[i] ); //釋放掉 azResult 的內存空間 sqlite3_free_table( azResult ); sqlite3_close(db); //關閉數據庫 return 0; } 請注意數據庫文件 test.db的訪問權限! 這里改成777!
    posted @ 2008-03-01 17:11 Super·shen BLOG 閱讀(1742) | 評論 (1)編輯 收藏

    [轉自] http://webdn.trueself.cn/archives/107

    posted @ 2008-02-28 14:19 Super·shen BLOG 閱讀(746) | 評論 (0)編輯 收藏

    ◆ 使用strtok函數分割。
         原型:char *strtok(char *s, char delim);
        strtok在s中查找包含在delim中的字符并用NULL('\0')來替換,直到找遍整個字符串。  
         功能:分解字符串為一組字符串。s為要分解的字符串,delim為分隔符字符串。
        說明:首次調用時,s指向要分解的字符串,之后再次調用要把s設成NULL。
                    strtok在s中查找包含在delim中的字符并用NULL('\0')來替換,直到找遍整個字符串。
        返回值:從s開頭開始的一個個被分割的串。當沒有被分割的串時則返回NULL。
                      所有delim中包含的字符都會被濾掉,并將被濾掉的地方設為一處分割的節點。

    使用例:
    #include <stdio.h>
    #include <string.h>
    #include <stdio.h>
    #include <string.h>

    int main(int argc,char **argv)
    {
        char * buf1="aaa, ,a, ,,,bbb-c,,,ee|abc";

        /* Establish string and get the first token: */
        char* token = strtok( buf1, ",-|");
        while( token != NULL )
         {
               /* While there are tokens in "string" */
               printf( "%s ", token );
              /* Get next token: */
              token = strtok( NULL, ",-|");
         }
        return 0;
    }

    OUT 值:
    aaa

    a

    bbb
    c
    ee
    abc

    ◆ 使用strstr函數分割。

        原型:extern char *strstr(char *haystack,char *needle);

        用法:#include <string.h>
       功能:從字符串haystack中尋找needle第一次出現的位置(不比較結束NULL)
       說明:返回指向第一次出現needle位置的指針,如果沒找到則返回NULL。

    使用例:
    #include <stdio.h>
    #include <string.h>

    int main(int argc,char **argv)
    {
         char *haystack="aaa||a||bbb||c||ee||";
         char *needle="||";
         char* buf = strstr( haystack, needle);
         while( buf != NULL )
         {
             buf[0]='\0';
             printf( "%s\n ", haystack);
              haystack = buf + strlen(needle);
              /* Get next token: */
              buf = strstr( haystack, needle);
         }
         return 0;
    }

    OUT 值:
    aaa
    a
    bbb
    c
    ee

    ◆ strtok比較適合多個字符作分隔符的場合,而strstr適合用字符串作分隔符的場合。

    posted @ 2008-02-27 16:35 Super·shen BLOG 閱讀(1475) | 評論 (0)編輯 收藏
    我們來看看到底如何從POST表單收集數據到CGI程序,下面給出了一個比較簡單的C源代碼:     
        
     

     

    #include<stdio.h>
    #include<stdlib.h>    
    #define MAXLEN 80    
    #define EXTRA 5
    /*   4個字節留給字段的名字"data",   1個字節留給"="   */
    #define   MAXINPUT   MAXLEN+EXTRA+2 
    /*   1個字節留給換行符,還有一個留給后面的NULL   */
    #define DATAFILE "../data/data.txt"
    /*   要被添加數據的文件   */

    void   unencode(char   *src,   char   *last,   char   *dest)
    {
     for(; src != last; src++, dest++)
      if(*src == "+")
       *dest = " ";
      else if(*src == "%") {    
       int   code;    
       if(sscanf(src+1,"%2x",&code)!=1)code="?";
       *dest=code;
       src   +=2;}
      else
       *dest=*src;
      *dest=" ";
      *++dest="";    
    }    

    int   main(void)    
    {    
     char *lenstr;
     char input[MAXINPUT], data[MAXINPUT];
     long len;
     
     printf("%s%c%c", "Content-Type:text/html;charset=gb2312",13,10);
     printf("<TITLE>Response</TITLE>");

     lenstr=getenv("CONTENT_LENGTH");
     if(lenstr==NULL || sscanf(lenstr,"%ld",&len)!=1 || len>MAXLEN)
      printf("<P>表單提交錯誤");
     else{
      FILE *f;
      fgets(input,   len+1,   stdin);
      unencode(input+EXTRA,   input+len,   data);

      f =fopen(DATAFILE, "a");
      if(f == NULL)    
       printf("<P>對不起,意外錯誤,不能夠保存你的數據");    
      else
       fputs(data,   f);    
      fclose(f);
      printf("<P>非常感謝,您的數據已經被保存<BR>%s",data);    
     }    
     return   0;    
    }    

        
           從本質上來看,程序先從CONTENT_LENGTH環境變量中得到數據的字長,然后讀取相應長度的字符串。因為數據內容在傳輸的過程中是經過了編碼的,所以必須進行相應的解碼。編碼的規則很簡單,主要的有這幾條:     

    1.   表單中每個每個字段用字段名后跟等號,再接上上這個字段的值來表示,每個字段之間的內容用&連結;    2.   所有的空格符號用加號代替,所以在編碼碼段中出現空格是非法的;    
    3.   特殊的字符比如標點符號,和一些有特定意義的字符如“+”,用百分號后跟其對應的ACSII碼值來表示。    

    例如:如果用戶輸入的是:     
       
    Hello   there!    

    那么數據傳送到服務器的時候經過編碼,就變成了data=Hello+there%21   上面的unencode()函數就是用來把編碼后的數據進行解碼的。在解碼完成后,數據被添加到data.txt文件的尾部,并在瀏覽其中回顯出來。    

    把文件編譯完成后,把它改名為collect.cgi后放在CGI目錄中就可以被表單調用了。下面給出了其相應的表單:    

    <FORM   ACTION="/cgi-bin/collect.cgi"   METHOD="POST"   >
    <P>請輸入您的留言(最多80個字符):<BR>
    <INPUT   NAME="data"   SIZE="60"   MAXLENGTH="80"   ><BR>
    <INPUT   TYPE="SUBMIT"   VALUE="確定">
    </FORM   >    
       
       
           事實上,這個程序只能作為例子,是不能夠正式的使用的。它漏掉了很關鍵的一個問題:當有多個用戶同時像文件寫入數據是,肯定會有錯誤發生。而對于一個這樣的程序而言,文件被同時寫入的幾率是很大的。因此,在比較正式的留言版程序中,都需要做一些更多的考慮,比如加入一個信號量,或者是借助于一個鑰匙文件等。因為那只是編程的技巧問題,在這兒就不多說了。

    posted @ 2008-02-27 13:52 Super·shen BLOG 閱讀(2772) | 評論 (1)編輯 收藏
    啥都不說,直接看代碼!

    簡單輸出代碼

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void main()
    {
    printf("Content-type:text/html\n\n");

    printf("hello world!");

    fflush(stdout);

    }



    處理get代碼

    #include <stdio.h>
    #include <stdlib.h>
    int zmain(void)
    {char *data;
    long m,n;
    printf("%s%c%c\n","Content-Type:text/html;charset=iso-8859-1",13,10);
    printf("<TITLE>Multiplication results</TITLE>\n");
    printf("<H3>Multiplication results</H3>\n");
    data = getenv("QUERY_STRING");
    if(data == NULL) 
    printf("<P>Error! Error in passing data from form to script.");
    else if(sscanf(data,"m=%ld&n=%ld",&m,&n)!=2) 
    printf("<P>Error! Invalid data. Data must be numeric.");
    else 
    printf("<P>The product of %ld and %ld is %ld.",m,n,m*n);
    return 0;
    }


    處理post代碼

    #include<stdio.h>
    #include<stdlib.h>
    void main()
    {
     int i,n;
     printf("Content-type:text/html\n\n");
     n=0;
     if(getenv("CONTENT_LENGTH"))
      n=atoi(getenv("CONTENT_LENGTH"));
     printf("%d",n);
     for(i=0;i<n;i++)
      putchar(getchar());
     putchar('\n');
     fflush(stdout);
    }



    還是代碼


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    /* 轉換函數聲明 */
    int htoi(char *);

    /*  主函數 */
    void zmain() {
     int i,n;
     char c;
     printf ("Content-type: text/html\n\n");
     n=0;
     if (getenv("CONTENT_LENGTH"))
      n=atoi(getenv("CONTENT_LENGTH"));
     for (i=0; i<n;i++){
      
      int is_eq=0; //判斷是否有等于號。
      
      c=getchar();
      switch(c){
      case '&':
       c='\n';
       break;
      case '+':
       c='+';
       break;
      case '%':
       {
        char s[3];
        s[0]=getchar();
        s[1]=getchar();
        s[2]=0;
        c=htoi(s);
        i+=2;
       }
       break;
      case '=':
       c='=';
       is_eq=1;
       break;
      };
      
      putchar(c);
      //if (is_eq) putchar(' ');
     }
     putchar ('\n');
     fflush(stdout);
    }

    /* 轉換為小寫 */
    int islower (int ch ) 

    {
        return (unsigned int) (ch - 'a') < 26u;
    }


    /* convert hex string to int 16進制轉換成10進制 */
    int htoi(char *s)

    {
     
     char *digits="0123456789ABCDEF";
     
     if(islower(s[0])) s[0]=toupper(s[0]);
     if(islower(s[1])) s[1]=toupper(s[1]);
     
     return 16 * (strchr(digits, s[0]) -strchr(digits,'0') ) +(strchr(digits,s[1])-strchr(digits,'0'));
     
    }


    #include<stdio.h>
    #include<stdlib.h>
    void zzzmain()
    {
     int i,n;
     printf("Content-type:text/html\n\n");
     n=0;
     if(getenv("CONTENT_LENGTH"))
      n=atoi(getenv("CONTENT_LENGTH"));
     printf("%d",n);
     for(i=0;i<n;i++)
      putchar(getchar());
     putchar('\n');
     fflush(stdout);
    }

     

    posted @ 2008-02-26 15:37 Super·shen BLOG 閱讀(750) | 評論 (0)編輯 收藏
    http://samhe.javaeye.com/blog/142416
    posted @ 2008-01-18 17:14 Super·shen BLOG 閱讀(313) | 評論 (0)編輯 收藏
    DWR(Direct Web Remoting)是一個WEB遠程調用框架.利用這個框架可以讓AJAX開發變得很簡單.利用DWR可以在客戶端利用JavaScript直接調用服務端的Java方法并返回值給JavaScript就好像直接本地客戶端調用一樣(DWR根據Java類來動態生成JavaScrip代碼).它的最新版本DWR0.6添加許多特性如:支持Dom Trees的自動配置,支持Spring(JavaScript遠程調用spring bean),更好瀏覽器支持,還支持一個可選的commons-logging日記操作.

    以上摘自open-open,它通過反射,將java翻譯成javascript,然后利用回調機制,輕松實現了javascript調用Java代碼。

    其大概開發過程如下:
    1.編寫業務代碼,該代碼是和dwr無關的。
    2.確認業務代碼中哪些類、哪些方法是要由javascript直接訪問的。
    3.編寫dwr組件,對步驟2的方法進行封裝。
    4.配置dwr組件到dwr.xml文件中,如果有必要,配置convert,進行java和javascript類型互轉。
    5.通過反射機制,dwr將步驟4的類轉換成javascript代碼,提供給前臺頁面調用。
    5.編寫網頁,調用步驟5的javascript中的相關方法(間接調用服務器端的相關類的方法),執行業務邏輯,將執行結果利用回調函數返回。
    6.在回調函數中,得到執行結果后,可以繼續編寫業務邏輯的相關javascript代碼。

    下面以用戶注冊的例子,來說明其使用。(注意,本次例子只是用于演示,說明DWR的使用,類設計并不是最優的)。

    1.先介紹下相關的Java類

      User: 用戶類,
      public class User {
    //登陸ID,主鍵唯一
    private String id;
    //姓名
    private String name;
    //口令
    private String password;
    //電子郵件
    private String email;
            
    //以下包含getXXX和setXXX方法
    .......
      }

      UserDAO:實現User的數據庫訪問,這里作為一個演示,編寫測試代碼
      public class UserDAO {
        //存放保存的數據
        private static Map dataMap = new HashMap();

        //持久用戶
        public boolean save(User user) {
          if (dataMap.containsKey(user.getId()))
            return false;
          System.out.println("下面開始保存用戶");
          System.out.println("id:"+user.getId());
          System.out.println("password:"+user.getPassword());
          System.out.println("name:"+user.getName());
          System.out.println("email:"+user.getEmail());
          dataMap.put(user.getId(), user);
          System.out.println("用戶保存結束");
          return true;
        }

        //查找用戶
        public User find(String id) {
          return (User)dataMap.get(id);
        }
    }

      DWRUserAccess:DWR組件,提供給javascript訪問的。

      public class DWRUserAccess {

          UserDAO userDAO = new UserDAO();

          public boolean save(User user) {
            return userDAO.save(user);
          }

          public User find(String id) {
            return userDAO.find(id);
          }
      }
      

      下面說明下程序執行的流程

      1.用戶在頁面上輸入相關注冊信息,id、name、password、email,點擊“提交”按鈕
      2.javascript代碼開始執行,根據用戶填寫相關信息,通過dwr提供的DWRUserAccess.js里save的方法,調用服務器端的DWRUserAccess類save方法,將注冊信息保存。
      3.通過DWRUserAccess.jsp里的find方法,調用服務器端DWRUserAccess類里的find方法,執行用戶信息查找。

      注意,在以上的執行過程中,DWRUserAccess是供DWR調用的,是DWR組件,因此需要將DWRUserAccess類配置到dwr中。

      接下來講解本次dwr測試環境的配置。

      1.新建一個webapp,命名為testApp
      2.將dwr.jar拷貝到testApp的WEB-INF的lib目錄下
      3.編譯上面的User,UserDAO,DWRUserAccess類,放到classes目錄下
      4.在web.xml中配置servlet,適配路徑到dwr目錄下,如下所示
        <servlet>
        <servlet-name>dwr-invoker</servlet-name>
        <display-name>DWR Servlet</display-name>
        <description>Direct Web Remoter Servlet</description>
        <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
        <init-param>
          <param-name>debug</param-name>
          <param-value>true</param-value>
        </init-param>
        <init-param>
          <param-name>scriptCompressed</param-name>
          <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>

      <servlet-mapping>
        <servlet-name>dwr-invoker</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
      </servlet-mapping>

      以上的配置可以攔截testApp下所有指向dwr的請求,關于這個攔截器,我們會在后面介紹。

      5.WEB-INF下新建一個dwr.xml文件,內容如下:
      < xml version="1.0" encoding="UTF-8" >
    <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

    <dwr>
      <allow>
    <create creator="new" javascript="DWRUserAccess">
          <param name="class" value="test.DWRUserAccess"/>
        </create>
    <convert converter="bean" match="test.User"/>
      </allow>
    </dwr>

      這里我們把DWRUserAccess配置到了dwr中,create元素中,creater="new"表示每調用一次DWRUserAccess時,需要new一個這樣的類;javascript="DWRUserAccess",表示提供給前臺頁面調用的javascirpt文件是DWRUserAccess.js。

      convert元素用于數據類型轉換,即java類和javascript之間相互轉換,因為和前臺交換的是User對象,因此需要對此使用bean轉換,我們將在后面介紹這個類。

      4.編寫測試的HTML頁面 test.html
       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
    <TITLE>DWR測試</TITLE>
    <meta http-equiv=Content-Type content="text/html; charset=gb2312">
    <script src="/oblog312/dwr/engine.js"></script>
    <script src="/oblog312/dwr/util.js"></script>
    <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
    </HEAD>
    <BODY>
    <B>用戶注冊</B><br>
    ------------------------------------------------
    <Br>
    <form name="regForm">
    登陸ID:<input type="text" name="id"><br>
    口  令:<input type="password" name="password"><br>
    姓  名:<input type="text" name="name"><br>
    電子郵件:<input type="text" name="email"><br>
    <input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br>
        </form>

    <br>
    <br><B>用戶查詢</B><br>
    ------------------------------------------------
    <Br>
    <form name="queryForm">
    登陸ID:<input type="text" name="id"><br>
    <input type="button" name="submitBtn" value="提交" onclick="OnFind()"><br>
    </form>
    <br>
    </BODY>
    </HTML>
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function saveFun(data) {
    if (data) {
      alert("注冊成功!");
    } else {
      alert("登陸ID已經存在!");
    }
    }

    function OnSave() {
    var userMap = {};
    userMap.id = regForm.id.value;
    userMap.password = regForm.password.value;
    userMap.name = regForm.name.value;
    userMap.email = regForm.email.value;
    DWRUserAccess.save(userMap, saveFun);
    }

    function findFun(data) {
    if (data == null) {
      alert("無法找到用戶:"+queryForm.id.value);
      return;
    }

    alert("找到用戶,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

    }

    function OnFind() {
    DWRUserAccess.find(queryForm.id.value, findFun);
    }
    //-->
    </SCRIPT>


    以下對頁面的javascript進行解釋

    <script src="/oblog312/dwr/engine.js"></script>
    <script src="/oblog312/dwr/util.js"></script>
    這兩個是dwr提供的,用戶可以不必關心,只需要導入即可

    <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
    是我們編寫的DWRUserAccess類,經dwr反射后,生成的javascript代碼,它和DWRUserAccess.java是對應的,供用戶調用,實際上我們就是通過這個js文件去調用服務器端的DWRUserAccess類的。

    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function saveFun(data) {
    if (data) {
      alert("注冊成功!");
    } else {
      alert("用戶名已經存在!");
    }
    }

    function OnSave() {
    var userMap = {};
    userMap.id = regForm.id.value;
    userMap.password = regForm.password.value;
    userMap.name = regForm.name.value;
    userMap.email = regForm.email.value;
    DWRUserAccess.save(userMap, saveFun);
    }

    function findFun(data) {
    if (data == null) {
      alert("無法找到用戶:"+queryForm.id.value);
      return;
    }

    alert("找到用戶,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

    }

    function OnFind() {
    DWRUserAccess.find(queryForm.id.value, findFun);
    }
    //-->
    </SCRIPT>

    這段javascirpt代碼,我們來看下OnSave函數,首先它構造一個map,將表單數據都設置到map中,然后調用DWRUserAccess.save(userMap, saveFun),執行save操作。大家可以注意到,服務器端的DWRUserAccess中的save方法是這樣的:boolean save(User user),其參數是一個User對象,返回一個boolean值;而客戶端的方法是這樣的:save(userMap,saveFun),第一個參數userMap是javascirpt中的map對象,在這里相當于服務器端的User對象(在服務器端執行時,會通過convert轉換成User對象),前面我們提到dwr是利用回調函數來返回執行結果的,第二個參數saveFun即是一個回調函數。在函數function saveFun(data)中,data是執行結果,這里是一個bool值,非常簡單的,我們通過判斷data是否為真,可以知道用戶名是否重復,用戶是否注冊成功。

    看一下OnFind查找函數,執行結果在回調函數findFun(data)中,因為服務器端返回的是一個User對象,通過convert,將會轉換成javascript的一個map對象,
    于是在findFun中,通過data.id、data.name、data.password、data.email我們可以輕松的訪問到這個User對象。


    好了配置完畢,啟動服務器,在目錄中打入localhost/testApp/test.html。

    1.在“用戶注冊”表單中,id框中輸入admin,password中輸入123456,name中輸入chenbug,email中輸入chenbug@zj.com,點擊提交按鈕,彈出對話框:“注冊成功”,在服務器后臺可以看到信息如下:

    下面開始保存用戶
    id:admin
    password:123456
    name:chenbug
    email:chenbug@zj.com
    用戶保存結束

    再次點擊提交按鈕,彈出對話框“登陸ID已經存在”。

    2.在“用戶查詢”對話框中,輸入登陸ID為admin,點擊提交按鈕,提示找到用戶,并顯示相關信息,輸入admin123,點擊提交按鈕,提示無法找到用戶。

    至此,測試結束。


    后續:
    1。攔截器 uk.ltd.getahead.dwr.DWRServlet
    該類攔截所有指向dwr目錄下的請求,并調用Processor的handler方法進行處理,在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我們可以看到詳細的處理過程。
    if (pathInfo.length() == 0 ||
                pathInfo.equals(HtmlConstants.PATH_ROOT) ||
                pathInfo.equals(req.getContextPath()))
            {
                resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX);
            }
            else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX))
            {
                index.handle(req, resp);
            }
            else if (pathInfo.startsWith(HtmlConstants.PATH_TEST))
            {
                test.handle(req, resp);
            }
            else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE))
            {
                iface.handle(req, resp);
            }
            else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC))
            {
                exec.handle(req, resp);
            }
            else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE))
            {
                file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
            }
            else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL))
            {
                file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
            }
            else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED))
            {
                file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
            }
            else
            {
                log.warn("Page not found (" + pathInfo + "). In debug/test mode try viewing /[WEB-APP]/dwr/"); //$NON-NLS-1$ //$NON-NLS-2$
                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            }

    通過判斷request請求的servlet路徑,進行處理,大家可以自己去參看,這里不詳細討論。


    2.bean轉換器,<convert converter="bean" match="test.User"/>
    將dwr.jar解壓縮,在路徑ukltdgetaheaddwr下可以看到dwr.xml,這里配置了系統默認的一些轉換器,
    <converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>即是剛才用到User類的轉換器,進入代碼我們來看看它是如何在javascript和java間進行轉換的。

    打開BeanConverter代碼,定位到函數

    public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws ConversionException

    即是將javascript對象轉換成java對象的,其中
    paramType即Class類型,在上面的例子中是test.User,
    InboundVariable iv,是傳入的值,通過iv.getValue可以得到傳入的javascript值串
    InboundContext inctx,是入口參數上下文,用于保存轉換的后java對象。

    因為前臺傳入的是一個javascript的map類型,而map肯定是以{開始和以}結束的,于是在這個函數一開始進行了判斷
    if (!value.startsWith(ConversionConstants.INBOUND_MAP_START))
            {
                throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
            }

            if (!value.endsWith(ConversionConstants.INBOUND_MAP_END))
            {
                throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
            }

    javascript中,map里各個項是用逗號連接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每個項的鍵值對是用冒號連接的,
    在convertInbound函數的接下來的處理中,即是通過分析map字串,通過paramType構造java實例(即User類),然后通過反射,將這些鍵值對設置到java實例中,并返回。
    這樣就完成了javascript到java的轉換。


    另一個函數
    public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException

    即是將java對象轉換為javascript對象(其實是聲明和賦值語句)。
    Object data ,是待轉換的java對象
    String varname,是javascript中的該對象的變量名
    OutboundContext outctx,傳出參數上下文,用于保存轉換后的javascript值

    StringBuffer buffer = new StringBuffer();
            buffer.append("var "); //$NON-NLS-1$
            buffer.append(varname);
            buffer.append("={};"); //$NON-NLS-1$
    這里聲明了map類型的變量。

    即下來來的代碼即是通過反射進行變量賦值,如下
      buffer.append(varname);
                        buffer.append('.');
                        buffer.append(name);
                        buffer.append('=');
                        buffer.append(nested.getAssignCode());
                        buffer.append(';');
    大家可以自己去參看更多的代碼。

    3.dwr本身提供了一個測試環境,大家在配置完后,可以在IE中輸入地址http://localhost/testApp/dwr/index.html,看到配置的各DWR組件,并進行相關測試。
    posted @ 2008-01-18 14:43 Super·shen BLOG 閱讀(41043) | 評論 (27)編輯 收藏

    1. dwr  - direct web remote
    2. 推技術
    3. http 長連接
    4. Comet  ----   HTTP長連接的“服務器推”技術
    5. Jetty服務器 ----  Jetty 6 Web 服務器針對 AJAX、Comet 應用的特點進行了很多創新的改進,請參考文章“AJAX,Comet and Jetty”(請參見 參考資源)。


    http://wiki.javascud.org/display/dwrcn/Home
    http://wiki.springside.org.cn/display/springside/DWR

    http://blog.csdn.net/octverve/archive/2007/09/26/1801826.aspx
    posted @ 2008-01-15 10:07 Super·shen BLOG 閱讀(310) | 評論 (0)編輯 收藏

    學習共進!

    MyEclipse 5.5 開發 Struts 1.2 簡單登錄的入門視頻(有聲+源碼)
      2007-09-19 01:50

    視頻講解: Netbeans 5.5 配置顯示中文 JavaDoc

    入門視頻: 使用 MyEclipse 開發 Swing 應用

    河南話講解 MyEclipse + Tomcat Servlet 開發入門視頻

    MyEclipse + JPA + Toplink 開發視頻: 開發并運行第一個 JPA 項目

    MyEclipse + JBoss 開發視頻: 配置,開發并運行第一個 EJB 3 項目

    JDBC 入門視頻: 配置 SQL Explorer 插件, ODBC 數據源, 建表, 用 JDBC 讀取數據庫

    Tomcat 入門視頻: 下載, 運行, 第一個 HelloWorld

    Eclipse 入門視頻: 下載, 運行, 第一個 HelloWorld

    Java 入門視頻: 下載, 安裝 JDK, 配置環境變量, HelloWorld

    推薦給初學者的 Java 視頻

    Netbeans 6.0 M10 開發 UML 項目的入門視頻

    MyEclipse UML 入門視頻2 - 根據代碼反向工程生成 UML

    MyEclipse UML 入門視頻

    MyEclipse + Tomcat 開發視頻: 下載,安裝,配置,開發并運行Web項目

    小電影: 用 MyEclipse 開發 Spring + Struts + Hibernate 的總結與操作視頻(9分鐘)

    小電影: 用 MyEclipse 開發 Spring + Struts 的總結與操作視頻(7分鐘)

    用MyEclipse 4 分鐘開發Spring整合Hibernate應用的視頻

    在 Linux 上配置并運行 Tomcat 服務器(入門整理)(視頻)

    Java 初學者入門視頻: 下載 JDK 和 Netbeans

    Eclipse 配置顯示中文 javadoc 的視頻

    Hibernate 英文 PPT 及 MyEclipse 操作視頻整理

    推薦一點 MyEclipse 的官方Spring,Hibernate入門視頻教程

    Netbeans 5.5 + JPA + Hibernate 3 + Tomcat 實例有聲視頻

    推薦一些AJAX視頻和文章

    夏昕 <<Spring 開發指南入門>>1 分鐘上手教程視頻(不帶解說)

    AJAX 入門培訓 PPT 及示例代碼

    Java EE 5 入門 PPT 講解有聲視頻 - 第二部分

    Java EE 5 入門 PPT 講解有聲視頻 - 第一部分

    Java EE 5 入門視頻 - 在 JSF 中使用 JPA

    Jigloo 開發 Swing 的入門教程

    視頻:使用 Netbeans 5.5可視化開發 JSF 的簡單注冊流程

    Java EE 5 入門視頻 - 在 J2SE 中使用 JPA

    Navicat管理Mysql 的視頻

    Weblogic 9 之旅圖文視頻 2 - Portal 開發環境設置, 簡單的Portal 開發(視頻已貼上)

    用 JProfiler4 調優 Weblogic 和 Tomcat 的視頻(原創)

    來自 http://m.tkk7.com/beansoft

    posted @ 2008-01-08 10:05 Super·shen BLOG 閱讀(693) | 評論 (0)編輯 收藏
    String command = "cmd /c C:/Program Files/MySQL/MySQL Server 5.0/bin>mysqldump -h localhost -u root -p aijia > E:/aijia.dmp";
      try {
       Process process = Runtime.getRuntime().exec(command);
       InputStreamReader ir = new InputStreamReader(process
         .getInputStream());
       LineNumberReader input = new LineNumberReader(ir);
       String line;
       while ((line = input.readLine()) != null)
        System.out.println(line);
       input.close();
      } catch (IOException e) {
       e.printStackTrace();
      }




    另外

    首先,設置mysql的環境變量(在path中添加%MYSQL_HOME%\bin),重啟電腦。
    完整代碼:
        /**
         * @param args
         */
        public static void main(String[] args) {
            /*
             * 備份和導入是一個互逆的過程。
             * 備份:程序調用mysql的備份命令,讀出控制臺輸入流信息,寫入.sql文件;
             * 導入:程序調用mysql的導入命令,把從.sql文件中讀出的信息寫入控制臺的輸出流
             * 注意:此時定向符">"和"<"是不能用的
             */
            backup();
            load();
        }

        /**
         * 備份檢驗一個sql文件是否可以做導入文件用的一個判斷方法:把該sql文件分別用記事本和ultra
         * edit打開,如果看到的中文均正常沒有亂碼,則可以用來做導入的源文件(不管sql文件的編碼格式如何,也不管db的編碼格式如何)
         */
        public static void backup() {
            try {
                Runtime rt = Runtime.getRuntime();

                // 調用 mysql 的 cmd:
                Process child = rt
                        .exec("mysqldump -u root --set-charset=utf8 bjse act_obj");// 設置導出編碼為utf8。這里必須是utf8
               
                // 把進程執行中的控制臺輸出信息寫入.sql文件,即生成了備份文件。注:如果不對控制臺信息進行讀出,則會導致進程堵塞無法運行
                InputStream in = child.getInputStream();// 控制臺的輸出信息作為輸入流
                           
                InputStreamReader xx = new InputStreamReader(in, "utf8");// 設置輸出流編碼為utf8。這里必須是utf8,否則從流中讀入的是亂碼
               
                String inStr;
                StringBuffer sb = new StringBuffer("");
                String outStr;
                // 組合控制臺輸出信息字符串
                BufferedReader br = new BufferedReader(xx);
                while ((inStr = br.readLine()) != null) {
                    sb.append(inStr + "\r\n");
                }
                outStr = sb.toString();
               
                // 要用來做導入用的sql目標文件:
                FileOutputStream fout = new FileOutputStream(
                        "e:/mysql-5.0.27-win32/bin/bjse22.sql");
                OutputStreamWriter writer = new OutputStreamWriter(fout, "utf8");
                writer.write(outStr);
                // 注:這里如果用緩沖方式寫入文件的話,會導致中文亂碼,用flush()方法則可以避免
                writer.flush();

                // 別忘記關閉輸入輸出流
                in.close();
                xx.close();
                br.close();
                writer.close();
                fout.close();

                System.out.println("/* Output OK! */");

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        /**
         * 導入
         *
         */
        public static void load() {
            try {
                String fPath = "e:/mysql-5.0.27-win32/bin/bjse22.sql";
                Runtime rt = Runtime.getRuntime();

                // 調用 mysql 的 cmd:
                Process child = rt.exec("mysql -u root bjse ");
                OutputStream out = child.getOutputStream();//控制臺的輸入信息作為輸出流
                String inStr;
                StringBuffer sb = new StringBuffer("");
                String outStr;
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        new FileInputStream(fPath), "utf8"));
                while ((inStr = br.readLine()) != null) {
                    sb.append(inStr + "\r\n");
                }
                outStr = sb.toString();

                OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
                writer.write(outStr);
                // 注:這里如果用緩沖方式寫入文件的話,會導致中文亂碼,用flush()方法則可以避免
                writer.flush();
                // 別忘記關閉輸入輸出流
                out.close();
                br.close();
                writer.close();

                System.out.println("/* Load OK! */");

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    posted @ 2007-12-07 13:25 Super·shen BLOG 閱讀(5483) | 評論 (1)編輯 收藏
    用Flex/Central/Java上傳文件      
         in java:
    import com.oreilly.servlet.MultipartRequest;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.IOException;
    import java.io.PrintWriter;

    public class UploadServlet extends HttpServlet {
        protected void doGet( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {;}

        protected void doPost( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {
            MultipartRequest parts = new MultipartRequest( req, "C:\\MyUploadPath" );
            PrintWriter out = res.getWriter();

            out.print( "SUCCESS" );
            out.close();
        }
    }

          in mxml:
    < mx:Application initialize="initApp( event )" xmlns:mx="http://www.macromedia.com/2003/mxml">
         < mx:Button id="btnUpload" label="Upload..." click="doUpload( event )" />
         < mx:Image id="imgUpload" width="100%" height="100%" horizontalAlign="center" />
    </mx:Application>

         as:

    private function doUpload( event:Object ):Void {
        var file:FileReference = new FileReference();

        // Ask the user to choose a file to upload
        if( file.browse( ["JPEG Files", "*.jpg"] ) ) {
            file.addListener( this );
            file.upload( "http://myurl/servlet/MyUploadServlet" );
        }
    }

    private function onUploadSuccess( ref:FileReference, response:String ):Void {
        imgUpload.source = "http://myurl/myfilepath/" + ref.name;
    }

    private function onUploadFailed( ref:FileReference, error:String, response:String ):Void {
        mx.controls.Alert.show( "Upload error: " + error );
    }

       

    servlet獲取絕對路徑方法:
    ServletConfig   config   =   this.getServletConfig();     
    ServletContext   context   =   getServletContext();   
    String   path   =   context.getRealPath("");  
    posted @ 2007-12-03 14:50 Super·shen BLOG 閱讀(1928) | 評論 (1)編輯 收藏
    用flex做即時通訊,收到的最新消息應該在最下面,但textArea的滾動條默認在最上方,不方便查看最新消息。

    可以使用 maxVerticalScrollPosition屬性可以獲取最下方的值,非常方便


    另外提供類:

    package Util
    {
        import mx.controls.TextArea;

        public class ChatTextarea extends TextArea
        {
            public function ChatTextarea()
            {
                super();
            }
           
            override public function set htmlText( value:String ):void
            {
                super.htmlText = value;
                this.validateNow();
                if( textField ) verticalScrollPosition = textField.maxScrollV
            }
           
            override public function set text( value:String ):void
            {
                super.htmlText = value;
                this.validateNow();
                if( textField ) verticalScrollPosition = textField.maxScrollV;
            }
        }

    }
    posted @ 2007-11-22 16:34 Super·shen BLOG 閱讀(3123) | 評論 (0)編輯 收藏
    問題:

    然后運行某Flex程序時,出現如下提示:
    This content requires the Adobe Flash Player. Get Flash
    但是,鏈接到Adobe的Flash Player下載網頁,重裝了N次也不行。

    google到下面的信息:
    "...Flex Builder 2 裏面附的 debugger player 版次比正式版的 Flash Player 9 舊一點,有時會導致網頁的自動偵測失靈(誤以為user沒裝 flash player),所以現在 adobe 網頁上已經有新版的 debugger player ,可以先試試裝那個版本看看。"


    實際解決方法:
    因為本機已安裝了Flex bulider 3 , 既然知道問題所在,就不用再去down了,找到...\Flex bulider 3\Players\目錄,運行Install Flash Player 9 ActiveX.msi,選擇Repair,出錯失敗,再次選擇Remove卸載,重新安裝此ActiveX,瀏覽器中刷新mxml頁面,OK,搞定,收工。
    posted @ 2007-11-22 13:30 Super·shen BLOG 閱讀(1411) | 評論 (0)編輯 收藏

    已經很久沒摸過FLASH了,由于要接一個項目需要用的flash實現。 當我使用flash cs3 寫程序時發現已經和以前的大不一樣了!多年沒接觸本來還想在友人面前顯耀一下寶刀未老,天哪,好多地方不一樣了,剛接觸還真不習慣,還出丑了。

    flash cs3  的改變源自于 as3的重大改變。更源于flash player AM2的重大改變。

    as3功能很強大,語言和java類型,也是面向對象的,也是使用虛擬機解釋。 (虛擬機這個概念太強了。現在的主流程序都是用類似虛擬機技術,JAVA  .NET  FLEX)

    實現技術原理 flash 和 java 曾經紅火一時的applet 幾乎差不多了。但是flash更為簡單易用,易于入門!


    posted @ 2007-11-22 10:49 Super·shen BLOG 閱讀(314) | 評論 (0)編輯 收藏
         摘要: 如何解決端口沖突導致tomcat無法啟動的問題 Tomcat在啟動時主要使用下面的3個端口 <Server port="8005" shutdown="SHUTDOWN" debug="0"> <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8080" minProcessors=...  閱讀全文
    posted @ 2007-11-22 10:00 Super·shen BLOG 閱讀(16623) | 評論 (2)編輯 收藏
    自己在網上找了半天沒找到只有 “時分秒”的控件, 就自己做了個,發在這里方便有人用到


    鼠標點擊 后 的效果


    SetTime.js

    /**//***********************************
    * 簡單時間控件: version 1.0
    * 作者:李祿燊 
    * 時間:2007-10-31

    * 使用說明:
    * 首先把本控件包含到頁面 
    * <script src="XXX/setTime.js" type="text/javascript"></script>
    * 控件調用函數:_SetTime(field)
    * 例如 <input name="time" type="text"   onclick="_SetTime(this)"/>
    *
    ***********************************
    */
    var str = "";
    document.writeln(
    "<div id=\"_contents\" style=\"padding:6px; background-color:#E3E3E3; font-size: 12px; border: 1px solid #777777;  position:absolute; left:?px; top:?px; width:?px; height:?px; z-index:1; visibility:hidden\">");
    str 
    += "\u65f6<select name=\"_hour\">";
    for (h = 0; h <= 9; h++) {
        str 
    += "<option value=\"0" + h + "\">0" + h + "</option>";
    }
    for (h = 10; h <= 23; h++) {
        str 
    += "<option value=\"" + h + "\">" + h + "</option>";
    }
    str 
    += "</select> \u5206<select name=\"_minute\">";
    for (m = 0; m <= 9; m++) {
        str 
    += "<option value=\"0" + m + "\">0" + m + "</option>";
    }
    for (m = 10; m <= 59; m++) {
        str 
    += "<option value=\"" + m + "\">" + m + "</option>";
    }
    str 
    += "</select> \u79d2<select name=\"_second\">";
    for (s = 0; s <= 9; s++) {
        str 
    += "<option value=\"0" + s + "\">0" + s + "</option>";
    }
    for (s = 10; s <= 59; s++) {
        str 
    += "<option value=\"" + s + "\">" + s + "</option>";
    }
    str 
    += "</select> <input name=\"queding\" type=\"button\" onclick=\"_select()\" value=\"\u786e\u5b9a\" style=\"font-size:12px\" /></div>";
    document.writeln(str);
    var _fieldname;
    function _SetTime(tt) {
        _fieldname 
    = tt;
        
    var ttop = tt.offsetTop;    //TT控件的定位點高
        var thei = tt.clientHeight;    //TT控件本身的高
        var tleft = tt.offsetLeft;    //TT控件的定位點寬
        while (tt = tt.offsetParent) {
            ttop 
    += tt.offsetTop;
            tleft 
    += tt.offsetLeft;
        }
        document.all._contents.style.top 
    = ttop + thei + 4;
        document.all._contents.style.left 
    = tleft;
        document.all._contents.style.visibility 
    = "visible";
    }
    function _select() {
        _fieldname.value 
    = document.all._hour.value + ":" + document.all._minute.value + ":" + document.all._second.value;
        document.all._contents.style.visibility 
    = "hidden";
    }




    posted @ 2007-11-01 15:33 Super·shen BLOG 閱讀(11142) | 評論 (13)編輯 收藏

    下邊的所有都是自己對JAVA的理解不知道對不對,有待于以后實踐驗證

    用JAVA編程,無論是什么框架,什么庫,什么插件, 他們的也還是來自 最基本java類編程。

    比如,我猜想 TOMCAT服務器,也是由一個帶MAIN方法的類來啟動的, 然后開通一個端口服務器,它的原理應該和java socket server編程應該是一個道理。主要是啟動一些類,來接受客戶端的請求(容器的原理應該是這樣吧)


    再說 servlet 也是基本的 JAVA類, 他們是受容器的管理,受到的是容器的調用(容器應該也就是帶main的java類),并對客戶端產生相應。

    還有像 jsp 的所謂表現層框架,最終也是調用到帶main函數的java類。 它的原理是 jsp編譯生產 servlet ,servlet 最終還是依靠容器。
    其實我想,自己也可以開發一個表現層,只要能實時編譯成servlet,就能和jsp一樣的功能了。
    不過jsp是sun公司的標準產品,它的庫已經集合在大多數容器上了,得到廣大容器的廣泛支持,出來得也早,用人也多,很少人想到要做新的表現層(如果沒什么好功能,就等于重復發明車輪)。

    FreeMarker 的原理也是一樣,簡單說它就是一個庫,你可以把它集合到容器里,得到容器的支持后,用FreeMarker 編寫的表現層就能實時編譯成servlet。  最后得到的和jsp 得到的是一個效果。
    FreeMarker 最終的結果還是容器調用。

    不過要做一個FreeMarker 可不簡單,要有好的想法,要不就和jsp功能重復了,沒價值。


    以上都是個人想出來的 不知道是否正確 有待于個人深入學習。



    posted @ 2007-09-17 11:46 Super·shen BLOG 閱讀(4468) | 評論 (5)編輯 收藏

    java 中文亂碼處理。

     
    參考
    http://china.eceel.com/article/study_for_character_encoding_java.htm
    http://upurban.com/bbs/viewtopic.php?t=246

    1。什么是utf-8,什么是ISO-8859-1,什么是GB2312,還有什么是unicode

    2。java 程序的字符的表示格式

    3。jsp 程序中文顯示處理實例

    3。1
    <%@ page  pageEncoding="ISO-8859-1"%>和<%@ page  pageEncoding="GB2312"%>和<%@ page 

    pageEncoding="UTF-8"%>各自的意思是什么,他們是否只對post提交有效!
    request.setCharacterEncoding("UTF-8")是什么意思?有什么區別?還有

    response.setCharacterEncoding("UTF-8"),優先于下邊
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    setCharacterEncoding()該函數用來設置http請求或者相應的編碼。

    對于request,是指提交內容的編碼,指定后可以通過getParameter()則直接獲得正確的字符串,如果不

    指定,則默認使用iso8859-1編碼,需要進一步處理。參見下述"表單輸入"。值得注意的是在執行

    setCharacterEncoding()之前,不能執行任何getParameter()。java doc上說明:This method must be

    called prior to reading request parameters or reading input using getReader()。而且,該指定

    只對POST方法有效,對GET方法無效。分析原因,應該是在執行第一個getParameter()的時候,java將會

    按照編碼分析所有的提交內容,而后續的getParameter()不再進行分析,所以setCharacterEncoding()無

    效。而對于GET方法提交表單是,提交的內容在URL中,一開始就已經按照編碼分析所有的提交內容,

    setCharacterEncoding()自然就無效。

    對于response,則是指定輸出內容的編碼,同時,該設置會傳遞給瀏覽器,告訴瀏覽器輸出內容所采用的

    編碼。
     
    3.2. jsp輸出

    指定文件輸出到browser是使用的編碼,該設置也應該置于文件的開頭。例如:<%@ page

    contentType="text/html; charset= GBK" %>。該設置和response.setCharacterEncoding("GBK")等效。

     

    4。java EE程序利用過濾器 處理中文問實例
    提交數據的編碼格式
    tomcat默認提交格式是ISO-8859-1
    可以通過設置過濾器(只針對post提交)或修改server.xml 的URIencoding 編碼格式(只針對get提交)

    達到你想要的 數據提交編碼格式。

     

    總結

    ---by mylu 18:26 2007-5-20

    posted @ 2007-05-20 22:36 Super·shen BLOG 閱讀(1524) | 評論 (0)編輯 收藏

    ORM
    Object Relation Mapping
    對象 關系 映射

    對象 指實體域對象
    關系 關系數據


    模型

    概念模型(實體-屬性)
    關系數據模型(關系數據庫)
    域模型(對象)


    軟件分層

    v - 表述層
    c /

    ??? /業務層
    m- 持久層(hibernate 技術實現)
    ??? \數據層


    mvc 對應 各層次


    概念實體關系

    1對1
    1對多
    多對多


    表與表之間的關系 參照完整性

    外鍵
    多對多
    多對一


    域對象之間的 關系

    關聯 (一對一 一對多 多對多)
    依賴 (一個類需要訪問另外一個類)
    聚集 (一個類的對象是另一個類的一部分, 人和手)
    一般化 (繼承關系)


    域對象
    ?實體域對象? (實體EJB,POJO)
    過程域對象? (會話EJB,消息驅動EJB,POJO)
    事件域對象? ()

    在hibernate中 一般只關注 實體域對象 和 過程域對象


    域對象的關系

    ?域對象的關聯關系 是有方向的
    體現在類的編碼不一樣的

    單向關聯
    雙向關聯

    ?


    域對象的持久化
    把對象從內存中 保存到持久化設備中去

    ORM 與? ORM模式
    ORM模式是一種持久化技術,還有其他模式的持久化技術。如主動域模式(BMP),JDO模式,CMP模式。


    域模型和數據模型的各個不匹配之處
    1,繼承
    2,多對多
    3,雙向
    4。粒度
    盡量少連接查詢,很消耗時間的操作

    ?


    創建持久化類


    1。持久化類符合javabean的規范,包含一些屬性 以及對應的getxxx 色天下學習方法
    2。持久化類有一個id屬性,用來唯一表示類的每一個對象。 也叫OID 對象表示符
    3。Hibernate要求持久化類必須提供一個不帶參數的默認構造方法

    創建數據庫schema

    創建對象-關系映射文件

    (一般在eslispe中先創建數據庫 然后再創建持久化類以及映射文件)

    hibernate 映射類型


    hibernate的初始化

    static{

    try{
    //根據默認位置的hibernate配置文件創建 configuration實例
    Configuration config = new Configuration();
    config.addClass(Customer.class);
    //創建SessionFactory 實例
    sessionFactory = config.buildSessinoFactroy();
    }catch(Exception e){e.printStackTrace();}
    }


    SessionFactory 接口

    一個SessionFactory 實例是對應一個數據源的,應用從SessionFactory 獲取session實例對象
    1線程安全的
    2重量級的,不能隨意創建和銷毀她的實例。

    Session 接口

    1 Session接口是hibernate應用最為廣泛的接口。
    2 Session也被稱為持久化管理器,它提供和持久化相關的操作
    3 Session有以下特點
    ?a 不是線程安全的 所以應避免多線程共用一個Session實例
    ?b Session實例是輕量級的,所謂輕量級是指他的創建和銷毀不需要消耗太多的資源。意味著程序中可以經常創建和銷毀Session實例,保證不多線程使用Session對象。

    Session接口的常用方法:
    save()
    update()
    delete()
    load()

    Session執行事務流程

    Session session = factory.openSession();
    Transaction tx;
    try{
    tx = session.beginTranscation();
    //執行事務
    ...
    //提交事務
    tx.commit();
    }
    catche(Exception e)
    {//如果出現異常,撤消事務
    if(tx!=null)tx.rollback();
    throw e;
    }
    finally{
    session.close(); //不管事務是否成功,最后都要關閉session對象
    }
    }

    ?

    ?

    ?

    ?

    posted @ 2007-02-07 14:32 Super·shen BLOG 閱讀(412) | 評論 (0)編輯 收藏

    eXtremeComponents FAQ

    eXtremeComponents FAQ(中文版)

    Jeff Johnston

    Lucky

    冷月宮主

    版本0.1.0

    本文檔允許在遵守以下兩條原則的條件下被使用和傳播: 1)不能憑借本文檔索取任何費用 2)以任何方式(印刷物或電子版)使用和傳播時本文檔時,必須包含本版權申明

    (更新中...)


    eXtremeComponents FAQ(中文)


    1.?如何使用導出功能

    Q: 如何使用導出功能

    A: 為了使用導出功能,只需要在web.xml文件中加入eXtremeComponents的導出過濾器的配置,內容如下:

    <filter>
    <filter-name>eXtremeExport</filter-name>
    <filter-class>org.extremecomponents.table.filter.ExportFilter</filter-class>
    <init-param>
    <param-name>responseHeadersSetBeforeDoFilter</param-name>
    <param-value>true</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>eXtremeExport</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    2.?傳入中文參數亂碼

    Q: 傳入中文參數亂碼,如下頁面:

    		<form id="form1" name="form1" method="post" action="應用eXtremeTable的action或是結果頁面名">
    <select name="selecttype" size="6">
    <option value="第一個">第一個</option>
    <option value="第二個">第二個</option>
    <option value="第三個">第三個</option>
    </select>
    <input type="text" name="username" />
    <input type="submit" name="Submit" value="提交" />
    </form>

    當你提交時含有eXtremeTable的結果頁面會自動取得頁面上的表單參數,那怕是經過了action的mapping.findForward("forward"),在我的試用過程中到頁面上會出現傳遞過去的參數,但出現了亂碼問題,使用查詢(filter)功能是的中文參數問題類似。

    A:

    1. 確認服務器的參數是否設置了正確的編碼,如果使用Tomcat請確認Server.xml:

       <Connector port="80" URIEncoding="UTF-8" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false"
      redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" />
    2. 添加編碼過濾器到你的應用工程:

      /*
      * Copyright 1999-2001,2004 The Apache Software Foundation.
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
      *
      * http://www.apache.org/licenses/LICENSE-2.0
      *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      * See the License for the specific language governing permissions and
      * limitations under the License.
      */


      package filters;


      import java.io.IOException;
      import javax.servlet.Filter;
      import javax.servlet.FilterChain;
      import javax.servlet.FilterConfig;
      import javax.servlet.ServletException;
      import javax.servlet.ServletRequest;
      import javax.servlet.ServletResponse;
      import javax.servlet.UnavailableException;


      /**
      * <p>Example filter that sets the character encoding to be used in parsing the
      * incoming request, either unconditionally or only if the client did not
      * specify a character encoding. Configuration of this filter is based on
      * the following initialization parameters:</p>
      * <ul>
      * <li><strong>encoding</strong> - The character encoding to be configured
      * for this request, either conditionally or unconditionally based on
      * the <code>ignore</code> initialization parameter. This parameter
      * is required, so there is no default.</li>
      * <li><strong>ignore</strong> - If set to "true", any character encoding
      * specified by the client is ignored, and the value returned by the
      * <code>selectEncoding()</code> method is set. If set to "false,
      * <code>selectEncoding()</code> is called <strong>only</strong> if the
      * client has not already specified an encoding. By default, this
      * parameter is set to "true".</li>
      * </ul>
      *
      * <p>Although this filter can be used unchanged, it is also easy to
      * subclass it and make the <code>selectEncoding()</code> method more
      * intelligent about what encoding to choose, based on characteristics of
      * the incoming request (such as the values of the <code>Accept-Language</code>
      * and <code>User-Agent</code> headers, or a value stashed in the current
      * user's session.</p>
      *
      * @author Craig McClanahan
      * @version $Revision: 1.3 $ $Date: 2004/02/28 03:35:22 $
      */

      public class SetCharacterEncodingFilter implements Filter {


      // ----------------------------------------------------- Instance Variables


      /**
      * The default character encoding to set for requests that pass through
      * this filter.
      */
      protected String encoding = null;


      /**
      * The filter configuration object we are associated with. If this value
      * is null, this filter instance is not currently configured.
      */
      protected FilterConfig filterConfig = null;


      /**
      * Should a character encoding specified by the client be ignored?
      */
      protected boolean ignore = true;


      // --------------------------------------------------------- Public Methods


      /**
      * Take this filter out of service.
      */
      public void destroy() {

      this.encoding = null;
      this.filterConfig = null;

      }


      /**
      * Select and set (if specified) the character encoding to be used to
      * interpret request parameters for this request.
      *
      * @param request The servlet request we are processing
      * @param result The servlet response we are creating
      * @param chain The filter chain we are processing
      *
      * @exception IOException if an input/output error occurs
      * @exception ServletException if a servlet error occurs
      */
      public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain)
      throws IOException, ServletException {

      // Conditionally select and set the character encoding to be used
      if (ignore || (request.getCharacterEncoding() == null)) {
      String encoding = selectEncoding(request);
      if (encoding != null)
      request.setCharacterEncoding(encoding);
      }

      // Pass control on to the next filter
      chain.doFilter(request, response);

      }


      /**
      * Place this filter into service.
      *
      * @param filterConfig The filter configuration object
      */
      public void init(FilterConfig filterConfig) throws ServletException {

      this.filterConfig = filterConfig;
      this.encoding = filterConfig.getInitParameter("encoding");
      String value = filterConfig.getInitParameter("ignore");
      if (value == null)
      this.ignore = true;
      else if (value.equalsIgnoreCase("true"))
      this.ignore = true;
      else if (value.equalsIgnoreCase("yes"))
      this.ignore = true;
      else
      this.ignore = false;

      }


      // ------------------------------------------------------ Protected Methods


      /**
      * Select an appropriate character encoding to be used, based on the
      * characteristics of the current request and/or filter initialization
      * parameters. If no character encoding should be set, return
      * <code>null</code>.
      * <p>
      * The default implementation unconditionally returns the value configured
      * by the <strong>encoding</strong> initialization parameter for this
      * filter.
      *
      * @param request The servlet request we are processing
      */
      protected String selectEncoding(ServletRequest request) {

      return (this.encoding);

      }


      }
    3. 在web.xml中添加編碼過濾器配置:

       <filter>
      <filter-name>Set Character Encoding</filter-name>
      <filter-class>filters.SetCharacterEncodingFilter</filter-class>
      <init-param>
      <param-name>encoding</param-name>
      <param-value>gb2312</param-value>
      </init-param>
      </filter>
      <filter-mapping>
      <filter-name>Set Character Encoding</filter-name>
      <url-pattern>/*</url-pattern>
      </filter-mapping>

    3.?導出時中文文件名亂碼

    Q:關于導出時中文文件名為亂碼的問題

    A: 這是個bug,建議使用英文文件名,主要原因還是編碼問題。我們現在正在想辦法解決。

    4.?導出時文件內容亂碼

    Q:導出時文件內容亂碼

    A:首先請確認使用的是extremecomponents-1.0.1-M5-A4版以后的版本

    1. Excle: 導出為Excle的中文問題已經修正,默認的情況下支持導出中文,用戶不需要任何改動
    2. PDF : 由于extremecomponents使用了FOP來生成PDF文件,FOP在導出中文內容時會產生亂碼。具體的解決方案 大家可以參考最新eXtremeComponents包:支持 PDF中文導出

    5.?變量命名問題

    Q:當變量名為"action",在IE下執行產生javascript錯誤

    A: 內部使用了一些關鍵字,就目前我所知的為"action"、"submit"。建議大家命名時盡量避免,如果大家必須使用,則可以使用table標簽的autoIncludeParameters參數設置為"false":

    autoIncludeParameters="false"

    6.?格式化輸出表單中的數據

    Q:怎么樣格式化輸出表單中的數據

    A: 你可以設置列的cell:

    1. 日期格式化: cell = " date " format = " yyyy-MM-dd "
    2. 數字格式化: cell="currency" format="###,###,##0.00"

    詳細信息請參考指南

    7.?加入鏈接

    Q:怎么樣加入鏈接

    A: 你可以參考下例:

                <ec:table
    var="pres"
    items="presidents"
    action="${pageContext.request.contextPath}/compact.run"
    imagePath="${pageContext.request.contextPath}/images/table/compact/*.gif"
    view="compact"
    title="Compact Toolbar View"
    showTooltips="false"
    >
    <ec:exportPdf
    fileName="output.pdf"
    tooltip="Export PDF"
    headerColor="black"
    headerBackgroundColor="#b6c2da"
    headerTitle="Presidents"
    text="PDF"
    />
    <ec:exportXls
    fileName="output.xls"
    tooltip="Export Excel"
    text="XLS"
    />
    <ec:row>
    <ec:column property="fullName" title="Name">
    <a >${pres.fullName}</a>
    </ec:column>
    <ec:column property="nickName"/>
    <ec:column property="term"/>
    <ec:column property="born" cell="date"/>
    <ec:column property="died" cell="date"/>
    <ec:column property="career"/>
    </ec:row>
    </ec:table>

    8.?行高亮顯示

    Q: 我想使用行的高亮顯示如何設置

    A: 你只需要設置行標簽的highlightRow屬性: highlightRow="true"。eXtremeComponents提供了很多接口允許用戶按照自己的習慣來進行定制,包括:CSS、CELL、View。相關信息請參考指南。



    by lucky
    posted @ 2007-01-26 16:04 Super·shen BLOG 閱讀(280) | 評論 (0)編輯 收藏
    》對象之間方法調用,通過傳遞消息

    OOP使各個對象各司其職,分別負擔執行一組相關的任務,如果一個對象要依賴于一個不在其范圍內的方法,它就需要訪問包含該方法的第二個對象,即第一個對象需要第二個對象執行這個方法(或者叫方法調用) 利用OOP術語,叫做一個對象向另外一個對象發送消息。

    》對象的生成: 對象是在執行過程中由其所屬的類動態生成的。 一個類可以生成多個不同的對象。


    》 消息與方法的概念

    對象之間的傳遞通過消息傳遞完成

    一個發送消息的對象 發送的消息包含3個方面的內容
    1,接受消息的對象
    2,接受對象應用的方法。
    3,方法所需要的參數。

    》面向對象變成的基本特征
    1 封裝性 Encapsulation 把數據和操作組織在類內
    2?繼承性 Inheritance 通過類的繼承關系
    3多態性Polymophism(在運行的時候體現) ??A通過方法重裁 B通過方法重寫,子類覆蓋父類的方法(接口一個種特殊的類哦)

    posted @ 2007-01-24 17:47 Super·shen BLOG 閱讀(358) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 精品久久久久久国产免费了| 国产精品区免费视频| 亚洲狠狠爱综合影院婷婷| 中文字幕免费在线看电影大全| 久久亚洲AV成人出白浆无码国产 | 中文字幕在线观看免费视频| 亚洲成a人片在线观看精品| 免费大黄网站在线观| 无码成A毛片免费| 亚洲AV综合永久无码精品天堂| 亚洲色欲一区二区三区在线观看| 2021精品国产品免费观看 | 猫咪www免费人成网站| 亚洲国产日韩一区高清在线| 女人被男人桶得好爽免费视频| a级毛片视频免费观看| 亚洲日韩久久综合中文字幕| 亚洲情XO亚洲色XO无码| 丁香花在线观看免费观看| 国产在线观看xxxx免费| 亚洲午夜无码久久久久小说 | 亚洲福利视频网站| 亚洲免费在线观看| 成人午夜大片免费7777| 99视频在线看观免费| 一级毛片**免费看试看20分钟| 亚洲国产成人精品无码区在线秒播| 亚洲人成电影网站国产精品| 成人免费777777| 亚洲精品视频免费在线观看| a级毛片免费在线观看| 男男gay做爽爽免费视频| 亚洲图片校园春色| 久久亚洲精品视频| 亚洲国产一级在线观看 | fc2成年免费共享视频网站| 亚洲三级在线观看| 麻豆亚洲av熟女国产一区二| 亚洲中文字幕无码永久在线| 国产成人精品免费直播| 在线观看免费为成年视频|