Energy of Love  
日历
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 70
  • 文章 - 0
  • 评论 - 80
  • 引用 - 0

导航

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

JAVA EXCEL API 简介

Java Excel 是一开放源码项目,通过它 Java 开发人员可以读取 Excel 文件的内容、创建新的 Excel 文件、更新已经存在的 Excel 文件。使用该 API 非 Windows 操作系统也可以通过纯 Java 应用来处理 Excel 数据表。因为是使用 Java 编写的,所以我们在 Web 应用中可以通过 JSP、Servlet 来调用 API 实现对 Excel 数据表的访问。

现在发布的稳定版本是 V2.0,提供以下功能:

  • 从 Excel 95、97、2000 等格式的文件中读取数据;
  • 读取 Excel 公式(可以读取 Excel 97 以后的公式);
  • 生成 Excel 数据表(格式为 Excel 97);
  • 支持字体、数字、日期的格式化;
  • 支持单元格的阴影操作,以及颜色操作;
  • 修改已经存在的数据表;

现在还不支持以下功能,但不久就会提供了:

  1. 不能够读取图表信息;
  2. 可以读,但是不能生成公式,任何类型公式最后的计算值都可以读出;

回页首

应用示例

1 从 Excel 文件读取数据表

Java Excel API 既可以从本地文件系统的一个文件 (.xls),也可以从输入流中读取 Excel 数据表。读取 Excel 数据表的第一步是创建 Workbook( 术语:工作薄 ),下面的代码片段举例说明了应该如何操作:( 完整代码见 ExcelReading.java)

 import java.io.*; import jxl.*; … … … … try { // 构建 Workbook 对象 , 只读 Workbook 对象 // 直接从本地文件创建 Workbook // 从输入流创建 Workbook InputStream is = new FileInputStream(sourcefile); jxl.Workbook rwb = Workbook.getWorkbook(is); } catch (Exception e) { e.printStackTrace(); } 

一旦创建了 Workbook,我们就可以通过它来访问 Excel Sheet( 术语:工作表 )。参考下面的代码片段:

 // 获取第一张 Sheet 表 Sheet rs = rwb.getSheet(0); 

我们既可能通过 Sheet 的名称来访问它,也可以通过下标来访问它。如果通过下标来访问的话,要注意的一点是下标从 0 开始,就像数组一样。

一旦得到了 Sheet,我们就可以通过它来访问 Excel Cell( 术语:单元格 )。参考下面的代码片段:

 // 获取第一行,第一列的值 Cell c00 = rs.getCell(0, 0); String strc00 = c00.getContents(); // 获取第一行,第二列的值 Cell c10 = rs.getCell(1, 0); String strc10 = c10.getContents(); // 获取第二行,第二列的值 Cell c11 = rs.getCell(1, 1); String strc11 = c11.getContents(); System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType()); System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType()); System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType()); 

如果仅仅是取得 Cell 的值,我们可以方便地通过 getContents() 方法,它可以将任何类型的 Cell 值都作为一个字符串返回。示例代码中 Cell(0, 0) 是文本型,Cell(1, 0) 是数字型,Cell(1,1) 是日期型,通过 getContents(),三种类型的返回值都是字符型。

如果有需要知道 Cell 内容的确切类型,API 也提供了一系列的方法。参考下面的代码片段:

 String strc00 = null; double strc10 = 0.00; Date strc11 = null; Cell c00 = rs.getCell(0, 0); Cell c10 = rs.getCell(1, 0); Cell c11 = rs.getCell(1, 1); if(c00.getType() == CellType.LABEL) { LabelCell labelc00 = (LabelCell)c00; strc00 = labelc00.getString(); } if(c10.getType() == CellType.NUMBER) { NmberCell numc10 = (NumberCell)c10; strc10 = numc10.getValue(); } if(c11.getType() == CellType.DATE) { DateCell datec11 = (DateCell)c11; strc11 = datec11.getDate(); } System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType()); System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType()); System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType()); 

在得到 Cell 对象后,通过 getType() 方法可以获得该单元格的类型,然后与 API 提供的基本类型相匹配,强制转换成相应的类型,最后调用相应的取值方法 getXXX(),就可以得到确定类型的值。API 提供了以下基本类型,与 Excel 的数据格式相对应,如下图所示:


 

每种类型的具体意义,请参见 Java Excel API Document。

