byterat

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  54 随笔 :: 0 文章 :: 15 评论 :: 0 Trackbacks

#

spring事务探索

原文出处:
http://www.javaeye.com/topic/11190

spring自建事务管理模块。而且这个事务管理是一个抽象设计,可以应用到很多场合,包括普通的DataSource,jta,jms和hibernate上。

要正确使用spring的事务,首先需要了解spring在事务设计上的一些概念
统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatus

PlatformTransactionManager直译过来就是平台相关事务,这里的平台指的是“事务源”,包括刚才我说的DataSource,jta等等。这些无一不是一个事务源。广义的说,凡是可以完成事务性操作的对象,都可以设计出相对应的PlatformTransactionManager,只要这个事务源支持commit,rollback和getTransaction语意。

查看spring代码,可以发现这些manager实现事务,就是调用事务源的事务操作方法

比如

HibernateTransactionManager

代码

 

  1. protected   void  doCommit(DefaultTransactionStatus status) {   
  2.         HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();   
  3.          if  (status.isDebug()) {   
  4.             logger.debug( "Committing Hibernate transaction on session ["  +   
  5.                     txObject.getSessionHolder().getSession() +  "]" );   
  6.         }   
  7.          try  {   
  8.             txObject.getSessionHolder().getTransaction().commit();   
  9.         }   
  10. ...   
  11.   
  12.     }  

jdbc 的DataSourceTransactionManager

代码

 

  1. protected   void  doCommit(DefaultTransactionStatus status) {   
  2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();   
  3.         Connection con = txObject.getConnectionHolder().getConnection();   
  4.          if  (status.isDebug()) {   
  5.             logger.debug( "Committing JDBC transaction on connection ["  + con +  "]" );   
  6.         }   
  7.          try  {   
  8.             con.commit();   
  9.         }   
  10.         ...   
  11.     }  

那么PlatformTransactionManager以什么依据处理事务呢?
是TransactionStatus
查看api发现这个接口有三个方法
isNewTransaction() ,isRollbackOnly(),setRollbackOnly()
PlatformTransactionManager就是根据前两个方法决定是否要创建一个新事务,是要递交还是回滚。至于第三个方法是改变事务当前状态的,很多地方都要用到,偏偏PlatformTransactionManager自身好像不怎么用,毕竟事务状态的改变是由程序员代码决定的,不需要一个manager多管闲事。

总结上面所说的,spring的事务由PlatformTransactionManager管理,manager最后调用事务源的方法来实现一个事务过程。而manager通过TransactionStatus 来决定如何实现。

接下去说spring事务中的TransactionTemplate和TransactionInterceptor

TransactionTemplate其实和spring中其他的template的作用类似,起到化简代码的作用,不要被它那么长的名字吓倒了,事实上这个template并不是什么非常核心的对象。如果比较学究派的,可以去看看template设计模式,在此就不再对此赘述了。
为什么要有TransactionTemplate?先来看看如果没有TransactionTemplate,我们的代码该怎么写

先来看看spring reference中的一段代码

