随笔-314  评论-209  文章-0  trackbacks-0
 
为了方便大家查找,整理内容如下:
1. MySQL(http://www.mysql.com)mm.mysql-2.0.2-bin.jar
Class.forName( "org.gjt.mm.mysql.Driver" );
cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", sUsr, sPwd );

2. PostgreSQL(http://www.de.postgresql.org)pgjdbc2.jar
Class.forName( "org.postgresql.Driver" );
cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr, sPwd );

3. Oracle(http://www.oracle.com/ip/deploy/database/oracle9i/)classes12.zip
Class.forName( "oracle.jdbc.driver.OracleDriver" );
cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );

4. Sybase(http://jtds.sourceforge.net)jconn2.jar
Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd );
//(Default-Username/Password: "dba"/"sql")

5. Microsoft SQLServer(http://jtds.sourceforge.net)
Class.forName( "net.sourceforge.jtds.jdbc.Driver" );
cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr, sPwd );

6. Microsoft SQLServer(http://www.microsoft.com)
Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433;databaseName=master", sUsr, sPwd );

7. ODBC
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd );

8.DB2(新添加)
Class.forName("com.ibm.db2.jdbc.net.DB2Driver");
String url="jdbc:db2://192.9.200.108:6789/SAMPLE"
cn = DriverManager.getConnection( url, sUsr, sPwd );

9.Microsoft SQL Server series (6.5, 7.x and 2000) and Sybase 10

JDBC Name: jTDS
URL: http://jtds.sourceforge.net/
Version: 0.5.1
Download URL: http://sourceforge.net/project/showfiles.php?group_id=33291

语法:
Class.forName("net.sourceforge.jtds.jdbc.Driver ");
Connection con = DriverManager.getConnection("jdbc:jtds:sqlserver://host:port/database","user","password");
or
Connection con = DriverManager.getConnection("jdbc:jtds:sybase://host:port/database","user","password");

10.Postgresql
JDBC Name: PostgreSQL JDBC
URL: http://jdbc.postgresql.org/
Version: 7.3.3 build 110
Download URL: http://jdbc.postgresql.org/download.html
语法:
Class.forName("org.postgresql.Driver");
Connection con=DriverManager.getConnection("jdbc:postgresql://host:port/database","user","password");

11.IBM AS400主机在用的JDBC语法
有装V4R4以上版本的Client Access Express
可以在C:\Program Files\IBM\Client Access\jt400\lib
找到 driver 档案 jt400.zip,并更改扩展名成为 jt400.jar
语法:
java.sql.DriverManager.registerDriver (new com.ibm.as400.access.AS400JDBCDriver ());
Class.forName("com.ibm.as400.access.AS400JDBCConnection");
con = DriverManager.getConnection("jdbc:as400://IP","user","password");

12.informix
Class.forName("com.informix.jdbc.IfxDriver").newInstance();
String url =
"jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver;
user=testuser;password=testpassword";
Lib:jdbcdrv.zip<br><br>Class.forName( "com.sybase.jdbc.SybDriver" )
url="jdbc:sybase:Tds:127.0.0.1:2638/asademo";
SybConnection connection= (SybConnection)DriverManager.getConnection(url,"dba","sql");

13.SAP DB
Class.forName ("com.sap.dbtech.jdbc.DriverSapDB");
java.sql.Connection connection = java.sql.DriverManager.getConnection ( "jdbc:sapdb://" + host + "/" + database_name,user_name, password)

14.InterBase
String url = "jdbc:interbase://localhost/e:/testbed/database/employee.gdb";
Class.forName("interbase.interclient.Driver");
//Driver d = new interbase.interclient.Driver (); /* this will also work if you do not want the line above */
Connection conn = DriverManager.getConnection( url, "sysdba", "masterkey" );

15.HSqlDB
url:     http://hsqldb.sourceforge.net/
driver:  org.hsqldb.jdbcDriver
连接方式有4种,分别为:
con-str(内存): jdbc:hsqldb.
con-str(本地): jdbc:hsqldb:/path/to/the/db/dir
con-str(http): jdbc:hsqldb:http://dbsrv
con-str(hsql): jdbc:hsqldb:hsql://dbsrv
posted @ 2007-09-14 09:07 xzc 阅读(317) | 评论 (1)编辑 收藏
JOB
var jobno number
begin
  sys.dbms_job.submit(job => :jobno,
                      what => 'p_report_bb_install;',
                      next_date => to_date('05-09-2007', 'dd-mm-yyyy'),
                      interval => 'TRUNC(SYSDATE)+1');
  commit;
end;
/
posted @ 2007-09-04 17:42 xzc 阅读(242) | 评论 (2)编辑 收藏

数据字典dict总是属于Oracle用户sys的。
  1、用户:
   select username from dba_users;
  改口令
   alter user spgroup identified by spgtest;
  2、表空间:
   select * from dba_data_files;
   select * from dba_tablespaces;//表空间

   select tablespace_name,sum(bytes), sum(blocks)
    from dba_free_space group by tablespace_name;//空闲表空间

   select * from dba_data_files
    where tablespace_name='RBS';//表空间对应的数据文件

   select * from dba_segments
    where tablespace_name='INDEXS';
  3、数据库对象:
   select * from dba_objects;
   CLUSTER、DATABASE LINK、FUNCTION、INDEX、LIBRARY、PACKAGE、PACKAGE BODY、
   PROCEDURE、SEQUENCE、SYNONYM、TABLE、TRIGGER、TYPE、UNDEFINED、VIEW。
  4、表:
   select * from dba_tables;
   analyze my_table compute statistics;->dba_tables后6列
   select extent_id,bytes from dba_extents
   where segment_name='CUSTOMERS' and segment_type='TABLE'
   order by extent_id;//表使用的extent的信息。segment_type='ROLLBACK'查看回滚段的空间分配信息
   列信息:
    select distinct table_name
    from user_tab_columns
    where column_name='SO_TYPE_ID';
  5、索引: 
   select * from dba_indexes;//索引,包括主键索引
   select * from dba_ind_columns;//索引列
   select i.index_name,i.uniqueness,c.column_name
    from user_indexes i,user_ind_columns c
     where i.index_name=c.index_name
     and i.table_name ='ACC_NBR';//联接使用
  6、序列:
   select * from dba_sequences;
  7、视图:
   select * from dba_views;
   select * from all_views;
  text 可用于查询视图生成的脚本
  8、聚簇:
   select * from dba_clusters;
  9、快照:
   select * from dba_snapshots;
  快照、分区应存在相应的表空间。
  10、同义词:
   select * from dba_synonyms
    where table_owner='SPGROUP';
    //if owner is PUBLIC,then the synonyms is a public synonym.
     if owner is one of users,then the synonyms is a private synonym.
  11、数据库链:
   select * from dba_db_links;
  在spbase下建数据库链
   create database link dbl_spnew
   connect to spnew identified by spnew using 'jhhx';
   insert into acc_nbr@dbl_spnew
   select * from acc_nbr where nxx_nbr='237' and line_nbr='8888';
  12、触发器:
   select * from dba_trigers;
  存储过程,函数从dba_objects查找。
  其文本:select text from user_source where name='BOOK_SP_EXAMPLE';
  建立出错:select * from user_errors;
  oracle总是将存储过程,函数等软件放在SYSTEM表空间。
  13、约束:
  (1)约束是和表关联的,可在create table或alter table table_name add/drop/modify来建立、修改、删除约束。
  可以临时禁止约束,如:
   alter table book_example
   disable constraint book_example_1;
   alter table book_example
   enable constraint book_example_1;
  (2)主键和外键被称为表约束,而not null和unique之类的约束被称为列约束。通常将主键和外键作为单独的命名约束放在字段列表下面,而列约束可放在列定义的同一行,这样更具有可读性。
  (3)列约束可从表定义看出,即describe;表约束即主键和外键,可从dba_constraints和dba_cons_columns 查。
   select * from user_constraints
   where table_name='BOOK_EXAMPLE';
   select owner,CONSTRAINT_NAME,TABLE_NAME
    from user_constraints
    where constraint_type='R'
    order by table_name;
  (4)定义约束可以无名(系统自动生成约束名)和自己定义约束名(特别是主键、外键)
  如:create table book_example
    (identifier number not null);
    create table book_example
    (identifier number constranit book_example_1 not null);
  14、回滚段:
  在所有的修改结果存入磁盘前,回滚段中保持恢复该事务所需的全部信息,必须以数据库发生的事务来相应确定其大小(DML语句才可回滚,create,drop,truncate等DDL不能回滚)。
  回滚段数量=并发事务/4,但不能超过50;使每个回滚段大小足够处理一个完整的事务;
   create rollback segment r05
   tablespace rbs;
   create rollback segment rbs_cvt
   tablespace rbs
   storage(initial 1M next 500k);
  使回滚段在线
   alter rollback segment r04 online;
  用dba_extents,v$rollback_segs监测回滚段的大小和动态增长。
  回滚段的区间信息
   select * from dba_extents
   where segment_type='ROLLBACK' and segment_name='RB1';
  回滚段的段信息,其中bytes显示目前回滚段的字节数
   select * from dba_segments
    where segment_type='ROLLBACK' and segment_name='RB1';
  为事物指定回归段
   set transaction use rollback segment rbs_cvt
  针对bytes可以使用回滚段回缩。
   alter rollback segment rbs_cvt shrink;
   select bytes,extents,max_extents from dba_segments
    where segment_type='ROLLBACK' and segment_name='RBS_CVT';
  回滚段的当前状态信息:
   select * from dba_rollback_segs
    where segment_name='RB1';
  比多回滚段状态status,回滚段所属实例instance_num
  查优化值optimal
   select n.name,s.optsize
    from v$rollname n,v$rollstat s
     where n.usn=s.usn;
  回滚段中的数据
   set transaction use rollback segment rb1;/*回滚段名*/
   select n.name,s.writes
    from v$rollname n,v$rollstat s
     where n.usn=s.usn;
  当事务处理完毕,再次查询$rollstat,比较writes(回滚段条目字节数)差值,可确定事务的大小。
  查询回滚段中的事务
   column rr heading 'RB Segment' format a18
   column us heading 'Username' format a15
   column os heading 'Os User' format a10
   column te heading 'Terminal' format a10
   select r.name rr,nvl(s.username,'no transaction') us,s.osuser os,s.terminal te
    from v$lock l,v$session s,v$rollname r
     where l.sid=s.sid(+)
     and trunc(l.id1/65536)=R.USN
     and l.type='TX'
     and l.lmode=6
   order by r.name;
  15、作业
  查询作业信息
   select job,broken,next_date,interval,what from user_jobs;
   select job,broken,next_date,interval,what from dba_jobs;
  查询正在运行的作业
   select * from dba_jobs_running;
  使用包exec dbms_job.submit(:v_num,'a;',sysdate,'sysdate + (10/(24*60*60))')加入作业。间隔10秒钟
exec dbms_job.submit(:v_num,'a;',sysdate,'sysdate + (11/(24*60))')加入作业。间隔11分钟使用包exec dbms_job.remove(21)删除21号作业。

 

posted @ 2007-07-30 17:03 xzc 阅读(220) | 评论 (0)编辑 收藏
一. Input和Output
1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO中,所有的stream(包括Input和Out stream)都包括两种类型:
1.1 以字节为导向的stream
以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种类型:
1) input stream:
1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
2) StringBufferInputStream:把一个String对象作为InputStream
3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作
4) PipedInputStream:实现了pipe的概念,主要在线程中使用
5) SequenceInputStream:把多个InputStream合并为一个InputStream
2) Out stream
1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
2) FileOutputStream:把信息存入文件中
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
4) SequenceOutputStream:把多个OutStream合并为一个OutStream
1.2 以Unicode字符为导向的stream
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种类型:
1) Input Stream
1) CharArrayReader:与ByteArrayInputStream对应
2) StringReader:与StringBufferInputStream对应
3) FileReader:与FileInputStream对应
4) PipedReader:与PipedInputStream对应
2) Out Stream
1) CharArrayWrite:与ByteArrayOutputStream对应
2) StringWrite:无与之对应的以字节为导向的stream
3) FileWrite:与FileOutputStream对应
4) PipedWrite:与PipedOutputStream对应
以字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如CharArrayReader:和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个字符。
1.3 两种不现导向的stream之间的转换
InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
2. stream添加属性
2.1 “为stream添加属性”的作用
运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。但通过FilterInputStream和FilterOutStream的子类,我们可以为stream添加属性。下面以一个例子来说明这种功能的作用。
如果我们要往一个文件中写入数据,我们可以这样操作:
FileOutStream fs = new FileOutStream(“test.txt”);
然后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。但是,如果我们想实现“先把要写入文件的数据先缓存到内存中,再把缓存中的数据写入文件中”的功能时,上面的API就没有一个能满足我们的需求了。但是通过FilterInputStream和FilterOutStream的子类,为FileOutStream添加我们所需要的功能。
2.2 FilterInputStream的各种类型
2.2.1 用于封装以字节为导向的InputStream
1) DataInputStream:从stream中读取基本类型(int、char等)数据。
2) BufferedInputStream:使用缓冲区
3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)
4) PushbackInputStream:很少用到,一般用于编译器开发
2.2.2 用于封装以字符为导向的InputStream
1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream
2) BufferedReader:与BufferedInputStream对应
3) LineNumberReader:与LineNumberInputStream对应
4) PushBackReader:与PushbackInputStream对应
2.3 FilterOutStream的各种类型
2.2.3 用于封装以字节为导向的OutputStream
1) DataIOutStream:往stream中输出基本类型(int、char等)数据。
2) BufferedOutStream:使用缓冲区
3) PrintStream:产生格式化输出
2.2.4 用于封装以字符为导向的OutputStream
1) BufferedWrite:与对应
2) PrintWrite:与对应
3. RandomAccessFile
1) 可通过RandomAccessFile对象完成对文件的读写操作
2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
3) 可以直接跳到文件中指定的位置
4. I/O应用的一个例子
import java.io.*;
public class TestIO{
public static void main(String[] args)
throws IOException{
//1.以行为单位从一个文件读取数据
BufferedReader in =
new BufferedReader(
new FileReader("F:\\nepalon\\TestIO.java"));
String s, s2 = new String();
while((s = in.readLine()) != null)
s2 += s + "\n";
in.close();

//1b. 接收键盘的输入
BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter a line:");
System.out.println(stdin.readLine());

//2. 从一个String对象中读取数据
StringReader in2 = new StringReader(s2);
int c;
while((c = in2.read()) != -1)
System.out.println((char)c);
in2.close();

//3. 从内存取出格式化输入
try{
DataInputStream in3 =
new DataInputStream(
new ByteArrayInputStream(s2.getBytes()));
while(true)
System.out.println((char)in3.readByte());
}
catch(EOFException e){
System.out.println("End of stream");
}

//4. 输出到文件
try{
BufferedReader in4 =
new BufferedReader(
new StringReader(s2));
PrintWriter out1 =
new PrintWriter(
new BufferedWriter(
new FileWriter("F:\\nepalon\\ TestIO.out")));
int lineCount = 1;
while((s = in4.readLine()) != null)
out1.println(lineCount++ + ":" + s);
out1.close();
in4.close();
}
catch(EOFException ex){
System.out.println("End of stream");
}

//5. 数据的存储和恢复
try{
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("F:\\nepalon\\ Data.txt")));
out2.writeDouble(3.1415926);
out2.writeChars("\nThas was pi:writeChars\n");
out2.writeBytes("Thas was pi:writeByte\n");
out2.close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream("F:\\nepalon\\ Data.txt")));
BufferedReader in5br =
new BufferedReader(
new InputStreamReader(in5));
System.out.println(in5.readDouble());
System.out.println(in5br.readLine());
System.out.println(in5br.readLine());
}
catch(EOFException e){
System.out.println("End of stream");
}

