1用JAVA自带的函数
publicstaticbooleanisNumeric(String str){
for(inti=str.length();--i>=0;){
if(!Character.isDigit(str.charAt(i))){
returnfalse;
}
}
returntrue;
}
2用正则表达式
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
return pattern.matcher(str).matches();
}
3用ascii码
public static booleanisNumeric(String str){
for(inti=str.length();--i>=0;){
intchr=str.charAt(i);
if(chr<48 || chr>57)
return false;
}
return true;
}
posted @
2007-10-14 01:31 jadmin 阅读(74) |
评论 (0) |
编辑 收藏
import java.io.*;
public class ToFile
{
public static void main(String[] args)
{
try
{
String filename = "out.txt";
BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
bw.write("Hello,China!");
bw.write("\n");
bw.write("Hello,World!");
bw.close();
}
catch(IOException e)
{
System.out.println("IOException");
e.printStackTrace();
}
}
}
posted @
2007-10-08 21:45 jadmin 阅读(92) |
评论 (0) |
编辑 收藏
古之欲明明德于天下者,先治其国;
欲治其国者,先齐其家;欲齐其家者,先修其身;
欲修其身者,先正其心;欲正其心者,先诚其意;
欲诚其意者,先致其知,致知在格物。
posted @
2007-10-04 12:36 jadmin 阅读(127) |
评论 (0) |
编辑 收藏
在网络给我们的工作学习带来极大方便的同时,病毒、木马、后门以及黑客程序也严重影响着信息的安全。这些程序感染计算机的一个共同特点是在注册表中写入信息,来达到如自动运行、破坏和传播等目的。以下是笔者在网上收集的,通过修改注册表来对付病毒、木马、后门以及黑客程序,保证个人计算机的安全。
1.清理访问“网络邻居”后留下的字句信息
在HEKY_CURRENT_USER\Network\Recent下,删除下面的主键。
2.取消登陆时自动拨号
在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Network\RealModeNet下修改右边窗口中的“autologon”为“01 00 00 00 00”。
3.取消登录时选择用户
已经删除了所有用户,但登录时还要选择用户,我们要取消登录时选择用户,就要在HKEY_LOCAL_MACHINENetworkLogon下,在右边的窗口中,修改"UserProfiles"值为"0"。
4.隐藏上机用户登录的名字
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Winlogon下在右边的窗口中新建字符串"DontDisplayLastUserName",设值为"1"。
5.预防Acid Battery v1.0木马的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下若在右边窗口中如发现了“Explorer”键值,则说明中了YAI木马,将它删除。
6.预防YAI木马的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下若在右边窗口中如发现了“Batterieanzeige”键值,则说明中了YAI木马,将它删除。
7.预防Eclipse 2000木马的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下若在右边窗口中如发现了“bybt”键值,则将它删除。
然后在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下删除右边的键值“cksys”,重新启动电脑。
8.预防BO2000的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下若在右边窗口中如发现了“umgr32.exe”键值,则说明中了BO2000,将它删除。
9.预防爱虫的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下若在右边窗口中如发现了“MSKernel32”键值,就将它删除。
10.禁止出现IE菜单中“工具”栏里“interner选项”
把c:\windows\system下的名为inetcpl.cpl更名为inetcpl.old或则别的名字后就会出现禁止使用的情况把名字再换回来,就可以恢复使用。
11.预防BackDoor的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下若在右边窗口中如发现了“Notepad”键值,就将它删除。
12.预防WinNuke的破坏
在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxDMSTCP下在右边的窗口中新建或修改字符串“BSDUrgent”,设其值为0。
13.预防KeyboardGhost的破坏
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices下如发现KG.EXE这一键值,就将它删除,并查找KG.exe文件和kg.dat文件,将它们都删除。
14.查找NetSpy黑客程序
在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下,在右边的窗口中寻找键"NetSpy",如果存在,就说明已经装有NetSpy黑客程序,把它删除。
posted @
2007-10-03 10:00 jadmin 阅读(42) |
评论 (0) |
编辑 收藏
package com.zh.util;
import com.zh.conpool.Condata;
import java.sql.ResultSet;
import java.sql.SQLException;
public class page
{
ResultSet rs;
ResultSet rst;
private int intCountTopic;
public int intPageSize;
public int intPageCount;
public int intPage;
private String Countsql;
private String Pagisql;
private String str;
private String str_where;
private String str_parameter;
private String nowPage;
private String HttpFile;
Condata db;
public page()
{
rs = null;
rst = null;
intCountTopic = 0;
intPage = 0;
Countsql = null;
Pagisql = null;
str = null;
str_where = null;
str_parameter = "";
db = new Condata();
}
public static void main(String args[])
{
}
public void setPages(int i)
{
intPageSize = i;
}
public String getPagisql()
{
return Pagisql;
}
public ResultSet setQuerysql(String s, String s1, String s2, String s3)
throws SQLException
{
ResultSet resultset = null;
nowPage = s3;
HttpFile = s2;
Countsql = "select count(*) from " + s + " " + s1;
Pagisql = "select * from " + s + " " + s1 + " order by id desc";
try
{
Condata _tmp = db;
Condata.getConnection();
}
catch(Exception exception)
{
exception.getMessage();
}
try
{
resultset = querySql(Countsql, Pagisql);
}
catch(SQLException sqlexception)
{
sqlexception.getMessage();
}
return resultset;
}
public ResultSet querySql(String s, String s1)
throws SQLException
{
try
{
Condata condata = db;
Condata.getConnection();
}
catch(Exception exception) { }
if(nowPage == null)
{
intPage = 1;
} else
{
intPage = Integer.parseInt(nowPage);
if(intPage < 1)
intPage = 1;
}
rs = db.executeQuery(s);
if(rs.next())
intCountTopic = rs.getInt(1);
intPageCount = intCountTopic % intPageSize == 0 ? intCountTopic / intPageSize : intCountTopic / intPageSize + 1;
if(intPage > intPageCount)
intPage = intPageCount;
rs.close();
rst = db.executeQuery(s1);
return rst;
}
public int getCountTopic()
{
return intCountTopic;
}
public int getPageCount()
{
return intPageCount;
}
public int getIntPage()
{
return intPage;
}
public String PageFooter()
{
String s = "<form action=" + HttpFile + " name=form1 methord=post>";
int i = intPage - 1;
int j = intPage + 1;
int k = (intPageSize * getIntPage() + 1) - intPageSize;
if(k < 0)
k = 0;
s = s + "<font style='font-size: 9pt'>\u603B\u8BA1<font color='red'>" + getCountTopic() + "</font>\u6761\u8BB0\u5F55," + "\u3010\u5171<font color='red'>" + getPageCount() + "</font>\u9875\u3011";
s = s + "\u3010" + intPageSize + "\u6761/\u9875\u3011 \u5F53\u524D\u7B2C<font color='red'>" + getIntPage() + "</font>\u9875(\u5217\u51FA\u7B2C" + k + "\u5230\u7B2C" + getIntPage() * intPageSize + "\u6761) ";
if(intPage > 1)
s = s + " <A href=" + HttpFile + "?pages=1" + str_parameter + ">\u9996\u9875</A> ";
else
s = s + " \u9996\u9875 ";
if(intPage > 1)
s = s + " <A href=" + HttpFile + "?pages=" + i + str_parameter + ">\u4E0A\u4E00\u9875</A> ";
else
s = s + " \u4E0A\u4E00\u9875 ";
if(intPage < intPageCount)
s = s + " <A href=" + HttpFile + "?pages=" + j + str_parameter + ">\u4E0B\u4E00\u9875</A> ";
else
s = s + " \u4E0B\u4E00\u9875 ";
if(intPageCount > 1 && intPage != intPageCount)
s = s + " <A href=" + HttpFile + "?pages=" + intPageCount + str_parameter + ">\u5C3E\u9875</A>";
else
s = s + " \u5C3E\u9875</font>";
s = s + "</form>";
return s;
}
public void closeConn()
{
db.close();
}
}
posted @
2007-10-02 21:32 jadmin 阅读(60) |
评论 (0) |
编辑 收藏
============================JSP数据分页显示代码(完整、高效)============================
<%@ page language="java" import="java.util.*,java.sql.*" %>
<%@ page contentType="text/html;charset=gb2312" %>
<jsp:useBean id="cn" scope="page" class="DBConnection.Conn" />
<%
//变量声明
int intpagesize; //一页显示的记录数
int introwcount; //记录总数
int intpagecount; //总页数
int intpage; //待显示页码
//设置一页显示的记录数
intpagesize = 20;
//设置当前网页文件名
string strpageurl="show.jsp";
//取得待显示页码
string strpage = request.getparameter("page");
if(strpage==null){
intpage = 1;
}
else{
//将字符串转换成整型
intpage = java.lang.integer.parseint(strpage);
if(intpage<1) intpage = 1;
}
//获取记录总数
ResultSet rsc=cn.rsexecuteQuery("Select count(id) as AllRecord from tablename");
introwcount=rsc.getInt("AllRecord");
rsc.close();
//记算总页数
intpagecount = (introwcount+intpagesize-1) / intpagesize;
if(intpage>intpagecount) intpage = intpagecount;
//取得记录集
ResultSet rs=cn.rsexecuteQuery("select top "+intpagesize+" * from tablename where id not in (select top "+((intpage-1)
*intpagesize)+" id from tablename order by id desc) order by id desc");
while(rs.next) {
%>
********这里写循环体*******
<%
}
//关闭结果集
rs.close();
%>
<%-- 下面为页码输出代码段 --%>
共<%=intpagecount%>页 当前页< %=intpage%>/<%=intpagecount%>
<%if(intpage>1){%><a href="<%=strpageurl%>&page=1">首页</a><%}%> <a href="<%=strpageurl%>&page=<%=intpage-
1%>">上一页</a>
<%if(intpage<intpagecount){%><a href="<%=strpageurl%>&page=<%=intpage+1%>">下一页</a> <a href="<%=strpageurl%
>&page=<%=intpagecount%>">末页</a><%}%>
============================jsp的分页显示代码============================
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page language="java" import="java.sql.*" %>
<script language="javascript">
function newwin(url) {
var
newwin=window.open(url,"newwin","toolbar=no,location=no,directories=no,status=no,
menubar=no,scrollbars=yes,resizable=yes,width=600,height=450");
newwin.focus();
return false;
}
</script>
<script LANGUAGE="javascript">
function submit10()
{
self.location.replace("fenye1.jsp")
}
</script>
<%//变量声明
java.sql.Connection sqlCon; //数据库连接对象
java.sql.Statement sqlStmt; //SQL语句对象
java.sql.ResultSet sqlRst; //结果集对象
java.lang.String strCon; //数据库连接字符串
java.lang.String strSQL; //SQL语句
int intPageSize; //一页显示的记录数
int intRowCount; //记录总数
int intPageCount; //总页数
int intPage; //待显示页码
java.lang.String strPage;
int i;
//设置一页显示的记录数
intPageSize = 4;
//取得待显示页码
strPage = request.getParameter("page");
if(strPage==null){//表明在QueryString中没有page这一个参数,此时显示第一页数据
intPage = 1;
}
else{//将字符串转换成整型
intPage = java.lang.Integer.parseInt(strPage);
if(intPage<1) intPage = 1;
}
//装载JDBC驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//设置数据库连接字符串
strCon = "jdbc:odbc:heyang";
//连接数据库
sqlCon = java.sql.DriverManager.getConnection(strCon,"sa","");
//创建一个可以滚动的只读的SQL语句对象
sqlStmt =
sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.Result
Set.CONCUR_READ_ONLY);//准备SQL语句
strSQL = "select user_id,user_name from userinfo order by user_id desc";
//执行SQL语句并获取结果集
sqlRst = sqlStmt.executeQuery(strSQL);
//获取记录总数
sqlRst.last();//??光标在最后一行
intRowCount = sqlRst.getRow();//获得当前行号
//记算总页数
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//调整待显示的页码
if(intPage>intPageCount) intPage = intPageCount;
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>会员管理</title>
</head>
<body>
<form method="POST" action="fenye1.jsp">
第<%=intPage%>页 共<%=intPageCount%>页
<%if(intPage<intPageCount){%><a
href="fenye1.jsp?page=<%=intPage+1%>">下一页
</a><%}%> <%if(intPage>1){%><a href="fenye1.jsp?page=<%=intPage-1%>">
上一页</a><%}%>
转到第:<input type="text" name="page" size="8"> 页
<span><input class=buttonface type=´submit´ value=´GO´ name=´cndok´></span>
</form>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<th>ID</th>
<th>用户名</th>
<th width=´8%´>删除</th>
</tr>
<%
if(intPageCount>0){
//将记录指针定位到待显示页的第一条记录上
sqlRst.absolute((intPage-1) * intPageSize + 1);
//显示数据
i = 0;
String user_id,user_name;
while(i<intPageSize && !sqlRst.isAfterLast()){
user_id=sqlRst.getString(1);
user_name=sqlRst.getString(2);
%>
<tr>
<td><%=user_id%></td>
<td><%=user_name%></td>
<td width=´8%´ align=´center´><a href="delete.jsp?user_id=<%=user_id%>"
onClick="return newwin(this.href);">删除</a></td>
</tr>
<%
sqlRst.next();
i++;
}
}
%>
</table>
</body>
</html>
<%
//关闭结果集
sqlRst.close();
//关闭SQL语句对象
sqlStmt.close();
//关闭数据库
sqlCon.close();
%>
posted @
2007-10-02 20:49 jadmin 阅读(60) |
评论 (0) |
编辑 收藏
前言
在使用数据库的过程中,不可避免的需要使用到分页的功能,可是JDBC的规范对此却没有很好的解决。对于这个需求很多朋友都有自己的解决方案,比如使用Vector等集合类先保存取出的数据再分页。但这种方法的可用性很差,与JDBC本身的接口完全不同,对不同类型的字段的支持也不好。这里提供了一种与JDBC兼容性非常好的方案。
JDBC和分页
Sun的JDBC规范的制定,有时很让人哭笑不得,在JDBC1.0中,对于一个结果集(ResultSet)你甚至只能执行next()操作,而无法让其向后滚动,这就直接导致在只执行一次SQL查询的情况下无法获得结果集的大小。所以,如果你使用的是JDBC1.0的驱动,那么是几乎无法实现分页的。
好在Sun的JDBC2规范中很好的弥补了这一个不足,增加了结果集的前后滚动操作,虽然仍然不能直接支持分页,但我们已经可以在这个基础上写出自己的可支持分页的ResultSet了。
和具体数据库相关的实现方法
有一些数据库,如Mysql, Oracle等有自己的分页方法,比如Mysql可以使用limit子句,Oracle可以使用ROWNUM来限制结果集的大小和起始位置。这里以Mysql为例,其典型代码如下:
// 计算总的记录条数
String SQL = "SELECT Count(*) AS total " + this.QueryPart;
rs = db.executeQuery(SQL);
if (rs.next())
Total = rs.getInt(1);
// 设置当前页数和总页数
TPages = (int)Math.ceil((double)this.Total/this.MaxLine);
CPages = (int)Math.floor((double)Offset/this.MaxLine+1);
// 根据条件判断,取出所需记录
if (Total > 0) {
SQL = Query + " LIMIT " + Offset + " , " + MaxLine;
rs = db.executeQuery(SQL);
}
return rs;
}
毫无疑问,这段代码在数据库是Mysql时将会是漂亮的,但是作为一个通用的类(事实上我后面要提供的就是一个通用类库中的一部分),需要适应不同的数据库,而基于这个类(库)的应用,也可能使用不同的数据库,所以,我们将不使用这种方法。
另一种繁琐的实现方法
我看过一些人的做法(事实上包括我在内,一开始也是使用这种方法的),即不使用任何封装,在需要分页的地方,直接操作ResultSet滚到相应的位置,再读取相应数量的记录。其典型代码如下:
<%
sqlStmt = sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
java.sql.ResultSet.CONCUR_READ_ONLY);
strSQL = "select name,age from test";
//执行SQL语句并获取结果集
sqlRst = sqlStmt.executeQuery(strSQL);
//获取记录总数
sqlRst.last();
intRowCount = sqlRst.getRow();
//记算总页数
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//调整待显示的页码
if(intPage>intPageCount) intPage = intPageCount;
%>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<%
if(intPageCount>0){
//将记录指针定位到待显示页的第一条记录上
sqlRst.absolute((intPage-1) * intPageSize + 1);
//显示数据
i = 0;
while(i<intPageSize && !sqlRst.isAfterLast()){
%>
<tr>
<td><%=sqlRst.getString(1)%></td>
<td><%=sqlRst.getString(2)%></td>
</tr>
<%
sqlRst.next();
i++;
}
}
%>
</table>
很显然,这种方法没有考虑到代码重用的问题,不仅代码数量巨大,而且在代码需要修改的情况下,将会无所适从。
使用Vector进行分页
还见过另一些实现分页的类,是先将所有记录都select出来,然后将ResultSet中的数据都get出来,存入Vector等集合类中,再根据所需分页的大小,页数,定位到相应的位置,读取数据。或者先使用前面提到的两种分页方法,取得所需的页面之后,再存入Vector中。
扔开代码的效率不说,单是从程序结构和使用的方便性上讲,就是很糟糕的。比如,这种做法支持的字段类型有限,int, double, String类型还比较好处理,如果碰到Blob, Text等类型,实现起来就很麻烦了。这是一种更不可取的方案。
一个新的Pageable接口及其实现
很显然,看过上面三种实现方法后,我们对新的分页机制有了一个目标,即:不与具体数据库相关;尽可能做到代码重用;尽可能与原JDBC接口的使用方法保持一致;尽可能高的效率。
首先,我们需要提供一个与java.sql.ResultSet向下兼容的接口,把它命名为Pageable,接口定义如下:
public interface Pageable extends java.sql.ResultSet{
/**返回总页数
*/
int getPageCount();
/**返回当前页的记录条数
*/
int getPageRowsCount();
/**返回分页大小
*/
int getPageSize();
/**转到指定页
*/
void gotoPage(int page) ;
/**设置分页大小
*/
void setPageSize(int pageSize);
/**返回总记录行数
*/
int getRowsCount();
/**
* 转到当前页的第一条记录
* @exception java.sql.SQLException 异常说明。
*/
void pageFirst() throws java.sql.SQLException;
/**
* 转到当前页的最后一条记录
* @exception java.sql.SQLException 异常说明。
*/
void pageLast() throws java.sql.SQLException;
/**返回当前页号
*/
int getCurPage();
}
这是一个对java.sql.ResultSet进行了扩展的接口,主要是增加了对分页的支持,如设置分页大小,跳转到某一页,返回总页数等等。
接着,我们需要实现这个接口,由于这个接口继承自ResultSet,并且它的大部分功能也都和ResultSet原有功能相同,所以这里使用了一个简单的Decorator模式。
PageableResultSet2的类声明和成员声明如下:
public class PageableResultSet2 implements Pageable {
protected java.sql.ResultSet rs=null;
protected int rowsCount;
protected int pageSize;
protected int curPage;
protected String command = "";
}
可以看到,在PageableResultSet2中,包含了一个ResultSet的实例(这个实例只是实现了ResultSet接口,事实上它是由各个数据库厂商分别实现的),并且把所有由ResultSet继承来的方法都直接转发给该实例来处理。
PageableResultSet2中继承自ResultSet的主要方法:
//……
public boolean next() throws SQLException {
return rs.next();
}
//……
public String getString(String columnName) throws SQLException {
try {
return rs.getString(columnName);
}
catch (SQLException e) {//这里是为了增加一些出错信息的内容便于调试
throw new SQLException (e.toString()+" columnName="
+columnName+" SQL="+this.getCommand());
}
}
//……
只有在Pageable接口中新增的方法才需要自己的写方法处理。
/**方法注释可参考Pageable.java
*/
public int getCurPage() {
return curPage;
}
public int getPageCount() {
if(rowsCount==0) return 0;
if(pageSize==0) return 1;
//calculate PageCount
double tmpD=(double)rowsCount/pageSize;
int tmpI=(int)tmpD;
if(tmpD>tmpI) tmpI++;
return tmpI;
}
public int getPageRowsCount() {
if(pageSize==0) return rowsCount;
if(getRowsCount()==0) return 0;
if(curPage!=getPageCount()) return pageSize;
return rowsCount-(getPageCount()-1)*pageSize;
}
public int getPageSize() {
return pageSize;
}
public int getRowsCount() {
return rowsCount;
}
public void gotoPage(int page) {
if (rs == null)
return;
if (page < 1)
page = 1;
if (page > getPageCount())
page = getPageCount();
int row = (page - 1) * pageSize + 1;
try {
rs.absolute(row);
curPage = page;
}
catch (java.sql.SQLException e) {
}
}
public void pageFirst() throws java.sql.SQLException {
int row=(curPage-1)*pageSize+1;
rs.absolute(row);
}
public void pageLast() throws java.sql.SQLException {
int row=(curPage-1)*pageSize+getPageRowsCount();
rs.absolute(row);
}
public void setPageSize(int pageSize) {
if(pageSize>=0){
this.pageSize=pageSize;
curPage=1;
}
}
PageableResultSet2的构造方法:
public PageableResultSet2(java.sql.ResultSet rs) throws java.sql.SQLException {
if(rs==null) throw new SQLException("given ResultSet is NULL","user");
rs.last();
rowsCount=rs.getRow();
rs.beforeFirst();
this.rs=rs;
}
这里只是简单的取得一个总记录数,并将记录游标移回初始位置(before first),同时将参数中的ResultSet赋给成员变量。
Pageable的使用方法
因为Pageable接口继承自ResultSet,所以在使用方法上与ResultSet一致,尤其是在不需要分页功能的时候,可以直接当成ResultSet使用。而在需要分页时,只需要简单的setPageSize, gotoPage,即可。
PreparedStatement pstmt=null;
Pageable rs=null;
……//构造SQL,并准备一个pstmt.
rs=new PageableResultSet2(pstmt.executeQuery());//构造一个Pageable
rs.setPageSize(20);//每页20个记录
rs.gotoPage(2);//跳转到第2页
for(int i=0; i<rs.getPageRowsCount(); i++){//循环处理
int id=rs.getInt(“ID”);
……//继续处理
}
总结
一个好的基础类应该是便于使用,并且具备足够的可移植性,同时要保证其功能的完善。在上面的实现中,我们从java.sql.ResultSet接口继承出Pageable,并实现了它。这就保证了在使用中与JDBC原有操作的一致性,同时对原有功能没有缩减。
同时它也是易于使用的,因为封装了一切必要的操作,所以在你的代码中唯一显得"难看"和"不舒服"的地方就是需要自己去构造一个PageableResultSet2。不过只要你愿意,这也是可以解决的。
当然它也有具有充分的可移植性,当你将数据库由Oracle变为Mysql或者SQLServer的时候,你仍然可以使用这些分页的代码。它在使用中(或者说在移植的过程中)唯一的限制就是你必须要使用一个支持JDBC2的驱动(现在明白为什么我把类命名为PageableResultSet2了吧。:P),不过,好在JDBC2已经成为标准了,绝大多数的数据库(如Oracle, Mysql, SQLServer)都有自己的或者第三方提供的JDBC2的驱动。
OK,这个分页的实现是否对你的编程有帮助呢?仔细看看,其实真正自己写的代码并不多的,大部分都只是简单的转发操作。一个合适的模式应用可以帮你很大忙。
posted @
2007-10-02 20:37 jadmin 阅读(48) |
评论 (0) |
编辑 收藏
1、不说“不可能”三个字;
2、凡事第一反应:找方法,而不是找借口;
3、遇到挫折对自己大声说:太棒了;
4、不说消极的话,不落入消极情绪,一旦出现立即正面处理;
5、凡事先订立目标,并且尽量制作“梦想版”;
6、凡事预先作计划,尽量前目标视觉化;
7、六点优先工作制,每一分,每一秒做生产力的事情;
8、随时用零碎的时间(如等人、排队等)做零碎的小活;
9、守时;
10、写下来,不要太依靠脑袋记忆;
11、随时记录灵感;
12、把重要的观念、方法写下来,并贴起来,以随时提示自己;
13、走路比平时快30%。走路时,脚尖稍用力推进;肢体语言健康有力,不懒散;
14、每天出门照镜子,给自己一个自信的笑容;
15、每天自我反省一次;
16、每天坚持一次运动;
17、听心跳1分钟。指在做重要事前,疲劳时,心情烦燥时,紧张时;
18、开会坐在前排;
19、微笑;
20、用心倾听,不打断对方说话;
21、说话时,声音有力。感觉自己声音似乎能产生有感染力的磁场;
22、同理心。说话之前,先考虑一下对方的感觉;
23、每天有意识、真诚地赞美别人三次以上;
24、及时写感谢卡,哪怕是用便条写;
25、不用训斥、指责的口吻跟别人说话;
26、控制住不要让自己做出为自己辩护的第一反应;
27、每天多做一件“分外事”
28、不管任何方面,每天必须至少做一次“进步一点点”;
29、每天提前15分钟上班,推迟30分钟下班;
30、每天在下班前5分钟的时间做一天的整理性工作;
31、定期存钱;
32、节俭;
33,当你有创意的时候用笔记下来,并努力去实现它。
posted @
2007-10-02 08:55 jadmin 阅读(53) |
评论 (0) |
编辑 收藏
【放弃】把握的反面就是放弃,选择了一个机会,就等于放弃了其他所有的可能。当新的机会摆在面前的时候,敢于放弃已经获得的一切,这不是功亏一篑,这不是半途而废,这是为了谋求更大的发展空间;或者什么都不为,只因为喜欢这样做,因为,年轻就是最大的机会。人,只有在三十岁之前才会有这个胆量,有这个资本,有这个资格。
【失恋】不是不在乎,是在乎不起。三十岁前最怕失去的不是已经拥有的东西,而是梦想。爱情如果只是一个过程,那么正是这个年龄应当经历的,如果要承但结果,三十岁以后,可能会更有能力,更有资格。其实,三十岁之前我们要做的事情很多,稍纵即逝,过久地沉溺在已经干涸的爱河的河床中,与这个年龄的生命节奏不合。
【离婚】不是不在乎,是一切还来得及。一位三十八岁的女友与老公结婚十五年,冷战十三年,终于分手。她说:“如果说后来不愿意离婚是为了孩子,那第他第一次提出离婚我没有同意,现在想来真不知道为什么。如果那个时候早分手,我的生活绝不会是今天这个样子。现在再重新开始,总觉得一切都晚了。”
【漂泊】漂泊不是一种不幸,而是一种资格。趁着没有家室拖累,趁着身体健康,此时不飘何时飘?当然,漂泊的不一定是身体,也许只是幻想和梦境。新世纪的时尚领袖是飘一代,渴望漂泊的人惟一不飘的是那颗心。
【失业】三十岁以前就尝到失业的滋味当然是一件不幸的事,但不一定是坏事。三十岁之前就过早地固定在一个职业上终此一生也许才是最大的不幸。失业也许让你想起埋藏很久而尘封的梦想,也许会唤醒连你自己都从未知道的潜能。也许你本来就没什么梦想,这时候也会逼着你去做梦。
【时尚】不要追赶时尚。按说青年人应该是最时尚的,但是独立思考和个性生活更重要。在这个物质社会,其实对时尚的追求早已经成为对金钱的追求。今天,时尚是物欲和世俗的同义语。
【格调】这是小资的东西,"小资"这个词在今天又二度流行,追求格调就是他们的专利。小资们说,有格调要满足四大要件:智慧、素养、自信和金钱。格调就是把"高尚"理解成穿着、气质、爱好的品位和室内装潢。也就是大老粗只会表现谈吐的庸俗,"小资"们已经有能力庸俗他们的心灵了。主流观念倒不是非要另类,另类已经成为年轻人观念的主流了,在今天,老土倒显得另类。关键是当今社会是一个创造观念的时代,而不是一个固守陈旧观念的时代。
【评价】我们最不应该做出的牺牲就是因为别人的评价而改变自我,因为那些对你指手画脚的人自己也不知道他们遵从的规则是什么。千万不要只遵从规矩做事,规矩还在创造之中,要根据自己的判断做每一件事,虽然这样会麻烦一点。
【幼稚】不要怕人说我们幼稚,这正说明你还年轻,还充满活力。"成熟"是个吓人的词儿,也是个害人的词儿。成熟和幼稚是对一个人最大而无当、最不负责任、最没用的概括。那些庸人,绝不会有人说他们幼稚。不信,到哪天你被生活压得老气横秋,暮气沉沉的时候,人们一定会说你成熟了,你就会知道"成熟"是个什么东西。
【不适应】在一首摇滚里有这么一句:"这个城市改变了我,这个城市不需要我。"不要盲目地适应你生存的环境,因为很可能这环境自身已经不适应这个社会的发展了。
【失败】我的老师曾经跟我说,一个人起码要在感情上失恋一次,在事业上失败一次,在选择上失误一次,才能长大。不要说失败是成功之母那样的老话,失败来得越早越好,要是三十岁,四十岁之后再经历失败,有些事,很可能就来不及了。
【错误】这是年轻人的专利。
【浅薄】如果每看一次《泰坦尼克号》就流一次眼泪,每看一次《大话西游》就笑得直不起腰,就会有人笑你浅薄。其实那只能说明你的神经依旧非常敏锐,对哪怕非常微弱的刺激都会迅速做出适应的反应;等你的感觉迟钝了,人们就会说你深沉了。
【明星】不是不必在乎,是不能在乎。明星在商品社会是一种消费品,花了钱,听了歌,看了电影,明星们的表现再好,不过是物超所值而己,也不值得崇拜呀?就像你在地摊上花五十块钱买的裙子,别人都猜是八百块钱买的,物超所值了吧?你就崇拜上这身裙子了?
【代价】不是不计代价,而是要明白做任何事都要付出代价。对我们这个年龄的人来说,这绝不是一句废话。否则,要到三十岁的时候才会明白自己曾经付出了多少代价,却不明白为什么付出,更不明白自己得到了多少,得到什么。
【孤独】这是为自由付出的代价。
【失意】包括感情上的,事业上的,也许仅仅是今天花了冤枉钱没买到可心的东西,朋友家高朋满座自己却插不上一句话。过分在乎失意的感受不是拿命运的捉弄来捉弄自己,就是拿别人的错误来惩罚自己。
【缺陷】也许你个子矮,也许你长得不好看,也许你的嗓音像唐老鸭……那么你的优势就是你不会被自己表面的浅薄的亮点所耽搁,少花一些时间,少走一些弯,直接发现你内在的优势,直接挖掘自己深层的潜能。
【误会】如果出于恶意,那么解释也没有用;如果出于善意,就不需要解释。专门说到"误会"倒不是为一个人在三十岁之前被人误会的时候更多,而是这个年龄的人想不开的时候更多。
【谣言】这是一种传染病,沉默是最好的疫苗。除非你能找出传染源,否则解释恰恰会成为病毒传播最理想的条件。
【疯狂】这是年轻人最好的心理调适,只能说明你精力旺盛,身心健康。说你"疯狂"是某些生活压抑、心力交瘁的中老年人恶意的评价,他们就像一部年久修的机器,最需要调试,但只能微调,一次大修就会让他们完全报废。
【稳定】三十岁之前就在乎稳定的生活,那只有两种可能,要么就是中了彩票,要么就是未老先衰。
【压力】中年人能够承受多大压力检验的是他的韧性;年轻人能承受多大压力,焕发的是他的潜能。
【出国】也许是个机会,也许是个陷阱。除非从考大学的那一刻你就抱着这个目标,否则,对待出国的态度应该像对待爱情一样,努力争取成败随缘。
【薪水】只要是给人打工,薪水再高也高不到哪儿去。所以在三十岁之前,机会远比金钱重要,事业远比金钱重要,将来远比金钱重要。对大多数人来说,三十岁之前干事业的首要目标绝不是挣钱,而是挣未来。
【存款】这倒不一定是因为我们钱少,年轻人现在谁都知道钱是有生命的。机会这么多,条件这么好,可以拿钱去按揭,做今天的事,花明天的钱;也可以拿钱去投资,拿钱去"充电"。钱只有在它流通的过程中才是钱,否则只是一沓世界上质量最好的废纸。
【房子】除非你买房子是为了升值,要么就是你结婚了。我有个同学,家在外地,大学毕业之后,单位没有宿舍,家里就给他买了一套房子。他曾经有过去北京工作的机会,但是他觉得刚买了房子就离开这座城市说不过去,就放弃了。到现在他工作稳定,但一事无成。唯一的成就就是结婚了,并且有了孩子,因为他觉得该让这房子永远空着,所以房子变成了家。房子是都市生活的寓言,这个寓言不应该过早的和我们相关。
【年龄】女孩子一过二十五就开始隐瞒自己的年龄,其实大可不必。现在青年期都延迟到四十五岁了,二十五又算得了什么呢?
【在乎】这是一种拿不起、放不下的心态,它的反面不是放弃,而是天马行空,自由自在,永远保持革命乐观主义的精神。
posted @
2007-10-02 08:51 jadmin 阅读(54) |
评论 (0) |
编辑 收藏
在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题。一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java语言默认的编码方式是UNICODE,而我们中国人通常使用的文件和数据库都是基于GB2312或者BIG5等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合Java编程实例,分析以上两个问题并提出解决它们的方案。
现在 Java 编程语言已经广泛应用于互联网世界,早在 Sun 公司开发 Java 语言的时候,就已经考虑到对非英文字符的支持了。Sun 公司公布的 Java 运行环境(JRE)本身就分英文版和国际版,但只有国际版才支持非英文字符。不过在 Java 编程语言的应用中,对中文字符的支持并非如同 Java Soft 的标准规范中所宣称的那样完美,因为中文字符集不只一个,而且不同的操作系统对中文字符的支持也不尽相同,所以会有许多和汉字编码处理有关的问题在我们进行应用开发中困扰着我们。有很多关于这些问题的解答,但都比较琐碎,并不能够满足大家迫切解决问题的愿望,关于 Java 中文问题的系统研究并不多,本文从汉字编码常识出发,分析 Java 中文问题,希望对大家解决这个问题有所帮助。
汉字编码的常识
我们知道,英文字符一般是以一个字节来表示的,最常用的编码方法是 ASCII 。但一个字节最多只能区分256个字符,而汉字成千上万,所以现在都以双字节来表示汉字,为了能够与英文字符分开,每个字节的最高位一定为1,这样双字节最多可以表示64K格字符。我们经常碰到的编码方式有 GB2312、BIG5、UNICODE 等。关于具体编码方式的详细资料,有兴趣的读者可以查阅相关资料。我肤浅谈一下和我们关系密切的 GB2312 和 UNICODE。GB2312 码,中华人民共和国国家标准汉字信息交换用编码,是一个由中华人民共和国国家标准总局发布的关于简化汉字的编码,通行于中国大陆地区及新加坡,简称国标码。两个字节中,第一个字节(高字节)的值为区号值加32(20H),第二个字节(低字节)的值为位号值加32(20H),用这两个值来表示一个汉字的编码。UNICODE 码是微软提出的解决多国字符问题的多字节等长编码,它对英文字符采取前面加“0”字节的策略实现等长兼容。如 “A” 的 ASCII 码为0x41,UNICODE 就为0x00,0x41。利用特殊的工具各种编码之间可以互相转换。
Java 中文问题的初步认识
我们基于 Java 编程语言进行应用开发时,不可避免地要处理中文。Java 编程语言默认的编码方式是 UNICODE,而我们通常使用的数据库及文件都是基于 GB2312 编码的,我们经常碰到这样的情况:浏览基于 JSP 技术的网站看到的是乱码,文件打开后看到的也是乱码,被 Java 修改过的数据库的内容在别的场合应用时无法继续正确地提供信息。
String sEnglish = “apple”;
String sChinese = “苹果”;
String s = “苹果 apple ”;
sEnglish 的长度是5,sChinese的长度是4,而 s 默认的长度是14。对于 sEnglish来说, Java 中的各个类都支持得非常好,肯定能够正确显示。但对于 sChinese 和 s 来说,虽然 Java Soft 声明 Java 的基本类已经考虑到对多国字符的支持(默认 UNICODE 编码),但是如果操作系统的默认编码不是 UNICODE ,而是国标码等。从 Java 源代码到得到正确的结果,要经过 “Java 源代码-> Java 字节码-> ; 虚拟机->操作系统->显示设备”的过程。在上述过程中的每一步骤,我们都必须正确地处理汉字的编码,才能够使最终的显示结果正确。
“ Java 源代码-> Java 字节码”,标准的 Java 编译器 javac 使用的字符集是系统默认的字符集,比如在中文 Windows 操作系统上就是 GBK ,而在 Linux 操作系统上就是ISO-8859-1,所以大家会发现在 Linux 操作系统上编译的类中源文件中的中文字符都出了问题,解决的办法就是在编译的时候添加 encoding 参数,这样才能够与平台无关。用法是
javac ?Cencoding GBK。
“ Java 字节码->虚拟机->操作系统”, Java 运行环境 (JRE) 分英文版和国际版,但只有国际版才支持非英文字符。 Java 开发工具包 (JDK) 肯定支持多国字符,但并非所有的计算机用户都安装了 JDK 。很多操作系统及应用软件为了能够更好的支持 Java ,都内嵌了 JRE 的国际版本,为自己支持多国字符提供了方便。
“操作系统->显示设备”,对于汉字来说,操作系统必须支持并能够显示它。英文操作系统如果不搭配特殊的应用软件的话,是肯定不能够显示中文的。
还有一个问题,就是在 Java 编程过程中,对中文字符进行正确的编码转换。例如,向网页输出中文字符串的时候,不论你是用
out.println(string);
还是用<%=string%>,都必须作 UNICODE 到 GBK 的转换,或者手动,或者自动。在 JSP 1.0中,可以定义输出字符集,从而实现内码的自动转换。用法是
<%@page contentType=”text/html; charset=gb2312” %>
但是在一些 JSP 版本中并没有提供对输出字符集的支持,(例如 JSP 0.92),这就需要手动编码输出了,方法非常多。最常用的方法是
String s1 = request.getParameter(“keyword”);
String s2 = new String(s1.getBytes(“ISO-8859-1”),”GBK”);
getBytes 方法用于将中文字符以“ISO-8859-1”编码方式转化成字节数组,而“GBK” 是目标编码方式。我们从以ISO-8859-1方式编码的数据库中读出中文字符串 s1 ,经过上述转换过程,在支持 GBK 字符集的操作系统和应用软件中就能够正确显示中文字符串 s2 。
Java 中文问题的表层分析及处理
背景
开发环境 JDK1.15 Vcafe2.0 JPadPro
服务器端 NT IIS Sybase System Jconnect(JDBC)
客户端 IE5.0 Pwin98
.CLASS 文件存放在服务器端,由客户端的浏览器运行 APPLET , APPLET 只起调入 FRAME 类等主程序的作用。界面包括 Textfield ,TextArea,List,Choice 等。
I.用 JDBC 执行 SELECT 语句从服务器端读取数据(中文)后,将数据用 APPEND 方法加到 TextArea(TA) ,不能正确显示。但加到 List 中时,大部分汉字却可正确显示。
将数据按“ISO-8859-1” 编码方式转化为字节数组,再按系统缺省编码方式 (Default Character Encoding) 转化为 STRING ,即可在 TA 和 List 中正确显示。
程序段如下:
dbstr2 = results.getString(1);
//After reading the result from DB server,converting it to string.
dbbyte1 = dbstr2.getBytes(“iso-8859-1”);
dbstr1 = new String(dbbyte1);
在转换字符串时不采用系统默认编码方式,而直接采用“ GBK” 或者 “GB2312” ,在 A 和 B 两种情况下,从数据库取数据都没有问题。
II.处理方式与“取中文”相逆,先将 SQL 语句按系统缺省编码方式转化为字节数组,再按“ISO-8859-1”编码方式转化为 STRING ,最后送去执行,则中文信息可正确写入数据库。
程序段如下:
sqlstmt = tf_input.getText();
//Before sending statement to DB server,converting it to sql statement.
dbbyte1 = sqlstmt.getBytes();
sqlstmt = newString(dbbyte1,”iso-8859-1”);
_stmt = _con.createStatement();
_stmt.executeUpdate(sqlstmt);
……
问题:如果客户机上存在 CLASSPATH 指向 JDK 的 CLASSES.ZIP 时(称为 A 情况),上述程序代码可正确执行。但是如果客户机只有浏览器,而没有 JDK 和 CLASSPATH 时(称为 B 情况),则汉字无法正确转换。
我们的分析:
1.经过测试,在 A 情况下,程序运行时系统的缺省编码方式为 GBK 或者 GB2312 。在 B 情况下,程序启动时浏览器的 JAVA 控制台中出现如下错误信息:
Can't find resource for sun.awt.windows.awtLocalization_zh_CN
然后系统的缺省编码方式为“8859-1”。
2.如果在转换字符串时不采用系统缺省编码方式,而是直接采用 “GBK” 或“GB2312”,则在 A 情况下程序仍然可正常运行,在 B 情况下,系统出现错误:
UnsupportedEncodingException。
3.在客户机上,把 JDK 的 CLASSES.ZIP 解压后,放在另一个目录中, CLASSPATH 只包含该目录。然后一边逐步删除该目录中的 .CLASS 文件,另一边运行测试程序,最后发现在一千多个 CLASS 文件中,只有一个是必不可少的,该文件是:
sun.io.CharToByteDoubleByte.class。
将该文件拷到服务器端和其它的类放在一起,并在程序的开头 IMPORT 它,在 B 情况下程序仍然无法正常运行。
4.在 A 情况下,如果在 CLASSPTH 中去掉 sun.io.CharToByteDoubleByte.class ,则程序运行时测得默认编码方式为“8859-1”,否则为 “GBK” 或 “GB2312” 。
如果 JDK 的版本为1.2以上的话,在 B 情况下遇到的问题得到了很好的解决,测试的步骤同上,有兴趣的读者可以尝试一下。
Java 中文问题的根源分析及解决
在简体中文 MS Windows 98 + JDK 1.3 下,可以用 System.getProperties() 得到 Java 运行环境的一些基本属性,类 PoorChinese 可以帮助我们得到这些属性。
类 PoorChinese 的源代码:
public class PoorChinese {}
执行 java PoorChinese 后,我们会得到:
系统变量 file.encoding 的值为 GBK ,user.language 的值为 zh , user.region 的值为 CN ,这些系统变量的值决定了系统默认的编码方式是 GBK 。
在上述系统中,下面的代码将 GB2312 文件转换成 Big5 文件,它们能够帮助我们理解 Java 中汉字编码的转化:
import java.io.*;
import java.util.*;
public class gb2big5
{
static int iCharNum=0;
public static void main(String[] args) {
System.out.println("Input GB2312 file, output Big5 file.");
if (args.length!=2)
{
System.err.println("Usage: jview gb2big5 gbfile big5file");
System.exit(1);
String inputString = readInput(args[0]);
writeOutput(inputString,args[1]);
System.out.println("Number of Characters in file: "+iCharNum+".");
}
static void writeOutput(String str, String strOutFile)
{
try
{
FileOutputStream fos = new FileOutputStream(strOutFile);
Writer out = new OutputStreamWriter(fos, "Big5");
out.write(str);
out.close();
}
catch (IOException e)
{
e.printStackTrace();
e.printStackTrace();
}
}
static String readInput(String strInFile)
{
StringBuffer buffer = new StringBuffer();
try
{
FileInputStream fis = new FileInputStream(strInFile);
InputStreamReader isr = new InputStreamReader(fis, "GB2312");
Reader in = new BufferedReader(isr);
int ch;
while ((ch = in.read()) > -1)
{
iCharNum += 1; buffer.append((char)ch);
}
in.close();
return buffer.toString();
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
}
编码转化的过程如下:
GB2312------------------>Unicode------------->Big5
执行 java gb2big5 gb.txt big5.txt ,如果 gb.txt 的内容是“今天星期三”,则得到的文件 big5.txt 中的字符能够正确显示;而如果 gb.txt 的内容是“情人节快乐”,则得到的文件 big5.txt 中对应于“节”和“乐”的字符都是符号“?”(0x3F),可见 sun.io.ByteToCharGB2312 和 sun.io.CharToByteBig5 这两个基本类并没有编好。
正如上例一样, Java 的基本类也可能存在问题。由于国际化的工作并不是在国内完成的,所以在这些基本类发布之前,没有经过严格的测试,所以对中文字符的支持并不像 Java Soft 所声称的那样完美。前不久,我的一位技术上的朋友发信给我说,他终于找到了 Java Servlet 中文问题的根源。两周以来,他一直为 Java Servlet 的中文问题所困扰,因为每面对一个含有中文字符的字符串都必须进行强制转换才能够得到正确的结果(这好象是大家公认的唯一的解决办法)。
后来,他确实不想如此继续安分下去了,因为这样的事情确实不应该是高级程序员所要做的工作,他就找出 Servlet 解码的源代码进行分析,因为他怀疑问题就出在解码这部分。经过四个小时的奋斗,他终于找到了问题的根源所在。原来他的怀疑是正确的, Servlet 的解码部分完全没有考虑双字节,直接把 %XX 当作一个字符。(原来 Java Soft 也会犯这幺低级的错误!)
如果你对这个问题有兴趣或者遇到了同样的烦恼的话,你可以按照他的步骤 对Servlet.jar 进行修改:
找到源代码 HttpUtils 中的 static private String parseName ,在返回前将 sb(StringBuffer) 复制成 byte bs[] ,然后 return new String(bs,”GB2312”)。作上述修改后就需要自己解码了:
HashTable form=HttpUtils .parseQueryString(request.getQueryString())或者
form=HttpUtils.parsePostData(……)
千万别忘了编译后放到 Servlet.jar 里面。
关于 Java 中文问题的总结
Java 编程语言成长于网络世界,这就要求 Java 对多国字符有很好的支持。 Java 编程语言适应了计算的网络化的需求,为它能够在网络世界迅速成长奠定了坚实的基础。 Java 的缔造者 (Java Soft) 已经考虑到 Java 编程语言对多国字符的支持,只是现在的解决方案有很多缺陷在里面,需要我们付诸一些补偿性的措施。而世界标准化组织也在努力把人类所有的文字统一在一种编码之中,其中一种方案是 ISO10646 ,它用四个字节来表示一个字符。当然,在这种方案未被采用之前,还是希望 Java Soft 能够严格地测试它的产品,为用户带来更多的方便。
附一个用于从数据库和网络中取出 中文乱码的处理函数,入参是有问题的字符串,出参是问题已经解决了的字符串。
posted @
2007-10-02 08:17 jadmin 阅读(59) |
评论 (0) |
编辑 收藏