代码

 

  1. DefaultTransactionDefinition def =  new  DefaultTransactionDefinition()   
  2. def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);   
  3.   
  4. TransactionStatus status = transactionManager.getTransaction(def);   
  5.   
  6. try  {   
  7.      // execute your business logic here   
  8. catch  (MyException ex) {   
  9.     transactionManager.rollback(status);   
  10.      throw  ex;   
  11. }   
  12. transactionManager.commit(status);  


这是直接使用transactionManager的例子,可以看到真正执行business logic 的地方是在try当中那段,前后的代码都是为了完成事务管理的。如果每个business logic都要写上那么一段,我肯定是疯了。我们翻出TransactionTemplate的代码看看他怎么化简了我们的代码

代码

 

  1. public  Object execute(TransactionCallback action)  throws  TransactionException {   
  2.         TransactionStatus status =  this .transactionManager.getTransaction( this );   
  3.         Object result =  null ;   
  4.          try  {   
  5.             result = action.doInTransaction(status);   
  6.         }   
  7.          catch  (RuntimeException ex) {   
  8.              // transactional code threw application exception -> rollback   
  9.             rollbackOnException(status, ex);   
  10.              throw  ex;   
  11.         }   
  12.          catch  (Error err) {   
  13.              // transactional code threw error -> rollback   
  14.             rollbackOnException(status, err);   
  15.              throw  err;   
  16.         }   
  17.          this .transactionManager.commit(status);   
  18.          return  result;   
  19.     }  

同上面的代码如出一辙,前后是事务处理代码,当中那段result = action.doInTransaction(status);是我们的应用代码。至于action是什么,全看各位的需要了。但是有一点要主要,如果利用TransactionTemplate,那么他不管你扔出什么异常都会回滚事务,但是回滚的是哪个事务呢?继续挖代码

代码

 

  1. private   void  rollbackOnException(TransactionStatus status, Throwable ex)  throws  TransactionException {   
  2.          if  (logger.isDebugEnabled()) {   
  3.             logger.debug( "Initiating transaction rollback on application exception" , ex);   
  4.         }   
  5.          try  {   
  6.              this .transactionManager.rollback(status);   
  7.         }   
  8.          catch  (RuntimeException ex2) {   
  9.             logger.error( "Application exception overridden by rollback exception" , ex);   
  10.              throw  ex2;   
  11.         }   
  12.          catch  (Error err) {   
  13.             logger.error( "Application exception overridden by rollback error" , ex);   
  14.              throw  err;   
  15.         }   
  16.     }  


真相大白,是对template所持有的某个transactionManager进行回滚。所以如果你的应用代码用的是事务源a的一些资源,比如到服务器a的一个datasource,但是你的transactionManager管理的是另一些资源,比如服务器b的一个datasource,代码铁定不会正常运行

特别是在一些多事务源的程序里,这点千万不能搞错。如果多个事务源之间要完成全局事务,还是老老实实用分布式事务管理服务吧(jta)

那么TransactionInterceptor是干什么的?这个是spring 的声明式事务的支持方式。因为用TransactionTemplate要硬编码,而且调整事务策略很麻烦(不是说不能调。举个例子原来程序抛出异常A需要回滚,现在不需要要,我就可以把a catch吃掉。这时候template就不会回滚了。但是每次调整都要重写编码。)而用TransactionInterceptor就可以将这些调整写在配置中。我们再来挖TransactionInterceptor的代码

代码

 

  1. public  Object invoke(MethodInvocation invocation)  throws  Throwable {   
  2.          // Work out the target class: may be null.   
  3.          // The TransactionAttributeSource should be passed the target class   
  4.          // as well as the method, which may be from an interface   
  5.         Class targetClass = (invocation.getThis() !=  null ) ? invocation.getThis().getClass() :  null ;   
  6.            
  7.          // Create transaction if necessary   
  8.         TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);   
  9.   
  10.         Object retVal =  null ;   
  11.          try  {   
  12.              // This is an around advice.   
  13.              // Invoke the next interceptor in the chain.   
  14.              // This will normally result in a target object being invoked.   
  15.             retVal = invocation.proceed();   
  16.         }   
  17.          catch  (Throwable ex) {   
  18.              // target invocation exception   
  19.             doCloseTransactionAfterThrowing(txInfo, ex);   
  20.              throw  ex;   
  21.         }   
  22.          finally  {   
  23.             doFinally(txInfo);   
  24.         }   
  25.         doCommitTransactionAfterReturning(txInfo);   
  26.   
  27.          return  retVal;   
  28.     }  


万变不离其宗。

所以使用spring的事务管理需要作这些事
1,设置好事务源,比如DataSource,hibernate的session。如果有多个事务源要考虑他们之间是否有全局事务,如果有,老老实实用jta,否则就需要自己写一个manager了
2,设置manager,根据你的事务源选择对应的PlatformTransactionManager
3,选择实现事物的方式,用template还是interceptor。用template代码直观点,但是template所管辖的manager和你应用代码所用的事务源要一致。如果用interceptor千万注意,一定要调用interceptor那个bean,而不是原始的那个target。在坛子上我已经看到至少有两个朋友说spring事物不起作用,从配置和代码上看都正确,这时要好好查查,调用的bean是哪一个。
4,这个是设计问题了,推荐事务处于一个较高层次,比如service上的某个函数,而底层的dao可以不考虑事务,否则可能会出现事务嵌套,增加程序复杂度。

posted @ 2007-03-05 14:45 比特鼠 阅读(240) | 评论 (0)编辑 收藏

2007年已经过去一个月了, 还没有制定今年的规划, 现在是时候了!

争取掌握以下技术:

