2008年8月21日 星期四

测试脚本

测试脚本

2008年8月6日 星期三

Java内部类的分析和整理

package test.jdk;

/**
* 内部类的收集与整理
*
* @author 赵学庆 www.java2000.net
*/
public class InnerTest {
private String instAtt = "实例变量";

private static String staticAtt = "静态变量";

public void test() {
int methodAtt = 1;
final int methodFinalAtt = 2;
// 非静态方法里的内部类
class staticMethodInnerClass {
@Override
public String toString() {
// 非静态方法里无法访问实例的外部变量
System.out.println("非静态方法的内部类可以访问外部类的实例变量:" + instAtt);
System.out.println("非静态方法的内部类可以访问外部类的静态变量:" + staticAtt);
// 非静态方法里无法访问方法的非final的变量
// System.out.println(methodAtt);
System.out.println("非静态方法的内部类可以访问方法的final变量:" + methodFinalAtt);
return "my nickname is white";
}
}
new staticMethodInnerClass().toString();
new Object() {
@Override
public String toString() {
System.out.println("非静态方法的匿名内部类可以访问外部类的实例变量:" + instAtt);
System.out.println("非静态方法的匿名内部类可以访问外部类的静态变量:" + staticAtt);
// 静态方法里匿名内部类无法访问方法的非final的变量
// System.out.println(methodAtt);
System.out.println("非静态方法的匿名内部类可以访问方法的final变量:" + methodFinalAtt);
return "我是匿名内部类";
}
}.toString();
}

public static void main(String blackbat[]) {
int methodAtt = 1;
final int methodFinalAtt = 2;
// 静态方法里的内部类
class staticMethodInnerClass {
@Override
public String toString() {
// 静态方法里无法访问实例的外部变量
// System.out.println(instAtt);
System.out.println("静态方法的内部类可以访问外部类的静态变量:" + staticAtt);
// 静态方法里无法访问方法的非final的变量
// System.out.println(methodAtt);
System.out.println("静态方法的内部类可以访问方法的final变量:" + methodFinalAtt);
return "my nickname is white";
}
}
new staticMethodInnerClass().toString();
new Object() {
@Override
public String toString() {
// 静态方法的匿名内部类不能访问外部类的非静态变量
// System.out.println("非静态方法的匿名内部类可以访问外部类的非静态变量:" + instAtt);
System.out.println("非静态方法的匿名内部类可以访问外部类的静态变量:" + staticAtt);
// 静态方法里匿名内部类无法访问方法的非final的变量
// System.out.println(methodAtt);
System.out.println("非静态方法的匿名内部类可以访问方法的final变量:" + methodFinalAtt);
return "我是匿名内部类";
}
}.toString();
new InnerTest().test();
// 建立静态内部类(static Inner Class)的对象
ImOutClass.StaticInnerClass staticIC = new ImOutClass.StaticInnerClass();
staticIC.access();
/*
* 建立非静态内部类(non-static Inner Class)的对象.
注意这种建立对象的格式 首先创建外部类的对象 然后使用对象.new 来创建。
*/
ImOutClass outC = new ImOutClass();
ImOutClass.InstInnerClass inC = outC.new InstInnerClass();
inC.access();
}
}

class ImOutClass {
private static String staticAtt = " 外部类的类变量 ";

private String instAtt = " 外部类的实例变量 ";

private static String xx = "外部静态变量";

// private String xx = "外部类的实例变量";
// 外部类的非静态方法
public void instanMethod() {
System.out.println(" 和外部类实例方法 ");
}

// 外部类的静态方法
public static void staticMethod() {
System.out.println(" 和外部类静态方法 ");
}

// 静态内部类(static Inner Class)
public static class StaticInnerClass {
public StaticInnerClass() {
System.out.println(" 我是静态内部类 ");
}

public void access() {
System.out.println(" 我可以访问 " + staticAtt);
staticMethod();
System.out.println(" 我可以访问外部的静态变量 " + xx);
// 非静态的方法 instanMethod() 无法从静态的地方使用
// instanMethod();
}
}

// 非静态内部类(non-static Inner Class)
public class InstInnerClass {
public InstInnerClass() {
System.out.println(" 我是成员级内部类,非静态内部类 ");
}

public void access() {
System.out.println(" 我可以访问 " + instAtt);
instanMethod();
staticMethod();
System.out.println(" 我可以访问外部的静态变量 " + xx);
}
}
}

运行结果为