当你完成对 Excel 电子表格数据的处理后,一定要使用 close() 方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要。参考如下代码片段:

 // 操作完成时,关闭对象,释放占用的内存空间 rwb.close(); 

Java Excel API 提供了许多访问 Excel 数据表的方法,在这里我只简要地介绍几个常用的方法,其它的方法请参考附录中的 Java Excel API Document。

Workbook 类提供的方法

1. int getNumberOfSheets() 
获得工作薄(Workbook)中工作表(Sheet)的个数,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); int sheets = rwb.getNumberOfSheets(); 

2. Sheet[] getSheets() 
返回工作薄(Workbook)中工作表(Sheet)对象数组,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); Sheet[] sheets = rwb.getSheets(); 

3. String getVersion() 
返回正在使用的 API 的版本号,好像是没什么太大的作用。

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); String apiVersion = rwb.getVersion(); 

Sheet 接口提供的方法

1) String getName() 
获取 Sheet 的名称,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); String sheetName = rs.getName(); 

2) int getColumns() 
获取 Sheet 表中所包含的总列数,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); int rsColumns = rs.getColumns(); 

3) Cell[] getColumn(int column) 
获取某一列的所有单元格,返回的是单元格对象数组,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); Cell[] cell = rs.getColumn(0); 

4) int getRows() 
获取 Sheet 表中所包含的总行数,示例:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); int rsRows = rs.getRows(); 

5) Cell[] getRow(int row) 
获取某一行的所有单元格,返回的是单元格对象数组,示例子:

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); Cell[] cell = rs.getRow(0); 

6) Cell getCell(int column, int row) 
获取指定单元格的对象引用,需要注意的是它的两个参数,第一个是列数,第二个是行数,这与通常的行、列组合有些不同。

 jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile)); jxl.Sheet rs = rwb.getSheet(0); Cell cell = rs.getCell(0, 0); 

2 生成新的 Excel 工作薄

下面的代码主要是向大家介绍如何生成简单的 Excel 工作表,在这里单元格的内容是不带任何修饰的 ( 如:字体,颜色等等 ),所有的内容都作为字符串写入。( 完整代码见 ExcelWriting.java)