//6. 通过RandomAccessFile操作文件
RandomAccessFile rf =
new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
for(int i=0; i<10; i++)
rf.writeDouble(i*1.414);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();
}
}
关于代码的解释(以区为单位):
1区中,当读取文件时,先把文件内容读到缓存中,当调用in.readLine()时,再从缓存中以字符的方式读取数据(以下简称“缓存字节读取方式”)。
1b区中,由于想以缓存字节读取方式从标准IO(键盘)中读取数据,所以要先把标准IO(System.in)转换成字符导向的stream,再进行BufferedReader封装。
2区中,要以字符的形式从一个String对象中读取数据,所以要产生一个StringReader类型的stream。
4区中,对String对象s2读取数据时,先把对象中的数据存入缓存中,再从缓冲中进行读取;对TestIO.out文件进行操作时,先把格式化后的信息输出到缓存中,再把缓存中的信息输出到文件中。
5区中,对Data.txt文件进行输出时,是先把基本类型的数据输出屋缓存中,再把缓存中的数据输出到文件中;对文件进行读取操作时,先把文件中的数据读取到缓存中,再从缓存中以基本类型的形式进行读取。注意in5.readDouble()这一行。因为写入第一个writeDouble(),所以为了正确显示。也要以基本类型的形式进行读取。
6区是通过RandomAccessFile类对文件进行操作。
posted @ 2007-06-20 21:49 xzc 阅读(244) | 评论 (0)编辑 收藏