静态方法的内部类可以访问外部类的静态变量:静态变量
静态方法的内部类可以访问方法的final变量:2
非静态方法的匿名内部类可以访问外部类的静态变量:静态变量
非静态方法的匿名内部类可以访问方法的final变量:2
非静态方法的内部类可以访问外部类的实例变量:实例变量
非静态方法的内部类可以访问外部类的静态变量:静态变量
非静态方法的内部类可以访问方法的final变量:2
非静态方法的匿名内部类可以访问外部类的实例变量:实例变量
非静态方法的匿名内部类可以访问外部类的静态变量:静态变量
非静态方法的匿名内部类可以访问方法的final变量:2
我是静态内部类
我可以访问 外部类的类变量
和外部类静态方法
我可以访问外部的静态变量 外部静态变量
我是成员级内部类,非静态内部类
我可以访问 外部类的实例变量
和外部类实例方法
和外部类静态方法
我可以访问外部的静态变量 外部静态变量

关于Hibernate3.2的count返回值的问题

@Override
public int countAllSubject() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
return ((Long) session.createQuery(
"select count(*) from Post where idParent=0").iterate().next())
.intValue();
}

问题关键在那个
(Long)
在我的机器上运行正常,可在一些网友的机器上运行报错
java.lang.ClassCastException: java.lang.Integer

他们修改成(Integer)则运行正常

我的机器上如果改成Integer,则会报错。

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer


经排查,最终确定:

由于我使用的是Hibernate 3.2版本,经确认,这个版本已经把以前返回 Integer的改成了 Long,
因为JPA里面的返回值规定是Long, Hibernate为了兼容这个,所以修改了返回值。

如果你从Hibernate 3.0.x/3.1.x升级到最新的3.2版,一定要注意,3.2版的很多sql函数如count(), sum()的唯一返回值已经从Integer变为Long,如果不升级代码,会得到一个ClassCastException。

这个变化主要是为了兼容JPA,可以在hibernate.org的最新文档中找到说明。

Hibernate Team也提供了一个与原来兼容的解决方案:

Configuration classicCfg = new Configuration();
classicCfg.addSqlFunction( "count", new ClassicCountFunction());
classicCfg.addSqlFunction( "avg", new ClassicAvgFunction());
classicCfg.addSqlFunction( "sum", new ClassicSumFunction());
SessionFactory classicSf = classicCfg.buildSessionFactory();

jsp:include 装载动态页面的问题

提问:
<%
String id="01";//从数据库中获取,非固定值
%>


为什么include中取不到id的值?
如何在根据id的变化,include不同的页面?

解答:
在外面把整个字符串生成了,在放到page里面,不要再page里面再次合成了。

<%
String id = "01";
String pageURL = "hello" + id;
%>


结论:
在许多标签里面,再次嵌套jsp表达式是不行的,不要再里面再次运算了。

JAVA通过Session和Cookie实现网站自动登录的技术

本方案为我这个站点当前使用的,能用,但不保证是最先进的。
原文:http://www.java2000.net/p1010

第一步,登陆的时候一旦选择了[自动登录]的选项,则需要在登陆成功后,附加下面的代码
应为一般网站都提供保存用户名的功能,所以我把这个写到了外面。只有密码是单独处理的。
其中的host就是你的域名
login.jsp
String host = request.getServerName();
Cookie cookie = new Cookie("SESSION_LOGIN_USERNAME", username); // 保存用户名到Cookie
cookie.setPath("/");
cookie.setDomain(host);
cookie.setMaxAge(99999999);
response.addCookie(cookie);
if (ParamUtils.getBooleanParameter(request, "savePassword")) {
// 保存密码到Cookie,注意需要加密一下
cookie = new Cookie("SESSION_LOGIN_PASSWORD", MD5.encode(u.getPassword()));
cookie.setPath("/");
cookie.setDomain(host);
cookie.setMaxAge(99999999);
response.addCookie(cookie);
}

这样,Cookie就生成了
第二步,在用户访问网站的时候,如果检测到没有登陆,则进行下面的判断。
index.jsp
String usernameCookie = null;
String passwordCookie = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("SESSION_LOGIN_USERNAME".equals(cookie.getName())) {
usernameCookie = cookie.getValue(); // 得到cookie的用户名
}
if ("SESSION_LOGIN_PASSWORD".equals(cookie.getName())) {
passwordCookie = cookie.getValue(); // 得到cookie的密码
}
}
if (usernameCookie != null && passwordCookie != null) { // 如果存在
if(Login.checkLogin(usernameCookie ,passwordCookie)){
// 登陆成功的处理
}else{
// 登陆不成功的处理
}
}
}