与读取 Excel 工作表相似,首先要使用 Workbook 类的工厂方法创建一个可写入的工作薄 (Workbook) 对象,这里要注意的是,只能通过 API 提供的工厂方法来创建 Workbook,而不能使用 WritableWorkbook 的构造函数,因为类 WritableWorkbook 的构造函数为 protected 类型。示例代码片段如下:

 import java.io.*; import jxl.*; import jxl.write.*; … … … … try { // 构建 Workbook 对象 , 只读 Workbook 对象 //Method 1:创建可写入的 Excel 工作薄 jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile)); //Method 2:将 WritableWorkbook 直接写入到输出流 /* OutputStream os = new FileOutputStream(targetfile); jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os); */ } catch (Exception e) { e.printStackTrace(); } 

API 提供了两种方式来处理可写入的输出流,一种是直接生成本地文件,如果文件名不带全路径的话,缺省的文件会定位在当前目录,如果文件名带有全路径的话,则生成的 Excel 文件则会定位在相应的目录;另外一种是将 Excel 对象直接写入到输出流,例如:用户通过浏览器来访问 Web 服务器,如果 HTTP 头设置正确的话,浏览器自动调用客户端的 Excel 应用程序,来显示动态生成的 Excel 电子表格。

接下来就是要创建工作表,创建工作表的方法与创建工作薄的方法几乎一样,同样是通过工厂模式方法获得相应的对象,该方法需要两个参数,一个是工作表的名称,另一个是工作表在工作薄中的位置,参考下面的代码片段:

 // 创建 Excel 工作表 jxl.write.WritableSheet ws = wwb.createSheet("Test Sheet 1", 0); 

"这锅也支好了,材料也准备齐全了,可以开始下锅了!",现在要做的只是实例化 API 所提供的 Excel 基本数据类型,并将它们添加到工作表中就可以了,参考下面的代码片段:

 //1. 添加 Label 对象 jxl.write.Label labelC = new jxl.write.Label(0, 0, "This is a Label cell"); ws.addCell(labelC); // 添加带有字型 Formatting 的对象 jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true); jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf); jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF); ws.addCell(labelCF); // 添加带有字体颜色 Formatting 的对象 jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED); jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc); jxl.write.Label labelCFC = new jxl.write.Label(1, 0, "This is a Label Cell", wcfFC); ws.addCell(labelCF); //2. 添加 Number 对象 jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926); ws.addCell(labelN); // 添加带有 formatting 的 Number 对象 jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##"); jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf); jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN); ws.addCell(labelNF); //3. 添加 Boolean 对象 jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false); ws.addCell(labelB); //4. 添加 DateTime 对象 jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date()); ws.addCell(labelDT); // 添加带有 formatting 的 DateFormat 对象 jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss"); jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df); jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF); ws.addCell(labelDTF); 

这里有两点大家要引起大家的注意。第一点,在构造单元格时,单元格在工作表中的位置就已经确定了。一旦创建后,单元格的位置是不能够变更的,尽管单元格的内容是可以改变的。第二点,单元格的定位是按照下面这样的规律 (column, row),而且下标都是从 0 开始,例如,A1 被存储在 (0, 0),B1 被存储在 (1, 0)。

最后,不要忘记关闭打开的 Excel 工作薄对象,以释放占用的内存,参见下面的代码片段:

 // 写入 Exel 工作表 wwb.write(); // 关闭 Excel 工作薄对象 wwb.close(); 

这可能与读取 Excel 文件的操作有少少不同,在关闭 Excel 对象之前,你必须要先调用 write() 方法,因为先前的操作都是存储在缓存中的,所以要通过该方法将操作的内容保存在文件中。如果你先关闭了 Excel 对象,那么只能得到一张空的工作薄了。

3 拷贝、更新 Excel 工作薄

接下来简要介绍一下如何更新一个已经存在的工作薄,主要是下面二步操作,第一步是构造只读的 Excel 工作薄,第二步是利用已经创建的 Excel 工作薄创建新的可写入的 Excel 工作薄,参考下面的代码片段:( 完整代码见 ExcelModifying.java)

 // 创建只读的 Excel 工作薄的对象 jxl.Workbook rw = jxl.Workbook.getWorkbook(new File(sourcefile)); // 创建可写入的 Excel 工作薄对象 jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile), rw); // 读取第一张工作表 jxl.write.WritableSheet ws = wwb.getSheet(0); // 获得第一个单元格对象 jxl.write.WritableCell wc = ws.getWritableCell(0, 0); // 判断单元格的类型 , 做出相应的转化 if(wc.getType() == CellType.LABEL) { Label l = (Label)wc; l.setString("The value has been modified."); } // 写入 Excel 对象 wwb.write(); // 关闭可写入的 Excel 对象 wwb.close(); // 关闭只读的 Excel 对象 rw.close(); 

之所以使用这种方式构建 Excel 对象,完全是因为效率的原因,因为上面的示例才是 API 的主要应用。为了提高性能,在读取工作表时,与数据相关的一些输出信息,所有的格式信息,如:字体、颜色等等,是不被处理的,因为我们的目的是获得行数据的值,既使没有了修饰,也不会对行数据的值产生什么影响。唯一的不利之处就是,在内存中会同时保存两个同样的工作表,这样当工作表体积比较大时,会占用相当大的内存,但现在好像内存的大小并不是什么关键因素了。

一旦获得了可写入的工作表对象,我们就可以对单元格对象进行更新的操作了,在这里我们不必调用 API 提供的 add() 方法,因为单元格已经于工作表当中,所以我们只需要调用相应的 setXXX() 方法,就可以完成更新的操作了。

尽单元格原有的格式化修饰是不能去掉的,我们还是可以将新的单元格修饰加上去,以使单元格的内容以不同的形式表现。

新生成的工作表对象是可写入的,我们除了更新原有的单元格外,还可以添加新的单元格到工作表中,这与示例 2 的操作是完全一样的。

最后,不要忘记调用 write() 方法,将更新的内容写入到文件中,然后关闭工作薄对象,这里有两个工作薄对象要关闭,一个是只读的,另外一个是可写入的。

回页首

小结

本文只是对 Java Excel API 中常用的方法作了介绍,要想更详尽地了解 API,请大家参考 API 文档,或源代码。Java Excel API 是一个开放源码项目,请大家关注它的最新进展,有兴趣的朋友也可以申请加入这个项目,或者是提出宝贵的意见。

posted @ 2011-12-05 15:48 不高兴 阅读(455) | 评论 (1)编辑 收藏
 
使用Junit4.4测试 
在类上的配置Annotation 
@RunWith(SpringJUnit4ClassRunner.class) 用于配置spring中测试的环境 
@ContextConfiguration(Locations="../applicationContext.xml") 用于指定配置文件所在的位置 
@Test标注在方法前,表示其是一个测试的方法 无需在其配置文件中额外设置属性. 

多个配置文件时{"/applic","/asas"} 可以导入多个配置文件 

测试中的事务配置 , 
AbstractTransactionalJUnit38SpringContextTests、 AbstractTransactionalJUnit4SpringContextTests 
AbstractTransactionalTestNGSpringContextTests 
已经在类级别预先配置了好了事物支持 

在普通spring的junit环境中配置事务 
在类之前加入注解 
@TransactionConfiguration(transactionManagert="txMgr",defaultRollback=false) 
@Transactional 
在方法中主要使用的Annotation包括 
@TestExecutionListeners({})---用于禁用默认的监听器 否着需要通过@contextconfiguration配置一个ApplicationContext; 

@BeforeTransaction 
@Before 
@Rollback(true) 
@AfterTransaction 
@NotTransactional 

Junit4.4下支持类,方便基于junit4.4的测试 
AbstractJUnit4SpringContextTests: 

AbstractTransactionalJUnit4SpringContextTests: 
需要在applicationContext中定义一个datasource 

2009年3月9日 
目前Spring2.5只支持4.4的Junit进行测试 
下面是一个简单的测试Demo 

 1 package com.gameplus.service.webService;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.test.context.ContextConfiguration;
 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 9 
10 @RunWith(SpringJUnit4ClassRunner.class)
11 @ContextConfiguration(locations={"../../../../applicationContext.xml","../../../../applicationDatasource.xml"})
12 public class UserServiceTest  {
13     @Resource
14     private IUserService userService;
15     
16     @Test
17     public void testAddOpinion1() {
18         userService.downloadCount(1);
19         System.out.println(1);
20     }
21     @Test
22     public void testAddOpinion2() {
23         userService.downloadCount(2);
24         System.out.println(2);
25     }
26 }
27 

注意需要新的Jar包如下 
javassist-3.4.GA.jar 
hibernate3.jar 
hibernate-annotations.jar 
尤其注意用新版的,旧版会出现类未找到的异常 
posted @ 2011-11-30 19:38 不高兴 阅读(54701) | 评论 (3)编辑 收藏
 

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://ralf0131.blogbus.com/logs/55701639.html

参考:http://www.javaeye.com/topic/14631
关于JUnit4: http://www.ibm.com/developerworks/cn/java/j-junit4.html

背景:
如果在Hibernate层采用lazy=true的话,有的时候会抛出LazyInitializationException,这时一种解决办法是用OpenSessionInViewFilter,但是如果通过main方法来运行一些测试程序,那么上述方法就没有用武之地了。这里提供了一种方法,来达到实现和OpenSessionInViewFilter相同作用的目的。这里的应用场景是采用JUnit4来编写测试用例。

JUnit4的好处是:采用annotation来代替反射机制,不必写死方法名.
首先添加一个abstract class(AbstractBaseTestCase.class), 做一些准备性的工作:
(可以看到@Before和@After两个annotation的作用相当于setUp()和tearDown()方法,但是,显然更灵活)

package testcase;

import org.hibernate.FlushMode;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.junit.After;

import org.junit.Before;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import org.springframework.orm.hibernate3.SessionFactoryUtils;

import org.springframework.orm.hibernate3.SessionHolder;

import org.springframework.transaction.support.TransactionSynchronizationManager;

 

/***

 * An abstract base class for TestCases.

 * All test cases should extend this class.

 */

public class AbstractBaseTestCase {

 

    private SessionFactory sessionFactory;  

    private Session session;  

    protected FileSystemXmlApplicationContext dsContext;

    private String []configStr = {"/WebRoot/WEB-INF/applicationContext.xml"};  

@Before

public void openSession() throws Exception {

dsContext = new FileSystemXmlApplicationContext(configStr);

        sessionFactory = (SessionFactory) dsContext.getBean("sessionFactory");  

        session = SessionFactoryUtils.getSession(sessionFactory, true);  

        session.setFlushMode(FlushMode.MANUAL);  

        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); 

}

 

@After

public void closeSession() throws Exception {

TransactionSynchronizationManager.unbindResource(sessionFactory);  

        SessionFactoryUtils.releaseSession(session, sessionFactory);  

}

}