1. Ruby On Rails 
进一步学习ruby的语法和语义,最好能深入到解释器一层看看有些特性是怎么实现的。

2、Spring AOP 及 AspectJ
个人觉得Spring 2.0和AspectJ的结合,有很多潜力,值得深入挖掘。

3. Web Service

4. Java JPA

5. Role-Based Access Control , Acegi
buaawhl推荐的,
http://csrc.nist.gov/rbac/
http://www.amazon.com/Role-Based-Access-Control-David-Ferraiolo/dp/1580533701/sr=1-1/qid=1161828835/ref=pd_bbs_1/002-1138304-7372032?ie=UTF8&s=books

下一个项目的权限管理会比较复杂,以前没学过这方面的知识。从Acegi开始吧,如果够用最好。

6. JBoss JBoss的Cache,AppServer的cluster方面是我比较感兴趣的地方,想尝试一下JBoss应用服务器

7. 满足一定条件(比如: 并发达1000个请求)框架Web Application群集部署

posted @ 2007-02-02 15:28 比特鼠 阅读(230) | 评论 (0)编辑 收藏

关于Spring属性编辑器详解

原文出处:
http://stamen.javaeye.com/blog/24660

最近刚在研究Spring的编辑器,发现很有意思,刚好galaxystar起了一个这样贴,我想对PropertyEditor作一个详细的整理会对大家有益,特定启了这个新帖。

所谓的PropertyEditor,顾名思义,就是属性编辑器。由于Bean属性通过配置文档以字符串了方式为属性赋值,所以必须有一个“东东”负责将这个字符串转换为属性的直接对象,如属性的类型为int,那么编辑器要做的工作就是int i = Integer.parseInt("1");
Spring为一般的属性类型提供了默认的编辑器,BeanWrapperImpl是Spring框架中重要的类,它负责对注入的Bean进行包装化的管理,常见属性类型对应的编辑器即在该类中通过以下代码定义:

代码

但是,并非Bean的属性都是这些常见的类型,如果你的Bean需要注入一个自定义类型的属性,而又想享受IoC的好处,那么就只得自己开干,提供一个自定义的PropertyEditor了。
下面,分几个步骤来说明,定义一个自定义PropertyEditor的过程。
1)首先,碰到的问题即是,要如何编辑自己的PropertyEditor,其实需要了解一点java.beans包的知识,在该包中,有一个java.beans.PropertyEditor的接口,它定义了一套接口方法(12个),即通过这些方法如何将一个String变成内部的一个对象,这两个方法是比较重要的:
a)setValue(Object value) 直接设置一个对象,一般不直接用该方法设置属性对象
b)setAsText(String text) 通过一个字符串来构造对象,一般在此方法中解析字符串,将构造一个
类对象,调用setValue(Object)来完成属性对象设置操作。

2)实现所有的接口方法是麻烦的,java.beans.PropertyEditorSupport 适时登场,一般情况下,我们通过扩展这个方便类即可。

3)编写完后,就是在Spring配置文件中注册该属性类型编辑器的问题,Spring提供了专门的注册工具类
org.springframework.beans.factory.config.CustomEditorConfigurer,它负责将属性类型和
属性编辑器关联起来。到时BeanFactory注入Bean的属性时,即会在注册表中查找属性类型对应的编辑器。

下面给出一个小例子,例子先作一个简单描述:
1)Person 需要进行属性注入的Bean,有两个属性 一个是name,一个是address Address是一个类
2)Address Person的属性类型,本身有3个属性。
3)AddressPropertyEditor Address类型对应的属性编辑器。

开工:
1.Person.java

代码

2.Address.java
代码


AddressPropertyEditor.java
代码

打开Spring配置文件,添上这两个配置项:

代码

 

下面是我自己写的日期转换类:

我的配置:
posted @ 2007-01-20 21:21 比特鼠 阅读(402) | 评论 (0)编辑 收藏

Error convertoring HTML to XHTML: System.ArgumentException: Cannot have ']]>' inside an XML CDATA block. at System.Xml.XmlTextWriter.WriteCData(String text) at System.Xml.XmlWriter.WriteNode(XmlReader reader, Boolean defattr) at FreeTextBoxControls.Support.Formatter.HtmlToXhtml(String input)
posted @ 2007-01-19 16:51 比特鼠 阅读(206) | 评论 (0)编辑 收藏

原文出自: http://www.blogjava.net/waterye/archive/2005/08/23/10836.aspx