一段注册码生成程序,有剪贴板操作

import java.io.*;
import java.text.*;
import java.util.Calendar;
import java.awt.datatransfer.*;

public class T {
private void go() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("XXXclipse Cracker");
System.out.print("Please Input User ID:");
String userId = br.readLine();
if (userId.length() == 0)
return;
String serialString = getSerial(userId, "200");
System.out.println("Serial Code:" + serialString);
java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(serialString), null);
System.out
.println("Note:The serial code has succefully copied into clipboard!\nPress 'Enter' to exit...");
br.readLine();
}

public static void main(String args[]) throws Exception {
new T().go();
}

public String getSerial(String userId, String licenseNum) {
Calendar cal = Calendar.getInstance();
cal.add(1, 3);
cal.add(6, -1);
NumberFormat nf = new DecimalFormat("000");
licenseNum = nf.format(Integer.valueOf(licenseNum));
String verTime = (new StringBuilder("-")).append(
(new SimpleDateFormat("yyMMdd")).format(cal.getTime())).append("0").toString();
String type = "YE3MP-";
String need = (new StringBuilder(userId.substring(0, 1))).append(type).append("300").append(
licenseNum).append(verTime).toString();
String dx = (new StringBuilder(need))
.append(
"Decompiling this copyrighted software is a violation of both your license agreement and the Digital Millenium Copyright Act of 1998 (http://www.loc.gov/copyright/legislation/dmca.pdf). Under section 1204 of the DMCA, penalties range up to a $500,000 fine or up to five years imprisonment for a first offense. Think about it; pay for a license, avoid prosecution, and feel better about yourself.")
.append(userId).toString();
int suf = decode(dx);
String code = (new StringBuilder(need)).append(String.valueOf(suf)).toString();
return change(code);
}

private int decode(String s) {
int i = 0;
char ac[] = s.toCharArray();
int j = 0;
for (int k = ac.length; j < k; j++)
i = 31 * i + ac[j];
return Math.abs(i);
}

private String change(String s) {
byte abyte0[] = s.getBytes();
char ac[] = new char[s.length()];
int i = 0;
for (int k = abyte0.length; i < k; i++) {
int j = abyte0[i];
if (j >= 48 && j <= 57)
j = ((j - 48) + 5) % 10 + 48;
else if (j >= 65 && j <= 90)
j = ((j - 65) + 13) % 26 + 65;
else if (j >= 97 && j <= 122)
j = ((j - 97) + 13) % 26 + 97;
ac[i] = (char) j;
}
return String.valueOf(ac);
}
}

公交换乘算法(本人并未验证)