接下来继承上述基类,实现测试逻辑:
(注意import static用于引用某个类的静态方法)
(@Test注解表明该方法是一个测试方法)
package testcase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
public class testCase1 extends AbstractBaseTestCase {
private YourManager manager;
@Before
public void prepare(){
manager = (YourManager)dsContext.getBean("YourManager");
}
@Test 
public void test1(){
try {
String result = manager.do_sth();
System.out.println(result);
assertEquals(result, EXPECTED_RESULT);
} catch (Exception e) {
e.printStackTrace();
fail("Exception thrown.");
}
}
}
posted @ 2011-11-30 19:19 不高兴 阅读(2254) | 评论 (0)编辑 收藏
 
document.getElementById(obj).style.backgroundPosition="10px 0px";
posted @ 2011-11-15 14:44 不高兴 阅读(1156) | 评论 (1)编辑 收藏
 
window.onload =function() { 
(function(b)
{
var a=document.createElement("script");
a.setAttribute("charset","utf-8");
a.setAttribute("type","text/javascript");
a.setAttribute("src",b);
document.getElementsByTagName("head")[0].appendChild(a)
}
)("1.js");
}
posted @ 2011-09-08 10:25 不高兴 阅读(400) | 评论 (0)编辑 收藏
 
String[] userData = "1######".split("#");
System.out.println(userData.length);
输出:userData.length = 1
该方法的作用就像是使用给定的表达式和限制参数 0 来调用两参数 split 方法。因此,结果数组中不包括结尾空字符串。 