OpenSessionInView模式

Spring+Hibernate中,  集合映射如果使用lazy="true", 当PO传到View层时, 出现未初始化session已关闭的错误,只能在dao先初始化
parent.getChilds().size();

Spring提供Open Session In View来解决这个问题, 有两种方式
1. Interceptor
    <!--  =========== OpenSession In View pattern ============== -->
    
< bean  id ="openSessionInViewInterceptor"
          class
="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" >
        
< property  name ="sessionFactory"  ref ="sessionFactory" />
    
</ bean >

    
< bean  id ="urlMapping"  class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
        
< property  name ="interceptors"  ref ="openSessionInViewInterceptor" />
        
< property  name ="mappings" >
            
< props >
            ......
            
</ props >

        
</ property >
    
</ bean >
2. Filter
< web-app >
 
< filter >
< filter-name > hibernateFilter </ filter-name >
< filter-class >
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</ filter-class >
</ filter >
 
< filter-mapping >
< filter-name > hibernateFilter </ filter-name >
< url-pattern > *.do </ url-pattern >
</ filter-mapping >

</ web-app >

说明: 个人更喜欢用Interceptor方式, filter是在web.xml中定义
有了OpenSessionInView,并不是一切就ok了。简单的crud可以,但对于复杂业务逻辑就要想点法子。

OSIV默认是request per session的, 所以即使没有显式update(po),Hibernate也会帮你保存的,dao的业务判断就无效,还好有evict()可用。
update code
// Controller
public
 ModelAndView update() {
    p 
=
 dao.getVo(id);
    bindObject(request);
    dao.update(p);
}

// Dao
public
 Object getVo(id) {
    p 
=
 getHibernateTemplate().get(clazz, id);
    p.getChilds().size();
    getHibernateTemplate().evict(p);
    
return
 p;
}

public   void
 update(p) {
    oldP 
=
 getVo(id);
    
//  ++--(oldP);

    getHibernateTemplate().update(p);
    
//  ++--(p);

}
posted @ 2007-01-19 15:33 比特鼠 阅读(301) | 评论 (0)编辑 收藏

例如:
<class name="User" table="user">
<id name="id" column="id" type="java.lang.Long">
<generator class="native"/>
</id>

generator标识符生成器 描述

increment      适用于代理主键。由Hibernate自动以递增方式生成
identity      适用于代理主键。由底层数据库生成标识符
sequence      适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列
hilo         适用于代理主键。Hibernate分局high/low算法生成标识符
seqhilo       适用于代理主键。使用一个高/低位算法来高效的生成long,short或者int类型的标识符。
native        适用于代理主键。根据底层数据库对自动生成标识符的方式,自动选择identity、sequence或hilo
uuid.hex       适用于代理主键。Hibernate基于128 位UUID 算法生成16 进制数值(编码后以长度32 的字符串表示)
uuid.string      适用于代理主键。与uuid.hex 类似,只是生成的主键未进行编码(以长度16 的字符串表示),不能应用在 PostgreSQL 数据库中
assigned       适用于自然主键。由Java应用程序负责生成标识符
foreign        适用于代理主键。使用另外一个相关联的对象的标识符

以下举例:
1、指定参数的情况:
    <id name="id" unsaved-value="0">
      <generator class="sequence">
        <param name="sequence">SEQ_CHILD</param>
      </generator>
</id>
使用的是sequence,适合oracle数据库;


2、对于sql server2000中的数据库子增字段,在配置文件使用下列方法实现:
<id name="id" type="long" unsaved-value="0">
     <column name="id" sql-type="numeric" not-null="true" />
     <generator class="identity" />
</id>
这里主要是:identity:代表由sql server2000数据库自己提供子增字段.如果要hibernate自己提供,则用increment关键字来实现


3、如果表中的主键用字符串类型:可以用hibernate自己提供的方法实现主键唯一:
  <id name="id" type="string" unsaved-value="null">
      <column name="cid" sql-type="char(32)" not-null="true" />
      <generator class="uuid.hex" />
  </id>
使用的是uuid.hex: 采用128位的算法来生成一个32位字符串。最通用的一种方式。适用于所有数据库。


