随笔-40  评论-66  文章-0  trackbacks-0
  2006年11月21日
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 阅读(1779) | 评论 (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 阅读(783) | 评论 (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 阅读(40990) | 评论 (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 阅读(1374) | 评论 (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 阅读(11096) | 评论 (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 阅读(4449) | 评论 (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 阅读(1511) | 评论 (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 阅读(396) | 评论 (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 阅读(345) | 评论 (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 阅读(2581) | 评论 (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 阅读(410) | 评论 (0)编辑 收藏
用Struts开发Web应用

要使用Struts 开发web 应用,开发人员将需要的超链接定义为ActionForward,HTML 表
单定义为ActionForm,定制的服务器端动作定义为Action 类。
需要访问JDBC 和EJB 的开发人员也可通过Action 对象进行他们的工作。这样,表现层不
需要和Model 层打交道。Struts Action 对象将收集View 需要的数据,然后将它们转发到
表现页面。Struts 提供 JSP 标记库,它们将和JSP 页面一起使用,简化 HTML 表单和访
问Action 要转发的其它数据。其它表现机制,比如Velocity templates, 也可用来访问
Struts 框架,以创建动态的web 页面。这种处理流程入下图:{D99B93EF-D27B-42BA-A010-CB465E53C7BD}.BMP



{A1ABCBA2-B893-4911-8786-5CF86A796AFB}.JPG
posted @ 2006-12-06 17:50 Super·shen BLOG 阅读(277) | 评论 (0)编辑 收藏

 

Java本身就支持多国语言编码,不需要写任何程序,可以很简单的
实现。
秘诀就是两点:

1、所有HTML/JSP页面全部采用UTF-8编码

2、客户端浏览器完全支持UTF-8编码

步骤:
1、首先把所有的HTML/JSP的ContentType都设为UTF-8

2、然后对于JSP程序中的非ASCII码提示信息都不应该写在程序里面,都应该放在
application.properties里面统一管理。

3、对HTML用native2ascii工具统一做一次处理,把HTML中的非ASCII码都转换为Unicode编码。

4、针对不同的语言,写不同的application.properties,比如说简体中文是
application_zh_CN.properties,繁体中文是application_zh_TW.properties这样,然后对这些配置信
息文件同样用native2ascii工具处理一次,把非ASCII码统统转为Unicode编码。

5、在Servlet的request.getCharacterEncoding()获得客户端的操作系统默认编码,然后set到Struts
的HTTPSession的Locale中。

OK!现在不同的客户访问,就会显示不同的语言版本了。你可以看看此时你的浏览器的字符集,就是
UTF-8。现在你的网站和Google一样了,嘿嘿,其实你有心的话,看看你的浏览器访问Google的时候是
什么字符集吧

切记:所有的HTML/JSP都要设为UTF-8编码,所有的文件中的非ASCII码字符都要用native2ascii工具转
为用ASCII表示的Unicode编码。
----------------------------------------
----------------------------------------
原创
----------------------------------------
上面所述是我从网上下的一篇于中文问题的解决方案,确切的说应该是关于Struts的国际化问题,下面我结合我的实践谈谈具体如何实现Struts的国际化问题,我对理论不是非常精通,我只能完全凭自己的理解和实践来讲述,所以下面讲的内容可能不是非常正确,还请大家原谅。但有一点可以肯定,我通过自己的努力解决了Struts的中文问题,并实现Struts的国际化,其实一切并不复杂,下面是具体步骤:

0.遇到的问题(这些问题也许不会同时出现)
a.中文数据从数据库中到jsp中后就变成了"????"
b.做好的中文properties文件,其中的中文value在页面显示乱码
c.jsp文件中的中文到浏览器后显示时也是乱码(建议不要在jsp文件中输入中文,尽量放在properties文件中)
d.由jsp传给bean的中文值,再由bean传回页面又是乱码
e.当更换本地浏览器的语言选项时,Web应用程序不能自动根据你的locale选择合适的*.properties文件。导致Web应用程序不能国际化。
1.环境:
Web服务器: Tomcat 5.0.19
操作系统: Win2000 Server
JVM : jdk 1.4
数 据 库: Oracle 8.1.7
开发工具: struts studio 5.2 pro for eclipse
2.先将所有*.jsp 网页中开头处加入

<%@ page language="java" contentType="text/html; charset=utf-8" %>
再设置<html:html locale = "true">

3.然后编辑好两个*.properties文件,放在classes文件夹下你指定的地方,这里是放在/web-inf/classes/com/wiley 下,它们分别是:

ApplicationResources.properties (英文资源文件)
ApplicationResources_zh.properties (中文资源文件)
随便用什么工具编写都行啊!
4.将ApplicationResources_zh.properties转码成gb2312。上面引文说要转成UTF-8,结果我试了,不行。转成gb2312就行了,操作是。
将ApplicationResources_zh.properties更名为ApplicationResources_xx.properties
在DOS命令行进入ApplicationResources_xx.properties所在的文件夹
使用命令:native2ascii -encoding gb2312 ApplicationResources_xx.properties ApplicationResources_zh.properties(至于你为什么会出现“native2ascii不是内部命令”,,请查其它资料,可能你要设置环境变量,因为他是jdk的文件夹bin下的一个应用程序)
5.接下来配置struts-config.xml,很简单,我们加入:

<message-resources parameter="com.wiley.ApplicationResources"/> 就行了;

到此已能解决大多数中文问题。如上面所说的a,b,e 现在打开浏览器,选择菜单:工具》internet选项》语言,将“中文-中国[zh-cn]”删掉,添加一个“英语-英国[zh-gb]”确定后,重启Tomcat,输入网址你就会发现,你的页面的文本信息就会用的是ApplicationResources.properties (英文资源文件)中的内容。如果换回“中文-中国[zh-cn]”,它就会显示ApplicationResources_zh.properties (中文资源文件)中的中文内容。

至于问题“c.jsp文件中的中文到浏览器后显示时也是乱码” 你就要用与第4步类似的方法来重新对*.jsp 文件编码,这时-encoding的参数就要用UTF-8了,如果你用的也是struts studio 5.2 pro for eclipse工具,这一步就免了。它会自动用UTF-8的格式存储。
至于问题“d.由jsp传给bean的中文值,再由bean传回页面又是乱码”的解决,我只是加了个过滤器。
你可以现在web.xml中加入:
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.wiley.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<servlet-name>action</servlet-name>
</filter-mapping>

然后在你指定的包内加个java文件 我放在了/web-inf/classes/com/wiley 里,下面是源代码:
/*
* XP Forum
*
* Copyright (c) 2002-2003 RedSoft Group. All rights reserved.
*
*/
package com.huahang.tj.struts.filters;

import javax.servlet.*;
import java.io.IOException;

/**
* <p>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 <a href="mailto:jwtronics@yahoo.com">John Wong</a>
*
* @version $Id: SetCharacterEncodingFilter.java,v 1.1 2002/04/10 13:59:27 johnwong Exp $
*/
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);

}

}//EOC
到此我遇到的中文问题已全部得到解决,并从中理解到struts的国际化的深刻含义。
我个人觉得struts作为一个功能强大的应用框架,应该早就考虑到它的国际化问题,并在实际应用中不会很复杂,只要我们遵循一些规则,就可以尽情享受struts给我们带来的无穷乐趣。希望以上所述对大家有所帮助。
posted @ 2006-12-06 16:46 Super·shen BLOG 阅读(252) | 评论 (0)编辑 收藏

Cannot retrieve mapping for action

异常
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login (/Login是你的action名字)




可能原因
action没有再struts-config.xml 中定义,或没有找到匹配的action,例如在JSP文件中使用 <html:form action="Login.do".将表单提交给Login.do处理,如果出现上述异常,请查看struts-config.xml中的定义部分,有时可能是打错了字符或者是某些不符合规则,可以使用struts console工具来检查。





Cannot retrieve definition for form bean null

异常
org.apache.jasper.JasperException: Cannot retrieve definition for form bean null

可能原因

这个异常是因为Struts根据struts-config.xml中的mapping没有找到action期望的form bean。大部分的情况可能是因为在form-bean中设置的name属性和action中设置的name属性不匹配所致。换句话说,action和form都应该各自有一个name属性,并且要精确匹配,包括大小写。这个错误当没有name属性和action关联时也会发生,如果没有在action中指定name属性,那么就没有name属性和action相关联。当然当action制作某些控制时,譬如根据参数值跳转到相应的jsp页面,而不是处理表单数据,这是就不用name属性,这也是action的使用方法之一。





No action instance for path /xxxx could be created

异常
No action instance for path /xxxx could be created

可能原因
特别提示:因为有很多中情况会导致这个错误的发生,所以推荐大家调高你的web服务器的日志/调试级别,这样可以从更多的信息中看到潜在的、在试图创建action类时发生的错误,这个action类你已经在struts-config.xml中设置了关联(即添加了<action>标签)。

在struts-config.xml中通过action标签的class属性指定的action类不能被找到有很多种原因,例如:

定位编译后的.class文件失败。Failure to place compiled .class file for the action in the classpath (在web开发中,class的的位置在r WEB-INF/classes,所以你的action class必须要在这个目录下。例如你的action类位于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设置action的属性type时就是action.Login).
拼写错误,这个也时有发生,并且不易找到,特别注意第一个字母的大小写和包的名称。

在struts-config.xml中指定的action类没有继承自Stuts的Action类,或者你自定义的Action类没有继承自Struts提供的Action类。

你的action类必须继承自Struts提供的Action类。

你的classpath的问题。例如web server没有发现你的资源文件,资源文件必须在WEB-INF/classes/目录下。

Problem in struts-config.xml file with action mapping.

Problem with data-sources.xml file.

相关链接
http://www.mail-archive.com/struts-user ... org/msg65874.html
Action Mapping mistake in struts-config.xml:
http://www.manning.com/ao/readforum.ht ... mp;readthread=177
data-sources.xml file?:
http://www.caucho.com/quercus/faq/section.xtp?section_id=30





No getter method for property XXXX of bean org.apache.struts.taglib.html.BEAN

异常
javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN

可能原因
没有位form bean中的某个变量定义getter 方法

这个错误主要发生在表单提交的FormBean中,用struts标记<html:text property=”username”>时,在FormBean中必须有一个getUsername()方法。注意字母“U”。

Related Links
Case can trip up the matching between get method's name and name specified in Struts tag
http://saloon.javaranch.com/cgi-bin/ubb/ultimate ... c&f=58&t=000163





java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm

错误
java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm

可能原因
这个错误主要发生在在classpath中找不到相应的Java .class文件。如果这个错误发生在web应用程序的运行时,主要是因为指定的class文件不在web server的classpath中(/WEB-INF/classes 和 /WEB-INF/lib)。

在上面的错误中,原因是找不到ActionForm类。

This error is sometimes seen when one or more ActionForm.class instances are actually in the classpath. This most often occurs when ActionForm.class is made available correctly by placing struts.jar in the /WEB-INF/lib directory. When this library has been correctly placed and it is verified that ActionForm.class actually is present in the struts.jar file, the problem is either that more than one copy of ActionForm.class is in the classpath or (more likely) that duplicate versions of class files other than ActionForm are in the same classpath, causing confusion. This is especially true if a class that extends ActionForm is made available twice, such as in an .ear file that encompasses a .war file as well as in the .war file's own classpath (/WEB-INF/classes). This problem can be resolved by guaranteeing that there are no redundant classes, especially those related to Struts (directly from Struts or extensions of Struts), in the web application's view.

相关连接
EJB and Web Shared Links:
http://forum.java.sun.com/thread.jsp?forum=26&am ... ;tstart=0&trange=15
Keep Action and ActionForm (and their children) as non-overlapping unit(s) of an application
http://www.mail-archive.com/struts-u ... ache.org/msg47466.html
http://www.mail-archive.com/struts-user ... org/msg47467.html





Exception creating bean of class org.apache.struts.action.ActionForm: {1}

异常
javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}

可能原因
Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This might occur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this class for the form-bean.

Not associating an ActionForm-descended class with an action can also lead to this error.

Related Links






Cannot find ActionMappings or ActionFormBeans collection

Exception
javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection

可能原因
不是标识Struts actionServlet的<servlet>标记就是映射.do扩展名的<sevlet-mapping>标记或者两者都没有在web.xml中声明。

在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺少一个标记的关闭符号/>。最好使用struts console工具检查一下。

另外,load-on-startup必须在web.xml中声明,这要么是一个空标记,要么指定一个数值,这个数值用来表servlet运行的优先级,数值越大优先级越低。

还有一个和使用load-on-startup有关的是使用Struts预编译JSP文件时也可能导致这个异常。

相关链接
Explicitly Define <load-on-startup>
http://saloon.javaranch.com/cgi-bin/ubb/ultim ... topic&f=50&t=001055
http://threebit.net/tutorials/ejb/general/





NullPointerException at ... RequestUtils.forwardURL

异常
java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)

可能原因
在struts-config.xml中的forward元素缺少path属性。例如应该是如下形式:
<forward name="userhome" path="/user/userhome.jsp"/>





Cannot find bean org.apache.struts.taglib.html.BEAN in any scope

Exception
javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope




Probable Causes
试图在Struts的form标记外使用form的子元素。这常常发生在你在</html:form>后面使用Struts的html标记。

另外要注意可能你不经意使用的无主体的标记,如<html:form … />,这样web 服务器解析时就当作一个无主体的标记,随后使用的所有<html>标记都被认为是在这个标记之外的,如又使用了<html:text property=”id”>

还有就是在使用taglib引入HTML标记库时,你使用的prefix的值不是html。

相关连接
Using form subelements outside of a form tag
http://forum.java.sun.com/thread.jsp?thread= ... &message=1384153





Missing message for key xx.xx.xx

Exception
javax.servlet.jsp.JspException: Missing message for key xx.xx.xx

Probable Causes
这个key的值对没有在资源文件ApplicationResources.properties中定义。如果你使用eclipse时经常碰到这样的情况,当项目重新编译时,eclipse会自动将classes目录下的资源文件删除。

资源文件ApplicationResources.properties 不在classpath中 应将资源文件放到 WEB-INF/classes 目录下,当然要在struts-config.xml中定义)





Cannot find message resources under key org.apache.struts.action.MESSAGE

异常
Cannot find message resources under key org.apache.struts.action.MESSAGE

可能原因
很显然,这个错误是发生在使用资源文件时,而Struts没有找到资源文件。

Implicitly trying to use message resources that are not available (such as using empty html:options tag instead of specifying the options in its body -- this assumes options are specified in ApplicationResources.properties file)

XML parser issues -- too many, too few, incorrect/incompatible versions

Related Links
Provide Struts with Resource Bundle
http://threebit.net/tutorials/ejb/general/
XML Parser Issues
http://www.mail-archive.com/struts-user ... org/msg15779.html





No input attribute for mapping path /loginAction

错误
No input attribute for mapping path /xxxxAction

可能原因e
No input attribute in action mapping in struts-config.xml file for the action with the name specified in the error message. An input attribute is not required if form validation is not performed (either because the validate attribute is set to false or because the validation method in the relevant form class is not implemented. The input attribute specifies the page leading to this action because that page is used to display error messages from the form validation.

Related Links






Strange Output Characters

错误
Strange and seemingly random characters in HTML and on screen, but not in original JSP or servlet.

可能原因
混和使用Struts的html:form标记和标准的HTML标记不正确。

使用的编码样式在本页中不支持。





"Document contained no data" or no data rendered on page

错误
"Document contained no data" in Netscape

No data rendered (completely empty) page in Microsoft Internet Explorer

可能原因
使用一个Action的派生类而没有实现perform()方法或execute()方法。在Struts1.0中实现的是perform()方法,在Struts1.1中实现的是execute()方法,但Struts1.1向后兼容perform()方法。

但你使用Struts1.1创建一个Action的派生类,并且实现了execute()方法,而你在Struts1.0中运行的话,就会得到"Document contained no data" error message in Netscape or a completely empty (no HTML whatsoever) page rendered in Microsoft Internet Explorer.”的错误信息。


posted @ 2006-12-06 16:44 Super·shen BLOG 阅读(478) | 评论 (0)编辑 收藏
Action类

用来访问业务逻辑类。当 ActionServlet 从容器接收到一个请求,它使用URI (或者路径
“path”) 来决定那个Action 将用来处理请求。一个 Action 可以校验输入,并且访问业务
层以从数据库或其他数据服务中检索信息。


ActionForm类

为校验输入或者使用输入来更新数据库, Action 需要知道什么值被提交上来。它并不是强
制每个Action 都要从请求中抓取这些值,而是由 ActionServlet 将输入绑定到JavaBean中。
输入 bean 就是Struts ActionForm 类的子类。ActionServlet 通过查找请求的路径可以决定使
用哪个ActionForm , Action 也是通过同样的方法选取的。ActionForm 扩展了
org.apache.struts.action.ActionForm 类

每个请求都必须以HTTP 响应进行应答。 通常,Struts Action 并不自行渲染响应信息,
而是将请求转发到其他资源,比如JSP 页面。Struts 提供一个ActionForward 类,用来将
一个页面的路径保存为逻辑名称。当完成业务逻辑后,Action 选择并向Servlet 返回一个
ActionForward。Servlet 然后使用保存在ActionForward 对象中的路径来调用页面完成响
应。

Struts 将这些细节都绑定在一个ActionMapping 对象中。每个ActionMapping 相对于一个
特定的路径。当某个路径被请求时,Servlet 就查询ActionMapping 对象。ActionMapping
对象告诉servlet,哪些个Action,ActionForm,和 ActionForward 将要被本次请求使用。
所有这些细节,关于Action, ActionForm, ActionForward, ActionMapping,以及其
它一些东西,都在struts-config.xml 文件中定义。 ActionServlet 在启动时读取这个配置文
件,并创建一个配置对象数据库



举个例子来说,
页面上如果有以下语句:
<html:form action="/hello.do">
当submit此form时,控制器从配置文件中找<action-mappings>下path="/hello" 的<action>元素
然后根据此action元素的type属性找要执行的action类文件
比如

<action-mappings>
    <action path="hello"
            type="cn.com.mylu.Hello"
            name="Hellofrom"
            ……
    </action>

其中 cn.com.mylu.Hellofrom 为ActionForm类javabean
           cn.com.mylu.Hello 为Action类

    <form-bean name="Hellofrom" type="cn.com.mylu.Hellofrom">
    </form-bean>


页面hello.do-----> action元素的path属性 ------> action元素的type属性----->Hello.java---->Hello.java中的execute方法
posted @ 2006-12-06 16:25 Super·shen BLOG 阅读(342) | 评论 (0)编辑 收藏

在讲外连接之前,先举例介绍内连接,也就是一般的相等连接。
select * from a, b where a.id = b.id;
对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将配合实例一一介绍。
1. LEFT OUTER JOIN:左外关联

SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
LEFT OUTER JOIN departments d 
ON (e.department_id = d.department_id);
 

等价于
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e, departments d 
WHERE e.department_id=d.department_id(+);
 

结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。
2. RIGHT OUTER JOIN:右外关联
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
RIGHT OUTER JOIN departments d 
ON (e.department_id = d.department_id);
 

等价于
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e, departments d 
WHERE e.department_id(+)=d.department_id;
 

结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。
3. FULL OUTER JOIN:全外关联
SELECT e.last_name, e.department_id, d.department_name 
FROM employees e 
FULL OUTER JOIN departments d 
ON (e.department_id = d.department_id);
 

结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。

posted @ 2006-11-29 14:32 Super·shen BLOG 阅读(399) | 评论 (0)编辑 收藏

下棋没啥长进,今天用了半个小时看看兵书,总结一下。

开局基本原理:
[尽快集结子力]
[争夺河界]

1。 尽快集结子力

·        如无必要,不要重复走同一子

·        先出炮、马 ,然后车、兵    [车要通 马要灵 炮要能呼应]

·        不可用一两个棋盲目进攻

·        子力要互相呼应,互相配合,不可互相干扰和阻塞

·        若吃兵使用对方能力快速出子或发动攻势,便不要吃

·        若吃兵使用对方能力快速出子或发动攻势,便不要吃


2.       争夺河界 :

除車以外,其他棋子在河界附近都可发挥最大威力及控制力,在中心的棋子要调动到两翼也较灵活、快速,所以河界附近为兵家必争之地。若河界附近被对方占领,便得设法攻下它。反之,自己占据时,须要坚守并利用它向对方的九宮进攻。

中局原理

3.       善用「車」:

4.        在防守中进攻,兼顾协调

5.       保护「士兵」:



关键还是实战时眼光锐利,先人一步。

posted @ 2006-11-21 17:35 Super·shen BLOG 阅读(5814) | 评论 (2)编辑 收藏
String strsql = "select temp.*,rownum  from (select * from tb_awardinfo order by award_id desc )temp where rownum <=5";
//自己乱写的,不知道效率怎么样,那位达人帮贴过代码来参考参考
posted @ 2006-11-21 16:17 Super·shen BLOG 阅读(828) | 评论 (0)编辑 收藏

oracle 分页

1. 最好还是利用分析函数
row_number() over ( partition by col1 order by col2 )

比如想取出100-150条记录,按照tname排序

select tname,tabtype from (
   select tname,tabtype,row_number() over ( order by tname ) rn from tab
)
where rn between 100 and 150;

2. 直接使用rownum 虚列
select tname,tabtype from (
   select tname,tabtype,rownum rn from tab where rownum <= 150
)
where rn >= 100;
使用序列不能基于整个记录集合进行排序,如果指定了order by子句,排序的的是选出来的记录集的排序.

------------------------------------------------------------------------
经过测试,在100万条数据的表中,检索数据的时候,方法2的速度要比方法1要快的.


排序分页

说明:Oracle下用rownum进行分页时 很容易出现排序的错乱。


但多套一层select 就能很好的解决该问题,特此记录,语句如下:

select t2.* from (select t1.*, rownum rn from (select * from tb_courseinfo order by rownum  desc )t1 where rownum <= 150 )t2 where rn >100


不懂具体效率怎么样,和上边一样应该还可以。




实际例子代码如下

int curpage=1;//当前页
int page_record=20;//每页显示的记录数
int introwcount=0; // 记录数
if(request.getParameter("page")==null||Integer.parseInt(request.getParameter("page"))<=0)
{
curpage = 0;
}
else
{
curpage=Integer.parseInt(request.getParameter("page"))-1;//获取传递的值,需要显示的页
}

String sql = "select t2.* from (select t1.*, rownum rn from (select * from tb_courseinfo order by rownum  desc )t1 where rownum <= "+(curpage+1)*page_record+" )t2 where rn > "+curpage*page_record;



posted @ 2006-11-21 16:11 Super·shen BLOG 阅读(4113) | 评论 (3)编辑 收藏