Java代码  收藏代码
  1. // Construct result  
  2.         int resultSize = matchList.size();  
  3.         if (limit == 0)  
  4.             while (resultSize > 0 && matchList.get(resultSize-1).equals(""))  
  5.                 resultSize--;  
  6.         String[] result = new String[resultSize];  
  7.         return matchList.subList(0, resultSize).toArray(result);  



split方法是调用Pattern的split实现的,看上面代码中的 
while (resultSize > 0 && matchList.get(resultSize-1).equals("")) 
                resultSize--; 
可见。字符串末尾的空字符串将从匹配结果中去除 
posted @ 2011-08-25 15:37 不高兴 阅读(1125) | 评论 (0)编辑 收藏
 

idCard.js部分*******************************************************


//****************************************************************************

// 构造函数,变量为15位或者18位的身份证号码
function clsIDCard(CardNo) {
  this.Valid=false;
  this.ID15='';
  this.ID18='';
  this.Local='';
  if(CardNo!=null)this.SetCardNo(CardNo);
}

// 设置身份证号码,15位或者18位
clsIDCard.prototype.SetCardNo = function(CardNo) {
  this.ID15='';
  this.ID18='';
  this.Local='';
  CardNo=CardNo.replace(" ","");
  var strCardNo;
  if(CardNo.length==18) {
    pattern= /^\d{17}(\d|x|X)$/;
    if (pattern.exec(CardNo)==null)return;
    strCardNo=CardNo.toUpperCase();
  } else {
    pattern= /^\d{15}$/;
    if (pattern.exec(CardNo)==null)return;
    strCardNo=CardNo.substr(0,6)+'19'+CardNo.substr(6,9)
    strCardNo+=this.GetVCode(strCardNo);
  }
  this.Valid=this.CheckValid(strCardNo);
}

// 校验身份证有效性
clsIDCard.prototype.IsValid = function() {
  return this.Valid;
}

// 返回生日字符串,格式如下,1981-10-10
clsIDCard.prototype.GetBirthDate = function() {
  var BirthDate='';
  if(this.Valid)BirthDate=this.GetBirthYear()+'-'+this.GetBirthMonth()+'-'+this.GetBirthDay();
  return BirthDate;
}

// 返回生日中的年,格式如下,1981
clsIDCard.prototype.GetBirthYear = function() {
  var BirthYear='';
  if(this.Valid)BirthYear=this.ID18.substr(6,4);
  return BirthYear;
}

// 返回生日中的月,格式如下,10
clsIDCard.prototype.GetBirthMonth = function() {
  var BirthMonth='';
  if(this.Valid)BirthMonth=this.ID18.substr(10,2);
  if(BirthMonth.charAt(0)=='0')BirthMonth=BirthMonth.charAt(1);
  return BirthMonth;
}

// 返回生日中的日,格式如下,10
clsIDCard.prototype.GetBirthDay = function() {
  var BirthDay='';
  if(this.Valid)BirthDay=this.ID18.substr(12,2);
  return BirthDay;
}