重要的知识点:
1. 如果有部门表,有员工表,员工表中有dep_id,则表部门类和员工类是one-to-many的关系:
   可以使用:  ( 在部门类department中使用下列)
   Department类: 
     /**  部门的所有员工   */
    private Set staffs = new TreeSet();
   
    xml的文件:
      <set name="staffs" >
          <key column="dep_id"/>
          <one-to-many class="hbp.sys.data.Staff"/>
      </set>
      如果是list,需要用索引<index> </index>,具体其中的含义,不是很明白.待以后研究
     
 2. 如果部门要有一个负责人,即部门表(tb_department)中有一个字段:staff_id.
     那么表示部门和负责人之间的关系是many-to-one的关系
     Department类:
      /** 部门负责人id */
    private Staff staff;
   
    xml 文件
     <many-to-one name="staff" class="hbp.sys.data.Staff"  column="staff_id"/> 
 
 3. 多对多关系,一般我们是做一个中间关联表.我用角色和权限做了个例子,
      Right(id,name)     Role(id,name)   中间表:tb_role_right(role_id,right_id)
      Right类中有一个Role的集合:private Set roles=new TreeSet();
      Role类中也有一个Right的集合:private Set rights=new TreeSet();
      则两者是明显的多对多关系.使用many-to-many来实现;
      xml文件中
      right.hbm.xml:如下:
        <set name="roles" table="tb_role_right" cascade="all">
           <key column="right_id"/>
           <many-to-many column="role_id" class="hbp.sys.data.Role"/>
        </set>
      role.hbm.xml文件中类似:
        <set name="rights" table="tb_role_right" cascade="all">
          <key column="role_id"/>
          <many-to-many column="right_id" class="hbp.sys.data.Right"/>
        </set>


4. 几个值得注意的问题:
        a)在xml?映射文件中,写类的名字时一定用类的全名:即:包+类名如:(hbp.sys.data.Staff),这个错误使我费了半天劲.:(
        b)我在写实现基本DAO操作时,写了
             session.delete("from Right as right where right.id="+id); 
             程序死活报错,我折腾了半天,跟踪到底,才恍然大悟,hibernate在解析sql语句的时候把
             其中的right,当成了数据库中的右连接("保留字"),唉,这种关键字,不能随便用啊,:)


5. hibernate中HQL语言的查询根据你的sql的不同而返回不同的对象类型.
         如果你使用session.find(String hql)
         一般会返回一个List,如:from Staff staff;返回的是包含所有的员工对象的集合
         如你的hql为:select count(*) from Staff staff;则返回的是一个Integer对象
         如果你使用的hql为:select count(distinct staff.name),count(*) from Staff staff;则返回的是一个Object
         即Object[],需要先把他转换成Object[],然后在取[0],[1].
         这种设计我不知道hibernate是如何处理的,感觉既好也不好.好的是可以使用一个find获得任意查询
         不好在于根据hql来处理返回结果,容易出错.

posted @ 2007-01-18 10:44 比特鼠 阅读(2077) | 评论 (0)编辑 收藏

<标识符>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef _STDIO_H_           //如果没有定义_STDIO_H_
#define _STDIO_H_  1        //则定义_STDIO_H_, 值为 1


1. 如果没有定义<标识符>, 则定义<标识符>
#ifndef <标识符>
#ifdefine <标识符> <标识符值>
..
..
#endif



2. 如果没有定义<标识符>, 则预编译程序段1, 否则编译程序段2

#ifndef <标识符> 
    
程序段1
 
#else

    
程序段2
 
#endif

3. 如果表达式的值不为0, 则编译程序段1, 否则编译程序段2

#if 表达式
    
程序段1
 
#else

    
程序段2
 
#endif


posted @ 2007-01-10 10:46 比特鼠 阅读(297) | 评论 (0)编辑 收藏

     摘要: JS的正则表达式 //校验是否全由数字组成 代码 function isDigit(s)    ...  阅读全文
posted @ 2006-12-20 21:49 比特鼠 阅读(214) | 评论 (0)编辑 收藏



正则表达式测试(V0.1)

表达式:
测试值:
输出值:
标  识: 全局  忽略  多行   方  法:
        


posted @ 2006-12-20 21:40 比特鼠 阅读(612) | 评论 (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*$)

应用:javascript中没有像vbscript那样的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

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

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

s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$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,''))"

posted @ 2006-12-20 21:25 比特鼠 阅读(268) | 评论 (0)编辑 收藏

仅列出标题
共6页: 上一页 1 2 3 4 5 6 下一页