/**
* 公交换乘一站的算法思想:
* (注意:车次信息、站点信息、公交信息是等价的都是以HashMap的形式存储信息)
* 1.从数据库中获得所有公交信息存储到ArrayList,每个具体信息的元数据有三个:
* 公交车次、公交站点、该公交站点距离该公交车次的始发站点的站数,具体信息用HashMap保存
* 2.然后把公交信息数据进行结构化,把所有公交站点抽出,再把每一个站点对应的所有车次抽出
* 与其一一对应,单一的车次信息用HashMap存储,站点对应的所有车次信息用ArrayList存储,
* 所有的站点有经过站点的车次信息用HashMap存储
* 3.根据查询要求,分别从结构化以后的公交信息数据中找到,经过出发地的所有车次,经过目的地
* 的所有车次,然后在分别遍历每个车次,筛选出符合要求的中转站点,筛选规则是:每查询出一个
* 站点时,得到该站点距离该站点对应车次的始发站的站数,如果这个站数小于查询站点距离该车次的始
* 发站的站数,那么就符合规则,便把该站点信息保存到符合站点的ArrayList中,反之亦然
* 4.分别得到查询条件中出发地和目的地的中转站点信息(中转站点信息存储在ArrayList中),然
* 后遍历两个中转站点信息的集合,得到最终的具体中转信息(最终中转信息也是用ArrayList存储)
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

public class T {
private String start = null;// 出发地

private String whither = null;// 目标地

private List schedule = null;// 用于缓存列车时刻表。

private HashMap stationsOfLine = null; // 所有公交线路,每个list存储该线路经过的所有车站。

private HashMap linesOfStation = null;// 所有车站,每个list中存储通过该车站的所有车次。

// private ArrayList startLine = new ArrayList ();//
// 途经出发地的所有车次。
// private ArrayList whitherLine = new ArrayList ();//
// 途经目的地的所有车次。
private ArrayList firLineStaList = new ArrayList();

private ArrayList secLineStaList = new ArrayList();

public T(String start, String whither) {
this.start = start;
this.whither = whither;
try {
this.schedule = this.executeQuery("select busLine,up,stationNo from bus_stations");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("读取数据库出错");
e.printStackTrace();
}
stationsOfLine = this.getStationsOfLine();
linesOfStation = this.getLinesOfStation();
}

private HashMap getStationsOfLine() {
HashMap map = new HashMap();// 用于 临时存储从schedule中取出的HashMap.
ArrayList line = null;// 每个list存储一个车次的相关车站信息。
String buffer = "a";// 缓存站名。
String temp = null;// 临时存储每次迭代取出的站名,用于与buffer站名比较。
HashMap stationsGroupByLine = new HashMap();// 存储以车次分组後的车站的list
Iterator it = schedule.iterator(); // 迭代器
while (it.hasNext()) {
map = (HashMap) it.next();
temp = (String) map.get("busLine");
if (stationsGroupByLine.containsKey(temp)) {
line = stationsGroupByLine.get(temp);
buffer = (String) ((Map) line.get(0)).get("busLine");
}
if (buffer.equals(temp)) {
line.add(map);// 将同一车次的车站放入一个list中
} else {
if (line != null && !line.isEmpty()) {
stationsGroupByLine.put(buffer, line);// 将由车次分组后的车站构成的list存入一个map
}
line = new ArrayList(); // line重新引用一个新构造的list,以供存储同一车站的车次。
line.add(map);// 将同一车次的车站放入刚刚构造的空list中
}
buffer = temp;// 缓存当前操作的车次。
}
return stationsGroupByLine;
}

private HashMap getLinesOfStation() {
HashMap map = new HashMap();// 用于 临时存储从schedule中取出的HashMap.
ArrayList station = null;// 每个list存储一个经过该车站的相关车次信息。
String buffer = "a";// 缓存车次。
String temp = null;// 临时存储每次迭代取出的车次,用于与buffer车次比较。
HashMap linesGroupBystation = new HashMap();// 存储以车站分组後的车次的list
Iterator it = schedule.iterator(); // 迭代器
while (it.hasNext()) {
map = (HashMap) it.next();
temp = (String) map.get("up");
if (linesGroupBystation.containsKey(temp)) {
// station存储temp车次对应的站点信息
station = linesGroupBystation.get(temp);
// 从station中取出已经放入linesGroupBystation车站信息,缓存改车站的名字
// 与刚取出的Map中存储到车站信息进行比较
buffer = (String) ((Map) station.get(0)).get("up");
}
if (buffer.equals(temp)) {
// 如果station中几经存在该站点信息,那么,本站和station中存储到是同一站,所以
// 将同一车次的车站放入一个list中
station.add(map);
} else {
if (station != null && !station.isEmpty()) {
// 将由车次分组后的车站构成的list存入一个map
linesGroupBystation.put(buffer, station);
}
// line重新引用一个新构造的list,以供存储经过另一车站的所有车次
station = new ArrayList();
station.add(map);// 将同一车次的车站放入刚刚构造的空list中
}
buffer = temp;// 缓存当前操作的车次。
}
return linesGroupBystation;
}

/**
* 站点筛选规则:把符合规则的站点添分别放入
*
* @param startSta
* @param whitherSta
*/
private void getStationsInLine(String startSta, String whitherSta) {
// 获得经过初始站点的所有公交车次
ArrayList firTrainLine = linesOfStation.get(startSta);
// 获得经过所有目的站点的公交车次
ArrayList secTrainLine = linesOfStation.get(whitherSta);
ArrayList station;
HashMap line = null;
int transferStaNo = 0;
// String stationName = null;
String trainNo = "";
if (firTrainLine != null) {
Iterator firIt = firTrainLine.iterator();
while (firIt.hasNext()) {
// 取出一个存储车站信息HashMap
line = (HashMap) firIt.next();
// 取出车次信息
trainNo = (String) line.get("busLine");
transferStaNo = (Integer) line.get("stationNo");
// 取出车次trainNo经过的所有站点信息
station = stationsOfLine.get(trainNo);
Iterator it = station.iterator();
while (it.hasNext()) {
Map map = (Map) it.next();// trainNo's map.
int i = (Integer) map.get("stationNo");
// 筛选站点规则:如果该站点距离初始站点距离比出发站点的距离初始站点的距离大,那么就把该站点存储到
// firLineStaList,反之就做反车了,所以那些站点不必加入firLineStaList中
if (i > transferStaNo) {
//
firLineStaList.add(map);
}
}
}
}
if (secTrainLine != null) {
Iterator secIt = secTrainLine.iterator();
while (secIt.hasNext()) {
line = (HashMap) secIt.next();
trainNo = (String) line.get("busLine");
transferStaNo = (Integer) line.get("stationNo");
station = stationsOfLine.get(trainNo);
Iterator it = station.iterator();
while (it.hasNext()) {
Map map = (Map) it.next();
int i = (Integer) map.get("stationNo");
if (i < transferStaNo) {
secLineStaList.add(map);
}
}
}
}
}