// 返回性别,1:男,0:女
clsIDCard.prototype.GetSex = function() {
  var Sex='';
  if(this.Valid)Sex=this.ID18.charAt(16)%2;
  return Sex;
}

// 返回15位身份证号码
clsIDCard.prototype.Get15 = function() {
  var ID15='';
  if(this.Valid)ID15=this.ID15;
  return ID15;
}

// 返回18位身份证号码
clsIDCard.prototype.Get18 = function() {
  var ID18='';
  if(this.Valid)ID18=this.ID18;
  return ID18;
}

// 返回所在省,例如:上海市、浙江省
clsIDCard.prototype.GetLocal = function() {
  var Local='';
  if(this.Valid)Local=this.Local;
  return Local;
}

clsIDCard.prototype.GetVCode = function(CardNo17) {
  var Wi = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1);
  var Ai = new Array('1','0','X','9','8','7','6','5','4','3','2');
  var cardNoSum = 0;
  for (var i=0; i<CardNo17.length; i++)cardNoSum+=CardNo17.charAt(i)*Wi[i];
  var seq = cardNoSum%11;
  return Ai[seq];
}

clsIDCard.prototype.CheckValid = function(CardNo18) {
  if(this.GetVCode(CardNo18.substr(0,17))!=CardNo18.charAt(17))return false;
  if(!this.IsDate(CardNo18.substr(6,8)))return false;
  var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"};
  if(aCity[parseInt(CardNo18.substr(0,2))]==null)return false;
  this.ID18=CardNo18;
  this.ID15=CardNo18.substr(0,6)+CardNo18.substr(8,9);
  this.Local=aCity[parseInt(CardNo18.substr(0,2))];
  return true;
}

clsIDCard.prototype.IsDate = function(strDate) {
  var r = strDate.match(/^(\d{1,4})(\d{1,2})(\d{1,2})$/);
  if(r==null)return false;
  var d= new Date(r[1], r[2]-1, r[3]);
  return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[2]&&d.getDate()==r[3]);
}

 

页面部分**************************************************************

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>身份证验证</title>
<script src="idCard.js"></script>
</head>
<body>
<script>
 function valiIdCard(idCard){
  var checkFlag = new clsIDCard(idCard);
  if (!checkFlag.IsValid()) {
   alert("输入的身份证号无效,请输入真实的身份证号!");
   document.getElementByIdx("idCard").focus();
   return false;
  }else{
    alert("正确!");
  }
 }

</script>
<input id="idCard" type="text" onblur="valiIdCard(this.value)"/>
</body>

posted @ 2011-08-25 14:56 不高兴 阅读(10233) | 评论 (6)编辑 收藏
 
该骗子诈骗短信内容:“温馨提示,现已从您帐上支出1300元,,工行客服:021—60512737。
posted @ 2010-10-18 11:05 不高兴 阅读(294) | 评论 (0)编辑 收藏
 
第一步:加入log4j-1.2.8.jar到lib下。

第二步:在CLASSPATH下建立log4j.properties。内容如下:

1 log4j.rootCategory=INFO, stdout , R

2

3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender

4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

5 log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n

6

7 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

8 log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log

9 log4j.appender.R.layout=org.apache.log4j.PatternLayout

10 log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

11

12 log4j.logger.com.neusoft=DEBUG

13 log4j.logger.com.opensymphony.oscache=ERROR

14 log4j.logger.net.sf.navigator=ERROR

15 log4j.logger.org.apache.commons=ERROR

16 log4j.logger.org.apache.struts=WARN

17 log4j.logger.org.displaytag=ERROR

18 log4j.logger.org.springframework=DEBUG

19 log4j.logger.com.ibatis.db=WARN

20 log4j.logger.org.apache.velocity=FATAL

21

22 log4j.logger.com.canoo.webtest=WARN

23

24 log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

25 log4j.logger.org.hibernate=DEBUG

26 log4j.logger.org.logicalcobwebs=WARN

第三步:相应的修改其中属性,修改之前就必须知道这些都是干什么的,在第二部分讲解。

第四步:在要输出日志的类中加入相关语句:

定义属性:protected final Log log = LogFactory.getLog(getClass());

在相应的方法中:

if (log.isDebugEnabled())

{

log.debug(“System …..”);

}

二、Log4j说明

1 log4j.rootCategory=INFO, stdout , R

