随笔-40  评论-66  文章-0  trackbacks-0
  2006年12月14日
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 阅读(1780) | 评论 (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 阅读(483) | 评论 (0)编辑 收藏

普遍的,简单的权限系统要求:

1.系统所有资源定义 [资源表]   ( 还可以分为更小的权限表,操作表,这里通叫资源表)
2.定义角色 [角色表]
3.给角色指定资源(一个角色可以管理多个资源) [角色-资源表]
4.定义用户组 [用户表]
5.给用户组指定角色(一个用户组可以拥有多种角色) [用户组-角色表]
6.给用户指定角色(一个用户可以拥有多种角色,可以直接指定角色,也可以继承用户组的角色)[用户-角色表]

 


查找权限时:

根据用户ID[用户-角色表]或用户组ID[用户组-角色表],查到所有角色ID,再[角色-资源表]找到所有角色下的所有资源。

此就是用户拥有的资源。(资源一般为模块,当然也可以分更细的定义为页面,操作方法等)


此权限设计适合于模块化访问系统,如OA


当然很多系统因地而已,不可能完全满足,按照自己系统需求设计是最合适的设计。



posted @ 2008-08-18 16:17 Super·shen BLOG 阅读(784) | 评论 (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 阅读(1650) | 评论 (1)编辑 收藏

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

posted @ 2008-02-28 14:19 Super·shen BLOG 阅读(724) | 评论 (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 阅读(1456) | 评论 (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 阅读(2743) | 评论 (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 阅读(729) | 评论 (0)编辑 收藏
http://samhe.javaeye.com/blog/142416
posted @ 2008-01-18 17:14 Super·shen BLOG 阅读(300) | 评论 (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 阅读(40991) | 评论 (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 阅读(302) | 评论 (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://www.blogjava.net/beansoft

posted @ 2008-01-08 10:05 Super·shen BLOG 阅读(670) | 评论 (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 阅读(5475) | 评论 (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 阅读(1914) | 评论 (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 阅读(3108) | 评论 (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 阅读(1375) | 评论 (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 阅读(295) | 评论 (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 阅读(16602) | 评论 (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 阅读(11098) | 评论 (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 阅读(4451) | 评论 (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 阅读(1512) | 评论 (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 阅读(397) | 评论 (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 href="http://www.whitehouse.gov/history/presidents/">${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 阅读(272) | 评论 (0)编辑 收藏
》对象之间方法调用,通过传递消息

OOP使各个对象各司其职,分别负担执行一组相关的任务,如果一个对象要依赖于一个不在其范围内的方法,它就需要访问包含该方法的第二个对象,即第一个对象需要第二个对象执行这个方法(或者叫方法调用) 利用OOP术语,叫做一个对象向另外一个对象发送消息。

》对象的生成: 对象是在执行过程中由其所属的类动态生成的。 一个类可以生成多个不同的对象。


》 消息与方法的概念

对象之间的传递通过消息传递完成

一个发送消息的对象 发送的消息包含3个方面的内容
1,接受消息的对象
2,接受对象应用的方法。
3,方法所需要的参数。

》面向对象变成的基本特征
1 封装性 Encapsulation 把数据和操作组织在类内
2 继承性 Inheritance 通过类的继承关系
3多态性Polymophism(在运行的时候体现)   A通过方法重裁 B通过方法重写,子类覆盖父类的方法(接口一个种特殊的类哦)

posted @ 2007-01-24 17:47 Super·shen BLOG 阅读(346) | 评论 (0)编辑 收藏
域对象之间的4种关系

1。关联

指类之间的引用关系,是实体域对象的最普遍的关系。
一对一、一对多、多对多关联

如果类A和类B关联,那么被引用的B将被定义为A的属性。

Customer  与 Order 是一对多的关联关系

Order 类 包含 Customer类的 属性

Customer  类 包含  集合 Order 


2。依赖

posted @ 2006-12-30 16:30 Super·shen BLOG 阅读(234) | 评论 (0)编辑 收藏


一个J2EE 工程中涉及的对象

  • 数据传输对象DTO
  • 业务对象BO (实体业务对象 过程业务对象 事件业务对象)
  • 数据访问对象DAO

 


概念

持久化框架、ORM框架、DAO设计模式

他们的关系是:ORM框架是一种持久化框架,DAO是用于实现持久化框架的一种设计模式。

posted @ 2006-12-27 17:14 Super·shen BLOG 阅读(397) | 评论 (0)编辑 收藏
 ActionErrors   errors   =   null;    
  errors   =   new   ActionErrors();    
  errors.add("isExist",   new   ActionError("error.isExist"));   
// errors.add("isExist",   new   ActionError("error.isExist"));   等效于errors.add("isExist",   new   ActionMessage("error.isExist"));    

  saveErrors(request,   errors);  
  return   (mapping.findForward("failure"));   


failure页面里也定义了<html:errors   name="isExist"/>  
  ApplicationResources.properties里面也定义了error.isExist=user   have   already   exist!!!   
  运行结果 跳转到failure页面,显示“user   have   already   exist!!!   ”




ActionErrors.GLOBAL_ERROR
怎么理解
它和我们使用普通的字符有什么区别啊

部分代码如下:
err.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.logon"));
err.add("errinfo", new ActionError("error.logon"));

以上两名有什么区别啊


没什么区别
ActionErrors.GLOBAL_ERROR也是一个字符串。
最好写做ActionErrors.GLOBAL_ERROR
不然的话可能会报错。


posted @ 2006-12-20 18:03 Super·shen BLOG 阅读(2582) | 评论 (3)编辑 收藏
和女主角Action 对象共舞

什么是Action?
和常规的web 应用相比,Struts Action 类工作起来就象一个小型的servlet。在大多数Java
应用中,诸如访问业务层的任务、错误处理等任务均是由servlet 承担的。在一个 Struts 应
用中,servlet 扮演着一个分派器的角色。而Action 对象则干实际的工作。象 servlets 一样,
Action 对象是多线程的。每个应用只需要一个Action 类的实例。

Action做些什么?

一个典型的Action 的职责通常是:

􀂄 ■校验前提条件或者声明
􀂄 ■调用需要的业务逻辑方法
􀂄 ■检测其它处理错误
􀂄 ■将控制路由到相关视图


检验输入: Action 需要做的就是确认ActionForm 是否是需要的类型。

调用逻辑业务:

Action 类是HTTP 与应用系统中其它部分之间的适配器。最重要的是要避免将业务逻辑放入
Action 之中。Action 类应该只是简单地收集业务方法需要的数据并传递它到具体的业务对
象。如果你同时在编写业务类和Action 类,可能会受到要将它们编写在一起的诱惑。一定
要抵挡这种诱惑,并且将业务方法放入Action 可调用的单独的类之中。Java 虚拟机(JVM)
针对这种方法调用作了优化;性能损失可以忽略不计。
同时你也得到了一些设计上的优势

Action检测错误:
Struts具有一个设计良好的错误处理系统,允许你可以:
􀂄■ 同时截获几个错误
􀂄■ 在请求中传递错误数据包
􀂄■ 显示本地化信息

这个处理流程涉及到两个对象 (ActionErrors 和 ActionError) 和一个注册错误的工
具方法(saveErrors) 。其它两个对象 (MessageResources 和 一个定制标签)则用来显
示错误信息

注册错误
总体流程归结为:
􀂄1 创建一个空的ActionErrors 实例
􀂄2 在错误发生时,为错误信息添加关键字;
􀂄3 检查是否添加了某些信息
􀂄4 保存ActionErrors 集合对象到请求中
􀂄5  转发控制到错误页面以显示信息
􀂄6  否则,正常继续

例如
ActionErrors errors = new ActionErrors();
try {
// * 调用业务对象 *
}

catch (ModelException e) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.detail",e.getMessage()));
}

if (!errors.empty()) {
saveErrors(Request, errors);
return (mapping.findForward("error"));
}

// * 正常继续 *

posted @ 2006-12-14 10:32 Super·shen BLOG 阅读(411) | 评论 (0)编辑 收藏