/**
* create date:2008-5-19 author:Administrator
*
* @return
*/
private ArrayList checkCrossLine() {
ArrayList crossLineList = new ArrayList();// 相交线路的集合,即是所有的换乘方法的集合
ArrayList lsStart = firLineStaList;// 经过起点站的所有车次的经停站站信息。
ArrayList lsEnd = secLineStaList;// 经过目的站的所有车次的经停站站信息。
if (lsStart != null && !lsStart.isEmpty() && lsEnd != null && !lsEnd.isEmpty()) {
for (Map mapStart : lsStart) {
for (Map mapEnd : lsEnd) {
if (IsInTheSameCity(mapStart.get("up"), mapEnd.get("up"))) {
// 将相交线路信息存入crossLine,存储某一个具体的换乘方法
Map crossLine = new HashMap(4, 0.8f);
// 把第一次要做到车次放如crossLine
crossLine.put("firstLine", mapStart.get("busLine"));
// 把要换乘的车次放入到crossLine
crossLine.put("secondLine", mapEnd.get("busLine"));
// 把中转站点放入到crossLine
crossLine.put("transferSta", mapEnd.get("up"));
// crossLine.put("transferSta",(String)startInf.get("up"));
// 将包含相交线路信息的HashMap存入List
// 也即是把具体某个换乘方法放入crossLineList
crossLineList.add(crossLine);
} else {
continue;
}
}
}
} else {
crossLineList = null;
}
return crossLineList;
}

private boolean IsInTheSameCity(String station1, String station2) {
if (station1.contains(station2) || station2.contains(station1)) {
// System.out.println(station1+"#########"+station2);
return true;
} else {
return false;
}
}

public ArrayList getSchemaOfTransfer() {
this.getStationsInLine(this.start, this.whither);
return this.checkCrossLine();
}

public static void main(String[] args) {
T tb = new T("前门", "天安门西");
// tb.getSchemaOfTransfer();
for (Map map : tb.getSchemaOfTransfer()) {
System.out.println(map);
System.out.println("您好,您可以先乘坐 " + map.get("firstLine") + " 到 " + map.get("transferSta")
+ " 然后换乘 " + map.get("secondLine") + " 便可到达,不要错过站吆 !");
}
// System.out.println(tb.secLineStaList.size());
}

private Connection getConnection() {
Connection con = null;
String url = "jdbc:mysql://127.0.0.1:3306/souwhat?autoReconnect=true&useUnicode=true&characterEncoding=GBK&mysqlEncoding=GBK";
String user = "root";
String psWord = "";
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("The Exception at load the Driver");
}
try {
con = DriverManager.getConnection(url, user, psWord);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("The Exception at creat the connection");
}
return con;
}

private void closeConnection(Connection conn) throws Exception {
if (conn != null) {
conn.close();
}
}

private List executeQuery(String sql) throws Exception {
// System.out.println("executeQuery(sql): " + sql);
List list = new ArrayList();
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
stmt = conn.createStatement();
System.out.println(sql);
rs = stmt.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
while (rs.next()) {
Map map = new HashMap();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
// 每一行所有列存入HashMap中
map.put(rsmd.getColumnName(i), rs.getObject(i));
}
// 所有行存入List中
list.add(map);
}
} catch (Exception e) {
System.out.println("数据库查询出错!");
e.printStackTrace();
} finally {
if (rs != null)
rs.close();
closeConnection(conn);
}
return list;
}
}