此句为将等级为INFO的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。等级可分为OFF、 FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示,具体讲解可参照第三部分定义配置文件中的logger。

3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender

此句为定义名为stdout的输出端是哪种类型,可以是

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

具体讲解可参照第三部分定义配置文件中的Appender。

4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

此句为定义名为stdout的输出端的layout是哪种类型,可以是

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

具体讲解可参照第三部分定义配置文件中的Layout。

5 log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n

如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

[QC]是log信息的开头,可以为任意字符,一般为项目简称。

输出的信息

[TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean 'MyAutoProxy'

具体讲解可参照第三部分定义配置文件中的格式化日志信息。

7 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

此句与第3行一样。定义名为R的输出端的类型为每天产生一个日志文件。

8 log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log

此句为定义名为R的输出端的文件名为D:\Tomcat 5.5\logs\qc.log

可以自行修改。

9 log4j.appender.R.layout=org.apache.log4j.PatternLayout

与第4行相同。

10 log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

与第5行相同。

12 log4j.logger.com. neusoft =DEBUG

指定com.neusoft包下的所有类的等级为DEBUG。

可以把com.neusoft改为自己项目所用的包名。

13 log4j.logger.com.opensymphony.oscache=ERROR

14 log4j.logger.net.sf.navigator=ERROR

这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。

15 log4j.logger.org.apache.commons=ERROR

16 log4j.logger.org.apache.struts=WARN

这两句是struts的包。

17 log4j.logger.org.displaytag=ERROR

这句是displaytag的包。(QC问题列表页面所用)

18 log4j.logger.org.springframework=DEBUG

此句为Spring的包。

24 log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

25 log4j.logger.org.hibernate=DEBUG

此两句是hibernate的包。

以上这些包的设置可根据项目的实际情况而自行定制。

三、log4j详解

1、定义配置文件

Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件log4j.properties(键=值)。下面将介绍使用log4j.properties文件作为配置文件的方法:

、配置根Logger

Logger 负责处理日志记录的大部分操作。

其语法为:

log4j.rootLogger = [ level ] , appenderName, appenderName, …

其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。Log4j建议只使用四个级别,优 先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定 义了INFO级别,只有等于及高于这个级别的才进行处理,则应用程序中所有DEBUG级别的日志信息将不被打印出来。ALL:打印所有的日志,OFF:关 闭所有的日志输出。 appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。

、配置日志信息输出目的地 Appender

Appender 负责控制日志记录操作的输出。

其语法为:

log4j.appender.appenderName = fully.qualified.name.of.appender.class

log4j.appender.appenderName.option1 = value1



log4j.appender.appenderName.optionN = valueN

这里的appenderName为在①里定义的,可任意起名。

其中,Log4j提供的appender有以下几种:

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),可通过 log4j.appender.R.MaxFileSize=100KB设置文件大小,还可通过 log4j.appender.R.MaxBackupIndex=1设置为保存一个备份文件。

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender

定义一个名为stdout的输出目的地,ConsoleAppender为控制台。

、配置日志信息的格式(布局)Layout

Layout 负责格式化Appender的输出。

其语法为:

log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class

log4j.appender.appenderName.layout.option1 = value1



log4j.appender.appenderName.layout.optionN = valueN

其中,Log4j提供的layout有以下几种:

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

2、格式化日志信息

Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

3、在代码中使用Log4j

我们在需要输出日志信息的类中做如下的三个工作:

1、导入所有需的commongs-logging类:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

2、在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类成员:

private final Log log = LogFactory.getLog(getClass());

LogFactory.getLog()方法的参数使用的是当前类的class。

3、使用org.apache.commons.logging.Log类的成员方法输出日志信息:

if (log.isDebugEnabled())
{
log.debug("111");
}
if (log.isInfoEnabled())
{
log.info("222");
}
if (log.isWarnEnabled())
{
log.warn("333");
}
if (log.isErrorEnabled())
{
log.error("444");
}
if (log.isFatalEnabled())
{
log.fatal("555")
}



log4j中关闭memcached日志
log4j.logger.com.danga.MemCached.MemCachedClient=ERROR
posted @ 2010-09-01 14:53 不高兴 阅读(265) | 评论 (0)编辑 收藏
 
一、连接池概述
 数据库连接池概述:
  数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个
应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
  数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个;释放空闲时
间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
  数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些
数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接
数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。数据库连接池的最小连接数和最大连接数的设
置要考虑到下列几个因素:
  1) 最小连接数是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费;
  2) 最大连接数是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之