业务常用,供大家学习:

引用地址:http://www.easydone.cn/014/200604022353065155.htm

package org.easydone.file;



import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * <p>Title: File 常用操作(部分)</p>
 * <p>Description: 业务用</p>
 * <p>Copyright: Copyright (c) 2006 www.easydone.cn</p>
 * <p>Company: 北京聚能易成科技有限公司</p>
 * @authory dirboy
 * @version 1.0
 */

public class FileOperate {

    /**
    * 创建目录
    * @param folderPath:目录路径
    * @return
    * @throws IOException
    */
    public static boolean createFolder(String folderPath) throws IOException {
        boolean result = false;
        File f = new File(folderPath);
        result = f.mkdirs();
        return result;
    }
    /**
    * 删除目录下所有文件
    * @param directory (File 对象)
    */
    public void emptyDirectory(File directory) {
        File[] entries = directory.listFiles();
        for (int i = 0; i < entries.length; i++) {
            entries[i].delete();
        }
    }


    /**
    * 创建文件
    * @param filepath:文件所在目录路径,比如:c:/test/test.txt
    * @return
    */
    public static boolean makeFile(String filepath) throws IOException {
        boolean result = false;
        File file = new File(filepath);
        result = file.createNewFile();
        file = null;
        return result;
    }
    /**
    * 删除文件
    * @param filepath:文件所在物理路径
    * @return
    */
    public static boolean isDel(String filepath) {
        boolean result = false;
        File file = new File(filepath);
        result = file.delete();
        file = null;
        return result;
    }
    /**
    * 文件重命名
    * @param filepath:文件所在物理路径
    * @param destname:新文件名
    * @return
    */
    public static boolean renamefile(String filepath,String destname) {
        boolean result = false;
        File f = new File(filepath);
        String fileParent = f.getParent();
        String filename = f.getName();
        File rf = new File(fileParent+"//"+destname);
        if(f.renameTo(rf)) {
            result = true;
        }
        f = null;
        rf = null;
        return result;
    }
    /**
    * 将文件内容写入数据库中
    * @param filepath:文件所在物理路径
    * @param content:写入内容
    * @throws Exception
    */
    public static void WriteFile(String filepath,String content) throws Exception {
        FileWriter filewriter = new FileWriter(filepath,true);//写入多行
        PrintWriter printwriter = new PrintWriter(filewriter);
        printwriter.println(content);
        printwriter.flush();
        printwriter.close();
        filewriter.close();
    }
    /**
    * 日志备份
    * @param filePath:日志备份路径
    * @param baksize:日志备份大小参考值(字节大小)
    * @throws IOException
    */
    public static void logBak(String filePath,long baksize) throws IOException {
        File f = new File(filePath);
        long len = f.length();
        SimpleDateFormat simpledateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        String s = simpledateformat.format(new Date());
        String fileName = f.getName();
        int dot = fileName.indexOf(".");
        String bakName = s+fileName.substring(dot);
        System.out.println(bakName);
        if(len>=baksize) {
            renamefile(filePath,bakName);
            makeFile(filePath);
        }
        f = null;
    }

}

posted @ 2007-06-14 16:52 xzc 阅读(2055) | 评论 (0)编辑 收藏

摘要:收集一些常用的正则表达式。

正则表达式用于字符串处理,表单验证等场合,实用高效,但用到时总是不太把握,以致往往要上网查一番。我将一些常用的表达式收藏在这里,作备忘之用。本贴随时会更新。

匹配中文字符的正则表达式:

[ \ u4e00 -\ u9fa5 ]

匹配双字节字符(包括汉字在内):

[ ^\ x00 -\ xff ]

应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

String . prototype . len = function (){ return this . replace ([ ^\ x00 -\ xff ] / g,"aa").length; }

匹配空行的正则表达式:

\ n [ \ s | ] *\ r

匹配HTML标记的正则表达式:

/ <(.*)>.*< \/ \1>|<(.*) \/ > /

匹配首尾空格的正则表达式:

( ^\ s * ) | ( \ s *$ )

应用:j avascript中没有像v bscript那样的trim函数,我们就可以利用这个表达式来实现,如下:

String . prototype . trim = function ()
{
    
return this . replace ( / (^\s*)|(\s*$) /g , "" ) ;
}

利用正则表达式分解和转换IP地址
下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的Javascript程序:

function IP2V ( ip )
{
    
re = / (\d+)\.(\d+)\.(\d+)\.(\d+) /g   //匹配IP地址的正则表达式
    
if ( re . test ( ip ))
    
{
        
return RegExp .$ 1 * Math . pow ( 255 , 3 ) )+ RegExp .$ 2 * Math . pow ( 255 , 2 ) )+ RegExp .$ 3 * 255 + RegExp .$ 4 * 1
    
}
    
else
    