后的数据库操作。
  3) 如果最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库
连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
目前常用的连接池有:C3P0、DBCP、Proxool
网上的评价是:
C3P0比较耗费资源,效率方面可能要低一点。
DBCP在实践中存在BUG,在某些种情会产生很多空连接不能释放,Hibernate3.0已经放弃了对其的支持。
Proxool的负面评价较少,现在比较推荐它,而且它还提供即时监控连接池状态的功能,便于发现连接泄漏的情况。
配置如下:
1、在spring配置文件中,一般在applicationContext.xml中
     <bean id="proxoolDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
            <property name="driver" value="${jdbc.connection.driverClassName}"/>
            <property name="driverUrl" value="${jdbc.connection.url}"/>
            <property name="user" value="${jdbc.connection.username}"/>
            <property name="password" value="${jdbc.connection.password}"/>
            <!-- 测试的SQL执行语句 -->
           <property name="houseKeepingTestSql" value="${proxool.houseKeepingTestSql}"/>
            <!-- 最少保持的空闲连接数 (默认2个) -->
             <property name="prototypeCount" value="${proxool.prototypeCount}"/>
            <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒) -->
            <property name="houseKeepingSleepTime" value="${proxool.hourseKeepingSleepTime}"/>
            <!-- 最大活动时间(超过此时间线程将被kill,默认为5分钟) -->
             <property name="maximumActiveTime" value="${proxool.maximumActiveTime}"/>
            <!-- 连接最长时间(默认为4个小时) -->
            <property name="maximumConnectionLifetime" value="${proxool.maximumConnectionLifetime}"/>
            <!-- 最小连接数 (默认2个) -->
            <property name="minimumConnectionCount" value="${proxool.minimumConnectionCount}"/>
            <!-- 最大连接数 (默认5个) -->
            <property name="maximumConnectionCount" value="${proxool.maximumConnectionCount}"/>
            <!-- -->
            <property name="statistics" value="${proxool.statistics}"/>
            <!-- 别名 -->
             <property name="alias" value="${proxool.alias}"/>
            <!-- -->
            <property name="simultaneousBuildThrottle" value="${proxool.simultaneous-build-throttle}"/>
     </bean>
     然后注入到sessionFactory中
     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
           <property name="dataSource" ref="proxoolDataSource"/>
     </bean>
 
Porxool 配置文件
--==--==--==--==--==<proxool.xml>==--==--==--==--==--==--==
<?xml version="1.0" encoding="UTF-8"?>
<proxool>
      <alias>WMS</alias>
      <driver-url>jdbc:postgresql://192.168.210.184:5432/wms</driver-url>
      <driver-class>org.postgresql.Driver</driver-class>
      <driver-properties>
             <property name="user" value="wms_user" />
             <property name="password" value="wms" />
      </driver-properties>
      <minimum-connection-count>2</minimum-connection-count>
      <maximum-connection-count>40</maximum-connection-count>
      <simultaneous-build-throttle>20</simultaneous-build-throttle>
      <prototype-count>2</prototype-count>
      <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
</proxool>
--==--==--==--==--==<proxool.xml>==--==--==--==--==--==--==
 
配置说明:
alias                                          -〉数据库连接别名(程序中需要使用的名称)
driver-url                                   -〉数据库驱动
driver-class                                -〉驱动程序类
driver-properties                        -〉联机数据库的用户和密码
minimum-connection-count          -〉最小连接数量,建议设置0以上,保证第一次连接时间
maximum-connection-count         -〉最大连接数量,如果超过最大连接数量则会抛出异常。连接数设置过多,服务器CPU和内存性能消耗很
大。
simultaneous-build-throttle          -〉同时最大连接数
prototype-count                          -〉一次产生连接的数量。
                                                 例:如果现在prototype-count设置为4个,但是现在已经有2个可以获得的连接,那么
将会试图再创建2个连接。
                                                  但不能超过最大连接数。
maximum-active-time                 -〉连接最大时间活动 默认5分钟
maximum-connection-lifetime      -〉连接最大生命时间 默认4小时
posted @ 2010-08-27 10:25 不高兴 阅读(28708) | 评论 (2)编辑 收藏
仅列出标题
共7页: 上一页 1 2 3 4 5 6 7 下一页 
 
Copyright © 不高兴 Powered by: 博客园 模板提供:沪江博客