{
        
throw new Error ( " Not a valid IP address! " )
    
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

var ip = " 10.100.20.168 "
ip = ip . split ( " . " )
alert ( " IP值是: " + ( ip [ 0 ] * 255 * 255 * 255 + ip [ 1 ] * 255 * 255 + ip [ 2 ] * 255 + ip [ 3 ] * 1 ))

匹配Email地址的正则表达式:

\ w + ([ -+. ] \ w + ) *@\ w + ([ -. ] \ w + ) *\.\ w + ([ -. ] \ w + ) *

匹配网址URL的正则表达式:

http : //([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序:[*注:此程序不正确]

var s = " abacabefgeeii "
var s1 = s . replace ( / (.).*\1 /g , " $1 " )
var re = new RegExp ( " [ " + s1 + " ] " , " g " )
var s2 = s . replace ( re , "" )
alert ( s1 + s2 )   //结果为:abcefgi

*注
===============================
如果var s = “abacabefggeeii”
结果就不对了,结果为:abeicfgg
正则表达式的能力有限
===============================

我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法,最终没有找到,这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符,再以重复的字符建立第二个表达式,取到不重复的字符,两者串连。这个方法对于字符顺序有要求的字符串可能不适用。

得用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1

s = " http://blog.penner.cn/page1.htm "
s = s . replace ( / (.* \/ ){ 0, }([^\.]+).* /i g , " $2 " )
alert ( s )

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文:

onkeyup = " value=value.replace(/[^\u4E00-\u9FA5]/g,'') " onbeforepaste = " clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,'')) "

用正则表达式限制只能输入全角字符:

onkeyup = " value=value.replace(/[^\uFF00-\uFFFF]/g,'') " onbeforepaste = " clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,'')) "

用正则表达式限制只能输入数字:

onkeyup = " value=value.replace(/[^\d]/g,'') " onbeforepaste = " clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,'')) "

用正则表达式限制只能输入数字和英文:

onkeyup = " value=value.replace(/[\W]/g,'') " onbeforepaste = " clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,'')) "

匹配非负整数(正整数 + 0)

^\ d +$

匹配正整数

^ [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] *$

匹配非正整数(负整数 + 0)

^ (( -\ d + ) | ( 0 + )) $

匹配负整数

^- [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] *$

匹配整数

^-?\ d +$

匹配非负浮点数(正浮点数 + 0)

^\ d + ( \.\ d + ) ?$

匹配正浮点数

^ (([ 0 - 9 ] +\. [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * ) | ([ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] *\. [ 0 - 9 ] + ) | ([ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * )) $

匹配非正浮点数(负浮点数 + 0)

^ (( -\ d + ( \.\ d + ) ? ) | ( 0 + ( \ .0 + ) ? )) $

匹配负浮点数

^ ( - (([ 0 - 9 ] +\. [ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * ) | ([ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] *\. [ 0 - 9 ] + ) | ([ 0 - 9 ] * [ 1 - 9 ][ 0 - 9 ] * ))) $

匹配浮点数

^ ( -?\ d + )( \.\ d + ) ?$

匹配由26个英文字母组成的字符串

^ [ A - Za - z ] +$

匹配由26个英文字母的大写组成的字符串

^ [ A - Z ] +$

匹配由26个英文字母的小写组成的字符串

^ [ a - z ] +$

匹配由数字和26个英文字母组成的字符串

^ [ A - Za - z0 - 9 ] +$

匹配由数字、26个英文字母或者下划线组成的字符串

^\ w +$

匹配email地址

^ [ \ w - ] + ( \. [ \ w - ] + ) *@ [ \ w - ] + ( \. [ \ w - ] + ) +$

匹配url

^ [ a - zA - z ] +: //匹配(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$

匹配html tag

<\ s * ( \ S + )( \ s [ ^> ] * ) ?> ( .*? ) <\ s *\ / \1\s*>

Visual Basic & C# Regular Expression
1.确认有效电子邮件格式
下面的示例使用静态 Regex.IsMatch 方法验证一个字符串是否为有效电子邮件格式。如果字符串包含一个有效的电子邮件地址,则 IsValidEmail 方法返回 true,否则返回 false,但不采取其他任何操作。您可以使用 IsValidEmail,在应用程序将地址存储在数据库中或显示在 ASP.NET 页中之前,筛选出包含无效字符的电子邮件地址。

[Visual Basic]

Function IsValidEmail(strIn As String) As Boolean
' Return true if strIn is in valid e-mail format.
Return Regex.IsMatch(strIn, ("^([\w-\.]+)@((\[[0-9]{ 1,3 }\.[0-9]{ 1,3 }\.[0-9]{ 1,3 }\.)|(([\w-]+\.)+))([a-zA-Z]{ 2,4 }|[0-9]{ 1,3 })(\]?)$")
End Function

[C#]

bool IsValidEmail(string strIn)
{
// Return true if strIn is in valid e-mail format.
return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{ 1,3 }\.[0-9]{ 1,3 }\.[0-9]{ 1,3 }\.)|(([\w-]+\.)+))([a-zA-Z]{ 2,4 }|[0-9]{ 1,3 })(\]?)$");
}

2.清理输入字符串
下面的代码示例使用静态 Regex.Replace 方法从字符串中抽出无效字符。您可以使用这里定义的 CleanInput 方法,清除掉在接受用户输入的窗体的文本字段中输入的可能有害的字符。CleanInput 在清除掉除 @、-(连字符)和 .(句点)以外的所有非字母数字字符后返回一个字符串。

[Visual Basic]

Function CleanInput(strIn As String) As String
' Replace invalid characters with empty strings.
Return Regex.Replace(strIn, "[^\w\.@-]", "")
End Function

[C#]

String CleanInput(string strIn)
{
    // Replace invalid characters with empty strings.
    return Regex.Replace(strIn, @"[^\w\.@-]", "");
}

3.更改日期格式
以下代码示例使用 Regex.Replace 方法来用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式。

[Visual Basic]

Function MDYToDMY(input As String) As String
Return Regex.Replace(input, _
"\b(?<month>\d{ 1,2 })/(?<day>\d{ 1,2 })/(?<year>\d{ 2,4 })\b", _
"${ day }-${ month }-${ year }")
End Function

[C#]

String MDYToDMY(String input)
{
    return Regex.Replace(input,"\\b(?<month>\\d{ 1,2 })/(?<day>\\d{ 1,2 })/(?<year>\\d{ 2,4 })\\b","${ day }-${ month }-${ year }");
}

Regex 替换模式
本示例说明如何在 Regex.Replace 的替换模式中使用命名的反向引用。其中,替换表达式 ${ day } 插入由 (?…) 组捕获的子字符串。

有几种静态函数使您可以在使用正则表达式操作时无需创建显式正则表达式对象,而 Regex.Replace 函数正是其中之一。如果您不想保留编译的正则表达式,这将给您带来方便

4.提取 URL 信息
以下代码示例使用 Match.Result 来从 URL 提取协议和端口号。例如,“http://www.penner.cn:8080……将返回“http:8080”。

[Visual Basic]

Function Extension(url As String) As String
Dim r As New Regex("^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/", _
RegexOptions.Compiled)
Return r.Match(url).Result("${ proto }${ port }")
End Function

[C#]

String Extension(String url)
{
    Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/",
    RegexOptions.Compiled);
    return r.Match(url).Result("${ proto }${ port }");
}

只有字母和数字,不小于6位,且数字字母都包含的密码的正则表达式
在C#中,可以用这个来表示:

" \w{ 6 }(\w+)* "

一个将需要将路径字符串拆分为根目录和子目录两部分的算法程序,考虑路径格式有:C:\aa\bb\cc ,\\aa\bb\cc , ftp://aa.bb/cc 上述路径将分别被拆分为:C:\和aa\bb\cc ,\\aa 和 \bb\cc , ftp:// 和 aa.bb/cc 用javascript实现如下:

var strRoot , strSub
var regPathParse = / ^([^\\^ \/ ]+[\\ \/ ]+|\\\\[^\\]+)(.*)$ /
if ( regPathParse . test ( strFolder ))
{
    
strRoot = RegExp .$ 1
    
strSub = RegExp .$ 2
}
Tags: »»
posted @ 2007-03-16 17:08 xzc 阅读(440) | 评论 (0)编辑 收藏

Selenium备忘手册

作者 johnsonchen 目标文章 项目日志 - 2006-09-13

    最近的项目准备用Selenium作一部分的Regression Test。在SpringSide里参考了一下,又下了个Selenium IDE玩玩,觉得还蛮容易上手,基本上不需要手动写测试代码。
    但实操起来时面对各种复杂的页面情况遇到不少麻烦。感觉Selenium 的offical documentation写的比较high level, 最后找了个though works的ppt,算得上比较全面易懂。匆匆翻译了一下,供后来者参考。


一、 格式
1. Test Case 格式

   Title  
 命令(Command)   目标(Target)   值(Value)
 命令(Command)  目标(Target)    (&nbsp;)
 判断(Assertion)   期望值(Expected)   实际值(Actual)


2. Test Suites 格式

 Title
 TestCase1.html
 TestCase2.html
 TestCase3.html

二、 Commands (命令)

  • Action
    对当前状态进行操作
    失败时,停止测试
  • Assertion
    校验是否有产生正确的值
  • Element Locators
    指定HTML中的某元素
  • Patterns
    用于模式匹配

1. Element Locators (元素定位器)

  • id=id
    id locator 指定HTML中的唯一id的元素 
  •  name=name
    name locator指定 HTML中相同name的元素中的第一个元素
  •  identifier=id
    identifier locator 首先查找HTML是否存在该id的元素, 若不存在,查找第一个该name的元素 
  • dom=javascriptExpression
    dom locator用JavaScript表达式来定位HTML中的元素,注意必须要以”document”开头
    例如:
    dom=document.forms[‘myForm’].myDropdown
    dom=document.images[56]
  •  xpath=xpathExpression
    xpath locator用 XPath 表达式来定位HTML中的元素,必须注意要以”//”开头
    例如:
    xpath=//img[@alt=’The image alt text’]
    xpath=//table[@id=’table1’]//tr[4]/td[2]
  •  link=textPattern
    link locator 用link来选择HTML中的连接或锚元素
    例如:
    link=The link text
  • 在没有locator前序的情况下 Without a locator prefix, Selenium uses:
    如果以”document.”开头,则默认是使用 dom locator,如果是以“//”开头,则默认使用xpath locator,其余情况均认作identifier locator

2. String Matching Patterns (字符串匹配模式)

  • glob:patthern
    glob模式,用通配符”*”代表任意长度字符,“?”代表一个字符
  • regexp:regexp
    正则表达式模式,用JavaScript正则表达式的形式匹配字符串
  • exact:string
    精确匹配模式,精确匹配整个字符串,不能用通配符
  • 在没有指定字符串匹配前序的时候,selenium 默认使用golb 匹配模式

3. Select Option Specifiers (Select选项指定器)

  • label=labelPattern
    通过匹配选项中的文本指定选项
    例如:label=regexp:^[Oo]ther
  • value=valuePattern
    通过匹配选项中的值指定选项
    例如:value=other
  • id=id
    通过匹配选项的id指定选项
    例如: id=option1
  • index=index
    通过匹配选项的序号指定选项,序号从0开始
    例如:index=2
  • 在没有选项选择前序的情况下,默认是匹配选项的文本

三、 Actions
描述了用户所会作出的操作。
Action 有两种形式: action和actionAndWait, action会立即执行,而actionAndWait会假设需要较长时间才能得到该action的相响,而作出等待,open则是会自动处理等待时间。

  • click
    click(elementLocator)
    - 点击连接,按钮,复选和单选框
    - 如果点击后需要等待响应,则用”clickAndWait”
    - 如果是需要经过JavaScript的alert或confirm对话框后才能继续操作,则需要调用verify或assert来告诉Selenium你期望对对话框进行什么操作。
     click aCheckbox 
     clickAndWait submitButton 
     clickAndWait  anyLink 

  • open
    open(url)

    - 在浏览器中打开URL,可以接受相对和绝对路径两种形式
    - 注意:该URL必须在与浏览器相同的安全限定范围之内
     open  /mypage 
     open http://localhost/  

  • type
     type(inputLocator, value)
    - 模拟人手的输入过程,往指定的input中输入值
    - 也适合给复选和单选框赋值
    - 在这个例子中,则只是给钩选了的复选框赋值,注意,而不是改写其文本
     type nameField  John Smith
     typeAndWait  textBoxThatSubmitsOnChange newValue

  • select
    select(dropDownLocator, optionSpecifier)
    - 根据optionSpecifier选项选择器来选择一个下拉菜单选项
    - 如果有多于一个选择器的时候,如在用通配符模式,如”f*b*”,或者超过一个选项有相同的文本或值,则会选择第一个匹配到的值
     select   dropDown  Australian Dollars
     select   dropDown  index=0
     selectAndWait  currencySelector  value=AUD
     selectAndWait  currencySelector  label=Auslian D*rs

  •  goBack,close
    goBack()
    模拟点击浏览器的后退按钮
    close()
    模拟点击浏览器关闭按钮
  • selectWindow
    select(windowId)
    - 选择一个弹出窗口
    - 当选中那个窗口的时候,所有的命令将会转移到那窗口中执行
     selectWindow  myPopupWindow 
     selectWindow null 

  • pause
    pause(millisenconds)
    - 根据指定时间暂停Selenium脚本执行
    - 常用在调试脚本或等待服务器段响应时
     pause  5000 
     pause  2000 

  • fireEvent
     fireEvent(elementLocatore,evenName)
    模拟页面元素事件被激活的处理动作
     fireEvent  textFieldfocus 
     fireEvent dropDown blur

  • waitForCondition
    waitForCondition(JavaScriptSnippet,time)

    - 在限定时间内,等待一段JavaScript代码返回true值,超时则停止等待
     waitForCondition  var value=selenium.getText("foo"); value.match(/bar/); 3000

  • waitForValue
    waitForValue(inputLocator, value)
    - 等待某input(如hidden input)被赋予某值,
    - 会轮流检测该值,所以要注意如果该值长时间一直不赋予该input该值的话,可能会导致阻塞
     waitForValue finishIndicationisfinished 
       

  • store,stroreValue
    store(valueToStore, variablename)
    保存一个值到变量里。
    该值可以由自其他变量组合而成或通过JavaScript表达式赋值给变量
     store  Mr John Smith fullname
     store  ${title} ${firstname} ${suname} fullname
     store  javascript{Math.round(Math.PI*100)/100} PI
     storeValue inputLocator variableName

    把指定的input中的值保存到变量中
     storeValue  userName userID 
     type  userName  ${userID}

  • storeText, storeAttribute
    storeText(elementLocator, variablename)
    把指定元素的文本值赋予给变量
     storeText  currentDate  expectedStartDate
     verifyValue  startDate  ${expectedStartDate}

    storeAttribute(elementLocator@attributeName,variableName)
    把指定元素的属性的值赋予给变量
     storeAttribute input1@class   classOfInput1
     verifyAttribute  input2@class  ${classOfInput1}

  • chooseCancel.., answer..
    chooseCancelOnNextConfirmation()
    - 当下次JavaScript弹出confirm对话框的时候,让selenium选择Cancel
    - 如果没有该命令时,遇到confirm对话框Selenium默认返回true,如手动选择OK按钮一样
     chooseCancelOnNextConfirmation    

    - 如果已经运行过该命令,当下一次又有confirm对话框出现时,也会同样地再次选择Cancel
    answerOnNextPrompt(answerString)
    - 在下次JavaScript弹出prompt提示框时,赋予其anweerString的值,并选择确定
     answerOnNextPrompt  Kangaroo  

四、 Assertions
允许用户去检查当前状态。两种模式: Assert 和 Verify, 当Assert失败,则退出测试;当Verify失败,测试会继续运行。

  • assertLocation, assertTitle
    assertLocation(relativeLocation)
    判断当前是在正确的页面
     verifyLocation  /mypage 
     assertLocation  /mypage 

  • assertTitle(titlePattern)
    检查当前页面的title是否正确
     verifyTitle  My Page  
     assertTitle  My Page  

  • assertValue
    assertValue(inputLocator, valuePattern)
    - 检查input的值
    - 对于 checkbox或radio,如果已选择,则值为”on”,反之为”off”
     verifyValue  nameField  John Smith
     assertValue  document.forms[2].nameField John Smith

  • assertSelected, assertSelectedOptions
    assertSelected(selectLocator, optionSpecifier)
    检查select的下拉菜单中选中的选型是否和optionSpecifer(Select选择选项器)的选项相同
     verifySelected  dropdown2  John Smith
     verifySelected  dorpdown2  value=js*123
     assertSelected  document.forms[2].dropDown label=J*Smith
     assertSelected  document.forms[2].dropDown  index=0

  • assertSelectOptions(selectLocator, optionLabelList)
    - 检查下拉菜单中的选项的文本是否和optionLabelList相同
    - optionLabelList是以逗号分割的一个字符串
     verifySelectOptions  dropdown2  John Smith,Dave Bird
     assertSelectOptions  document.forms[2].dropdown Smith,J,Bird,D

  • assertText
    assertText(elementLocator,textPattern)
    - 检查指定元素的文本
    - 只对有包含文本的元素生效
    - 对于Mozilla类型的浏览器,用textContent取元素的文本,对于IE类型的浏览器,用innerText取元素文本
     verifyText  statusMessage  Successful
     assertText  //div[@id='foo']//h1 Successful

     
  • assertTextPresent, assertAttribute
    assertTextPresent(text)
    检查在当前给用户显示的页面上是否有出现指定的文本
     verifyTextPresent  You are now logged in  
     assertTextPresent  You are now logged in  

  • assertAttribute( elementLocator@attributeName , ValuePattern)
    检查当前指定元素的属性的值
     verifyAttribute txt1@class  bigAndBlod
     assertAttribute  document.images[0]@alt alt-text
     verifyAttribute  //img[@id='foo']/alt  alt-text

  • assertTextPresent, etc.
    assertTextPresent(text)
    assertTextNotPresent(text)
    assertElementPresent(elementLocator)
     verifyElementPresent  submitButton  
     assertElementPresent  //img[@alt='foo']  
    assertElementNotPresent(elementLocator)
  • assertTable
    assertTable(cellAddress, valuePattern)
    - 检查table里的某个cell中的值
    - cellAddress的语法是tableName.row.column, 注意行列序号都是从0开始
     verifyTable  myTable.1.6 Submitted
     assertTable  results0.2  13

     
  • assertVisible, nonVisible
    assertVisible(elementLocator)
    - 检查指定的元素是否可视的
    - 隐藏一个元素可以用设置css的‘visibility’属性为’hidden’,也可以设置‘display’属性为‘none’
     verfyVisible  postcode  
     assertVisible  postcode  

  • assertNotVisible(elementLocator)
     verfyNotVisible  postcode  
     assertNotVisible  postcode  

  • Editable, non-editable
    assertEditable(inputLocator)
    检查指定的input是否可以编辑
     verifyEditable  shape  
     assertEditable  colour  

  • assertNotEditable(inputLocator)
    检查指定的input是否不可以编辑
  • assertAlert
    assertAlert(messagePattern)
    - 检查JavaScript是否有产生带指定message的alert对话框
    - alert产生的顺序必须与检查的顺序一致
    - 检查alert时会产生与手动点击’OK’按钮一样的效果。如果一个alert产生了,而你却没有去检查它,selenium会在下个action中报错。
    - 注意:Selenium 不支持 JavaScript 在onload()事件时 调用alert();在这种情况下,Selenium需要你自己手动来点击OK.
  • assertConfirmation
    assertConfirmation(messagePattern)
    - 检查JavaScript是否有产生带指定message的confirmation对话框和alert情况一样,confirmation对话框也必须在它们产生的时候进行检查
    - 默认情况下,Selenium会让confirm() 返回true, 相当于手动点击Ok按钮的效果。你能够通过chooseCancelOnNextConfirmation命令让confirm()返回false.同样地,如果一个cofirmation对话框出现了,但你却没有检查的话,Selenium将会在下个action中报错
    - 注意:在Selenium的环境下,confirmation对话框框将不会再出现弹出显式对话框
    - 注意:Selenium不支持在onload()事件时调用confirmation对话框,在这种情况下,会出现显示confirmatioin对话框,并需要你自己手动点击。
  •  assertPrompt
    assertPrompt(messagePattern)
    - 检查JavaScript是否有产生带指定message的Prompt对话框
    - 你检查的prompt的顺序Prompt对话框产生的顺序必须相同
    - 必须在verifyPrompt之前调用answerOnNextPrompt命令
    - 如果prompt对话框出现了但你却没有检查,则Selenium会在下个action中报错
     answerOnNextPrompt  Joe  
     click  id=delegate  
     verifyPrompt  Delegate to who?  


五、 Parameters and Variables
参数和变量的声明范围由简单的赋值到JavaScript表达式赋值。
Store,storeValue 和storeText 为下次访问保存值。
在Selenium内部是用一个叫storeVars的map来保存变量名。

  • Variable Substitution 变量替换
    提供了一个简单的方法去访问变量,语法 ${xxx}
     store   Mr  title
     storeValue  nameField  surname
     store   ${title} ${suname} fullname
     type  textElement  Full name is: ${fullname}

  •  JavaScript Evaluation JavaScript赋值
    你能用JavaScript来构建任何你所需要的值。
    这个参数是以javascript开头,语法是 javascript{‘with a trailing’}。
    可以通过JavaScript表达式给某元素赋值。
    store  javascript{'merchant'+(new Date()).getTime()}  merchantId
     type textElement  javascript{storedVars['merchantId'].toUpperCase()}

  • Generating Unique values 产生唯一值.  
    问题:你需要唯一的用户名
    解决办法: 基于时间来产生用户名,如’fred’+(new Date().getTime())
posted @ 2007-02-12 10:49 xzc 阅读(2037) | 评论 (1)编辑 收藏

作者:Radic     来源:sun

摘要:

本文是来自Sun官方站点的一篇关于如何编写安全的Java代码的指南,开发者在编写一般代码时,可以参照本文的指南
本文是来自Sun官方站点的一篇关于如何编写安全的Java代码的指南,开发者在编写一般代码时,可以参照本文的指南:

•        静态字段
•        缩小作用域
•        公共方法和字段
•        保护包
•        equals方法
•        如果可能使对象不可改变
•        不要返回指向包含敏感数据的内部数组的引用
•        不要直接存储用户提供的数组
•        序列化
•        原生函数
•        清除敏感信息


静态字段
•        避免使用非final的公共静态变量
应尽可能地避免使用非final公共静态变量,因为无法判断代码有无权限改变这些变量值。
•        一般地,应谨慎使用易变的静态状态,因为这可能导致设想中相互独立的子系统之间发生不可预知的交互。

缩小作用域
作为一个惯例,尽可能缩小方法和字段的作用域。检查包访问权限的成员能否改成私有的,保护类型的成员可否改成包访问权限的或者私有的,等等。

公共方法/字段
避免使用公共变量,而是使用访问器方法访问这些变量。用这种方式,如果需要,可能增加集中安全控制。
对于任何公共方法,如果它们能够访问或修改任何敏感内部状态,务必使它们包含安全控制。
参考如下代码段,该代码段中不可信任代码可能设置TimeZone的值:
private static TimeZone  defaultZone = null;

      public static synchronized void setDefault(TimeZone zone)
      {
          defaultZone = zone;
      }


保护包
有时需要在全局防止包被不可信任代码访问,本节描述了一些防护技术:
•        防止包注入:如果不可信任代码想要访问类的包保护成员,可以尝试在被攻击的包内定义自己的新类用以获取这些成员的访问权。防止这类攻击的方式有两种:
1.        通过向java.security.properties文件中加入如下文字防止包内被注入恶意类。
          ... 
package.definition=Package#1 [,Package#2,...,Package#n]

...


这会导致当试图在包内定义新类时类装载器的defineClass方法会抛出异常,除非赋予代码一下权限:
... 
RuntimePermission("defineClassInPackage."+package)

...


2.        另一种方式是通过将包内的类加入到封装的Jar文件里。
(参看http://java.sun.com/j2se/sdk/1.2/docs/guide/extensions/spec.html)
    通过使用这种技巧,代码无法获得扩展包的权限,因此也无须修改java.security.properties文件。
•        防止包访问:通过限制包访问并仅赋予特定代码访问权限防止不可信任代码对包成员的访问。通过向java.security.properties文件中加入如下文字可以达到这一目的:
      ... 
package.access=Package#1 [,Package#2,...,Package#n]

...


这会导致当试图在包内定义新类时类装载器的defineClass方法会抛出异常,除非赋予代码一下权限:
... 
RuntimePermission("defineClassInPackage."+package)

...


如果可能使对象不可改变
如果可能,使对象不可改变。如果不可能,使得它们可以被克隆并返回一个副本。如果返回的对象是数组、向量或哈希表等,牢记这些对象不能被改变,调用者修改这些对象的内容可能导致安全漏洞。此外,因为不用上锁,不可改变性能够提高并发性。参考Clear sensitive information了解该惯例的例外情况。

不要返回指向包含敏感数据的内部数组的引用
该惯例仅仅是不可变惯例的变型,在这儿提出是因为常常在这里犯错。即使数组中包含不可变的对象(如字符串),也要返回一个副本这样调用者不能修改数组中的字符串。不要传回一个数组,而是数组的拷贝。

不要直接在用户提供的数组里存储
该惯例仅仅是不可变惯例的另一个变型。使用对象数组的构造器和方法,比如说PubicKey数组,应当在将数组存储到内部之前克隆数组,而不是直接将数组引用赋给同样类型的内部变量。缺少这个警惕,用户对外部数组做得任何变动(在使用讨论中的构造器创建对象后)可能意外地更改对象的内部状态,即使该对象可能是无法改变的

序列化
当对对象序列化时,直到它被反序列化,它不在Java运行时环境的控制之下,因此也不在Java平台提供的安全控制范围内。
在实现Serializable时务必将以下事宜牢记在心:
•        transient

在包含系统资源的直接句柄和相对地址空间信息的字段前使用transient关键字。 如果资源,如文件句柄,不被声明为transient,该对象在序列化状态下可能会被修改,从而使得被反序列化后获取对资源的不当访问。

•        特定类的序列化/反序列化方法

为了确保反序列化对象不包含违反一些不变量集合的状态,类应该定义自己的反序列化方法并使用ObjectInputValidation接口验证这些变量。

如果一个类定义了自己的序列化方法,它就不能向任何DataInput/DataOuput方法传递内部数组。所有的DataInput/DataOuput方法都能被重写。注意默认序列化不会向DataInput/DataOuput字节数组方法暴露私有字节数组字段。

如果Serializable类直接向DataOutput(write(byte [] b))方法传递了一个私有数组,那么黑客可以创建ObjectOutputStream的子类并覆盖write(byte [] b)方法,这样他可以访问并修改私有数组。下面示例说明了这个问题。
你的类:
      public class YourClass implements Serializable {

            private byte [] internalArray;
....
private synchronized void writeObject(ObjectOutputStream stream) {
...

               stream.write(internalArray);
                ...
}
}


黑客代码

       public class HackerObjectOutputStream extends ObjectOutputStream{
            public void write (byte [] b) {
               Modify b
      }
}
...
             YourClass yc = new YourClass();
              ...

             HackerObjectOutputStream hoos = new HackerObjectOutputStream();

              hoos.writeObject(yc);


•        字节流加密

保护虚拟机外的字节流的另一方式是对序列化包产生的流进行加密。字节流加密防止解码或读取被序列化的对象的私有状态。如果决定加密,应该管理好密钥,密钥的存放地点以及将密钥交付给反序列化程序的方式等。

•        需要提防的其他事宜

如果不可信任代码无法创建对象,务必确保不可信任代码也不能反序列化对象。切记对对象反序列化是创建对象的另一途径。
比如说,如果一个applet创建了一个frame,在该frame上创建了警告标签。如果该frame被另一应用程序序列化并被一个applet反序列化,务必使该frame出现时带有同一个警告标签。

原生方法
应从以下几个方面检查原生方法:
•        它们返回什么
•        它们需要什么参数
•        它们是否绕过了安全检查
•        它们是否是公共的,私有的等
•        它们是否包含能绕过包边界的方法调用,从而绕过包保护

清除敏感信息
当保存敏感信息时,如机密,尽量保存在如数组这样的可变数据类型中,而不是保存在字符串这样的不可变对象中,这样使得敏感信息可以尽早显式地被清除。不要指望Java平台的自动垃圾回收来做这种清除,因为回收器可能不会清除这段内存,或者很久后才会回收。尽早清除信息使得来自虚拟机外部的堆检查攻击变得困难。

摘自:http://www.matrix.org.cn/resource/article/2006-12-15/Java+Code+Security_199f1a70-8bf4-11db-ab77-2bbe780ebfbf.html
posted @ 2006-12-29 20:47 xzc 阅读(232) | 评论 (0)编辑 收藏
在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方。
1、Create Sequence
你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限,
CREATE SEQUENCE emp_sequence
INCREMENT BY 1  -- 每次加几个
START WITH 1   -- 从1开始计数
NOMAXVALUE    -- 不设置最大值
NOCYCLE     -- 一直累加,不循环
CACHE 10;

一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL
CURRVAL=返回 sequence的当前值
NEXTVAL=增加sequence的值,然后返回 sequence 值
比如:
emp_sequence.CURRVAL
emp_sequence.NEXTVAL

可以使用sequence的地方:
- 不包含子查询、snapshot、VIEW的 SELECT 语句
- INSERT语句的子查询中
- NSERT语句的VALUES中
- UPDATE 的 SET中

可以看如下例子:
INSERT INTO emp VALUES
(empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20);

SELECT empseq.currval FROM DUAL;

但是要注意的是:
- 第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白?

- 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可以在create sequence的时候用nocache防止这种情况。

2、Alter Sequence
你或者是该sequence的owner,或者有ALTER ANY SEQUENCE 权限才能改动sequence. 可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence 再 re-create .
Alter sequence 的例子
ALTER SEQUENCE emp_sequence
  INCREMENT BY 10
  MAXVALUE 10000
  CYCLE   -- 到10000后从头开始
  NOCACHE ;


影响Sequence的初始化参数:
SEQUENCE_CACHE_ENTRIES =设置能同时被cache的sequence数目。

可以很简单的Drop Sequence
DROP SEQUENCE order_seq;

-------------------------------------
drop sequence SEQ_GROUP_ID
-- Create sequence
create sequence SEQ_GROUP_ID
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
cache 20;

select seq_group_id.nextval from dual
-------------------------------------
posted @ 2006-12-28 11:01 xzc 阅读(279) | 评论 (0)编辑 收藏
 我每月到企业举办一小时的免费“理财讲座”,一直都很受员工们的欢迎。讲座内容很少涉及复杂难懂的技术操作层面,也几乎不进入到产品介绍环节,因为据我了解,国内一般的中产白领们,目前普遍缺乏的是几个重要的理财概念——这些概念,会影响他们以后的行为,假如他们能老老实实执行这些理财上的概念,至少坚持10年
以上,那么,每一个人都能成为百万富翁。

  第一个理财概念:

  区分“投资”与“消费”

  区分“投资”行为与“消费”行为。一般人消费前,没有这种概念,学经济学的人消费前会考虑,这个消费是属于“投资”行为或是“消费”行为。

  先请看一个明显的例子:

  10年前甲和乙是本科的同学,在社会工作5年后,不约而同积蓄了30万元人民币。5年前,他们都花掉了这30万元。

  甲去通州购买了一套房。

  乙去买了一辆“奥迪”。

  5年后的今天:

  甲的房子,市值60万元。

  乙的二手车,市值只有5万元。

  两人目前的资产,明显有了很大差异,但他们的收入都一样,而且同样学历、基本具备同样的社会经验,为何大家财富不一样?

  甲花钱买房是“投资”行为——钱其实没有花出去,只是转移在了房子里,以后还是都归自己。

  乙花钱买车是“消费”行为——钱是花出去的,给了别人,二手车用过10年后,几乎一分不值。车跟房子不一样,房子10年后,说不定已翻了好几番。

  再看第二个例子:

  有一天,我的秘书向我提出一个问题:陈老师,我觉得客户甲有点怪。她说:客户甲去买一张演唱会的票,300元他嫌贵,犹豫很久,始终没买,但客户甲其实并不缺钱。但有一次,有一个著名企业总裁出版了一套“教导管理”光盘,6张光盘卖到天价1500元,客户甲却毫不犹豫将它买下来。为何¥300演唱票,客户甲嫌贵,却去买¥1500的几张光盘呢?

  解答如下:客户甲是将学的经济学的知识应用到日常生活里,客户甲每花费钱的时候,会先想这花钱是‘投资’行为或是‘消费’行为?

  买光盘,这1500元是“投资”行为,它其实没有花出去,它增长了客户甲的知识,让客户甲更有智慧,在未来的日子,客户甲用新学的智慧,会赚回1500元的好几倍,钱始终还在客户甲的口袋。

  但购买演唱会的票,是“消费”行为,是给了别人,再也拿不回来了。

  在生活中,还有更多的日常例子:

  (1) 客户甲会花3万人民币去买一幅油画,但不会花3万去买二手车。

  (2) 客户甲会花1万去买人寿保险,但不会花1万去欧洲度假。

  (3) 客户甲会很舍得花钱买书,但不舍得花钱去看电影。

  以上哪些是“投资”行为,那些是“消费”行为,每个人都会有自己的判断。下面是更多的例子,如果属于“投资”行为,那么,多贵都不必讨价还价,因为钱最终还是归自己。

  第二个理财概念:

  “哈佛”教条

  大家每个月都会将工资一部分储蓄起来,有些人储蓄10%工资,有些20%,有些30%。大部分人是一个月后,把没有花出去的钱储蓄起来,而且每个月储蓄多少基本没谱。

  在著名的美国第一学府哈佛大学,第一堂的经济学课,只教两个概念。

  第一个概念:花钱要区分“投资”行为或“消费”行为。

  第二个概念:每月先储蓄30%的工资,剩下来才进行消费。

  哈佛教导出来的人,以后都很富有,并非主要因为他们是名校出身、收入丰厚,而是他们每月的行为,跟一般的普通老百姓,只有一点不一样:

  哈佛教条:储蓄30%的工资是硬指标,剩下才消费。每月储蓄的钱是每月最重要的目标,只会超额完成,剩下的钱就越来越多。

  一般人:先花钱,能剩多少便储蓄多少,储蓄剩下的钱并不多。

  第三个理财概念:

  “理财三句话”

  理财走不出三句话,如果每句话都能吃透,并且完全执行,那么,打工一族都可以变得非常富有。

  很多朋友都知道客户甲的出身——难民,一无所有。到加拿大学经济学也是拿着奖学金,家里七兄弟姐妹,没有钱送客户甲们上大学,上大学后,从来没问家里拿过钱。毕业后打工,但客户甲坚持“理财三句话”原则,用经济学学到的学问,用到日常生活里,一步步走下去。现在20年后,客户甲有4套房,每月收租便有1万多的收入,也算是半个富有的人。

  其实每个人都做得到,在这公开这秘密。以前这些重要的理财概念,课程里面都有教。

  再举一些实例给大家看:巴菲特在他的书本里说他6岁开始储蓄,每月30块。到13岁时,当他有了3千块,他买了一只股票。年年坚持储蓄,年年坚持投资,十年如一日,他坚持了80年。现在85岁,是美国首富,比“微软”主席比尔·盖茨还有钱。

  学员有时候会问,如何能每年回报率达到10%以上。答:其实现在要银行里面,它们提供很多理财产品:基金,外币,QDII。 这些银行产品略有一点风险,但风险假如你能有效的管理它,10%的回报率其实也不难。当然,假如没有受过专业培训,你自己是瞎摸,你会亏掉很多钱。但你有两个途径:

  (1) 花点钱去学。

  (2)你自己没时间,那么可以去找专业的理财师。

  找专业理财师,要分辨他们的专业资格,你可以参考几个条件:

  (1) 已经考取了的理财规划师认证:中国注册理财规划师(CFP),全名是Certified Financial Planner。2005年已经在北京举行公开考试,现在很多银行的从业人员都在考。合格率偏低,暂时银行里面有资格的人也不多。

  (2) 有10年以上的理财经验。但其它有兴趣想多认识理财学问的,可以参加公开课程,费用只是几百元一节。参加学习的费用,是“投资”行为,并没有“花出去”,以后还是归你自己,学过以后,就不会“小钱精明,大钱糊涂”了。

  一般人错误的理财观念:

  挣得多,所以富有

  很多人认为,甲收入每月1.5万元,乙收入每月8000元,甲便应该比乙富有,这观念在社会上很普遍。但这是错的观念,错得很离谱。错在哪里?

  富有的定义,并不是你每月工资挣得多,而是你每月“剩下多少”——剩下的才是财富。请看例子:

  美国人每月工资高中国二、三倍,照一般的观念看,一般的美国人应比中国人富有。但实际情况却不是这样。一般美国人都有几张信用卡,他们喜欢消费,每月不单只是“月光一族”,更普遍是欠下信用卡不少的债。在美国,理财规划师的理财讲座,一般时间花在讲“如何减少你的债务”。

  一般美国人,银行的储蓄都不够美金几千元。在中国,没有这种情况,中国人善于储蓄,一般人在银行都有存款,超过十几万元的,人数还不少。

  所以,不要以为老美每月挣钱多就富有。其实,一般老美的白领比中国人的白领穷得多。当然,在北京见到的很多外派到北京工作的老美,是美国的精英,不是一般的美国白领,有钱人占多数。

  中国的中层白领,比美国的白领富有。请记住:富有不是比较每月工资,而是比较“剩下储蓄在银行里的存款”,以这个定义来讲,中国人中层白领在银行的存款,远比美国中层白领高。

  还有一个例子:

  一般人以为台湾人工资平均高出内地一倍,他们自然比我们富有,这也是一个错误的观念。

  去过台湾的朋友都知道,台湾地铁单程平均是12元,北京是3元;台湾午饭平均要50元,北京平均15元;在台湾租一套房6500元,北京在通州租一套房1500元。假如台湾人每月挣15000元,减去房租6500元,交通费1000元,吃饭300元,交税1500元,一点点娱乐2000元,“每月剩下1000元”。

  北京的初级工程师,每月工资8000元,减去交税1000元,减去房租1500元,交通费300元,吃饭1000元,娱乐1000元,“每月剩下3200元”。

  请问:是台湾人每月工资15000元,每月只剩下1000元的人富有,还是北京工程师,每月工资只有8000元,但每月剩下3200元的人富有呢?

  中国经过20多年的改革,已经造就了富有的一批人,请看《财富》杂志一年前的“富有”的人的调查报告,他们调查手头上持有“现金100万美元存款的人”,在亚洲区有多少人拥有这种财富。

  答案是:香港4万人,台湾8万人,日本12万,中国30万。中国每年增长率远远超出其他亚洲国家。所以人们不会觉得奇怪,外资银行到北京开业,老是在推广“理财服务”,因为中国这个地方,正是比较欠缺这一块的知识。

posted @ 2006-12-16 13:09 xzc 阅读(345) | 评论 (0)编辑 收藏
仅列出标题
共32页: First 上一页 20 21 22 23 24 25 26 27 28 下一页 Last