代碼如下:調用kettle 4.2版本
package test;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.vfs.FileSelector;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.util.EnvUtil;
import org.pentaho.di.job.Job;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.repository.RepositoryDirectory;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.pentaho.di.repository.kdr.KettleDatabaseRepositoryMeta;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import com.longtech.configuration.BaseConfiguration;
import com.platform.common.util.LoggerUtil;
/**
*
* @Description: java調用kettle 數據庫型資料庫中的轉換
* @author chen 此類是調用kettle 4.2版本的測試類
* @version 1.0,
* @date 2013-5-23 下午02:40:50
*/
public class ExecRepositoryTrans {
/**
* 本測試類慎用!!!!!!!
* @param args
*/
public static void main(String[] args) {
//D:\java\workspace\sics\src\config\kettle
String classesdir = BaseConfiguration.getString("classesdir");
String jobName = BaseConfiguration.getString("kettle.path.file");
if(StringUtils.isNotEmpty(jobName)){
LoggerUtil.info(ExecRepositoryTrans.class, "執行kettle job start-------------------");
runJob(classesdir + jobName);
LoggerUtil.info(ExecRepositoryTrans.class, "執行kettle job end -------------------");
}else{
LoggerUtil.info(ExecRepositoryTrans.class, "請配置kettle.path.file job 的路徑文件");
}
}
/**
*java 調用kettle 轉換
*/
public static void runTransfer(){
Trans trans=null;
FileSelector f = null;
try {
// 初始化
String fName= "D:\\kettle\\informix_to_am_4.ktr";
// 轉換元對象
KettleEnvironment.init();//初始化
EnvUtil.environmentInit();
TransMeta transMeta = new TransMeta(fName);
// 轉換
trans = new Trans(transMeta);
// 執行轉換
trans.execute(null);
// 等待轉換執行結束
trans.waitUntilFinished();
//拋出異常
if(trans.getErrors()>0){
throw new Exception("There are errors during transformation exception!(傳輸過程中發生異常)");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* java 調用 kettle 的job
* @param jobname 如: String fName= "D:\\kettle\\informix_to_am_4.ktr";
*/
public static void runJob(String jobname){
try {
KettleEnvironment.init();
//jobname 是Job腳本的路徑及名稱
JobMeta jobMeta = new JobMeta(jobname, null);
Job job = new Job(null, jobMeta);
//向Job 腳本傳遞參數,腳本中獲取參數值:${參數名}
//job.setVariable(paraname, paravalue);
job.start();
job.waitUntilFinished();
if (job.getErrors() > 0) {
throw new Exception("There are errors during job exception!(執行job發生異常)");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 配置數據源 調用資源庫中的相關job 、transfer
*/
public static void dbResource(){
String transName="t1";
try {
KettleEnvironment.init();
DatabaseMeta dataMeta = new DatabaseMeta("KettleDBRep","MSSQL","Native","127.0.0.1","etl","1433","sa","bsoft");
KettleDatabaseRepositoryMeta repInfo = new KettleDatabaseRepositoryMeta();
repInfo.setConnection(dataMeta);
KettleDatabaseRepository rep = new KettleDatabaseRepository();
rep.init(repInfo);
rep.connect("admin", "admin");
RepositoryDirectoryInterface dir = new RepositoryDirectory();
dir.setObjectId(rep.getRootDirectoryID());
TransMeta tranMeta = rep.loadTransformation(rep.getTransformationID(transName, dir), null);
Trans trans = new Trans(tranMeta);
trans.execute(null);
trans.waitUntilFinished();
} catch (KettleException e) {
e.printStackTrace();
}
}
}
方法一:用java.util.Date類來實現,并結合java.text.DateFormat類來實現時間的格式化,看下面代碼:
import java.util.*;
import java.text.*;
//以下默認時間日期顯示方式都是漢語語言方式
//一般語言就默認漢語就可以了,時間日期的格式默認為MEDIUM風格,比如:2008-6-16 20:54:53
//以下顯示的日期時間都是再Date類的基礎上的來的,還可以利用Calendar類來實現見類TestDate2.java
public class TestDate {
public static void main(String[] args) {
Date now = new Date();
Calendar cal = Calendar.getInstance();
DateFormat d1 = DateFormat.getDateInstance(); //默認語言(漢語)下的默認風格(MEDIUM風格,比如:2008-6-16 20:54:53)
String str1 = d1.format(now);
DateFormat d2 = DateFormat.getDateTimeInstance();
String str2 = d2.format(now);
DateFormat d3 = DateFormat.getTimeInstance();
String str3 = d3.format(now);
DateFormat d4 = DateFormat.getInstance(); //使用SHORT風格顯示日期和時間
String str4 = d4.format(now);
DateFormat d5 = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL); //顯示日期,周,時間(精確到秒)
String str5 = d5.format(now);
DateFormat d6 = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG); //顯示日期。時間(精確到秒)
String str6 = d6.format(now);
DateFormat d7 = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT); //顯示日期,時間(精確到分)
String str7 = d7.format(now);
DateFormat d8 = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM); //顯示日期,時間(精確到分)
String str8 = d8.format(now);//與SHORT風格相比,這種方式最好用
System.out.println("用Date方式顯示時間: " + now);//此方法顯示的結果和Calendar.getInstance().getTime()一樣
System.out.println("用DateFormat.getDateInstance()格式化時間后為:" + str1);
System.out.println("用DateFormat.getDateTimeInstance()格式化時間后為:" + str2);
System.out.println("用DateFormat.getTimeInstance()格式化時間后為:" + str3);
System.out.println("用DateFormat.getInstance()格式化時間后為:" + str4);
System.out.println("用DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL)格式化時間后為:" + str5);
System.out.println("用DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG)格式化時間后為:" + str6);
System.out.println("用DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT)格式化時間后為:" + str7);
System.out.println("用DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM)格式化時間后為:" + str8);
}
}
運行結果:
用Date方式顯示時間: Mon Jun 16 20:54:53 CST 2008
用DateFormat.getDateInstance()格式化時間后為:2008-6-16
用DateFormat.getDateTimeInstance()格式化時間后為:2008-6-16 20:54:53
用DateFormat.getTimeInstance()格式化時間后為:20:54:53
用DateFormat.getInstance()格式化時間后為:08-6-16 下午8:54
用DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL)格式化時間后為
:2008年6月16日 星期一 下午08時54分53秒 CST
用DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG)格式化時間后為
:2008年6月16日 下午08時54分53秒
用DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT)格式化時間后
為:08-6-16 下午8:54
用DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM)格式化時間
后為:2008-6-16 20:54:53
方法二:用java.util.Calendar類來實現,看下面:
import java.util.*;
import java.text.*;
//以下是利用Calendar類來實現日期時間的,和Date類相比較比較簡單
public class TestDate2 {
public static void main(String[] args) {
Calendar ca = Calendar.getInstance();
int year = ca.get(Calendar.YEAR);//獲取年份
int month=ca.get(Calendar.MONTH);//獲取月份
int day=ca.get(Calendar.DATE);//獲取日
int minute=ca.get(Calendar.MINUTE);//分
int hour=ca.get(Calendar.HOUR);//小時
int second=ca.get(Calendar.SECOND);//秒
int WeekOfYear = ca.get(Calendar.DAY_OF_WEEK);
System.out.println("用Calendar.getInstance().getTime()方式顯示時間: " + ca.getTime());
System.out.println("用Calendar獲得日期是:" + year +"年"+ month +"月"+ day + "日");
System.out.println("用Calendar獲得時間是:" + hour +"時"+ minute +"分"+ second +"秒");
System.out.println(WeekOfYear);//顯示今天是一周的第幾天(我做的這個例子正好是周二,故結果顯示2,如果你再周6運行,那么顯示6)
}
}
運行結果是:
用Calendar.getInstance().getTime()方式顯示時間: Mon Jun 16 21:54:21 CST 2008
用Calendar獲得日期是:2008年5月16日
用Calendar獲得時間是:9時54分21秒
2
總結:中的來說,方法二是最方便的,方法一顯得分笨拙,不過看個人喜歡了。
轉自:http://student.csdn.net/space.php?uid=122120&do=blog&id=14681
方法三:
字母 | 日期或時間元素 | 表示 | 示例 |
---|---|---|---|
G | Era 標志符 | Text | AD |
y | 年 | Year | 1996 ; 96 |
M | 年中的月份 | Month | July ; Jul ; 07 |
w | 年中的周數 | Number | 27 |
W | 月份中的周數 | Number | 2 |
D | 年中的天數 | Number | 189 |
d | 月份中的天數 | Number | 10 |
F | 月份中的星期 | Number | 2 |
E | 星期中的天數 | Text | Tuesday ; Tue |
a | Am/pm 標記 | Text | PM |
H | 一天中的小時數(0-23) | Number | 0 |
k | 一天中的小時數(1-24) | Number | 24 |
K | am/pm 中的小時數(0-11) | Number | 0 |
h | am/pm 中的小時數(1-12) | Number | 12 |
m | 小時中的分鐘數 | Number | 30 |
s | 分鐘中的秒數 | Number | 55 |
S | 毫秒數 | Number | 978 |
z | 時區 | General time zone | Pacific Standard Time ; PST ; GMT-08:00 |
Z | 時區 | RFC 822 time zone |
|
一、在linux下
刪除這些目錄是很簡單的,命令如下
find . -type d -name ".svn"|xargs rm -rf
或者
find . -type d -iname ".svn" -exec rm -rf {} \;
二、在windows下用以下法子:
1、在項目平級的目錄,執行dos命令:
xcopy project_dir project_dir_1 /s /i
2、或者在項目根目錄執行以下dos命令
for /r . %%a in (.) do @if exist "%%a\.svn" rd /s /q "%%a\.svn"
其實第二種方法可以用來干很多事的,比如把代碼中的.svn替換為任意其他文件名并在硬盤根目錄下執行,就可以從硬盤上刪除所有的這個文件啦。
3、添加注冊表(親自動手測試過)
可以將“快速刪除SVN版本信息”命名增加到資源管理器的右鍵上,這樣,鼠標點兩下就能把選中目錄下的所有.svn目錄干掉了。
代碼為:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="快速刪除SVN版本信息"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c D:\工具\批處理文件刪除SVN版本信息.bat"
將這段代碼保存為一個.reg文件,雙擊確認導入注冊表中不完整,后來自己手工添加。注意:文件“批處理文件刪除SVN版本信息.bat”不能放 在有空格的文件夾下,確認刪除時請看一下當前目錄不要刪除不該刪的目錄下的SVN版本信息。不知道怎么改進“cmd.exe /c D:\工具\批處理文件刪除SVN版本信息.bat”。
批處理文件刪除SVN版本信息.bat文件內容如下:
@echo off
echo ***********************************************************
echo 清除SVN版本信 息
echo ***********************************************************
:start
::啟動過程,切換目錄
:set pwd=%cd%
:cd %1
echo 工作目錄是:& chdir
:input
::獲取輸入,根據輸入進行處理
set source=:
set /p source=確定要清楚當前目錄下的.svn信息嗎?[Y/N/Q]
set "source=%source:"=%"
if "%source%"=="y" goto clean
if "%source%"=="Y" goto clean
if "%source%"=="n" goto noclean
if "%source%"=="N" goto noclean
if "%source%"=="q" goto end
if "%source%"=="Q" goto end
goto input
:clean
::主處理過程,執行清理工作
@echo on
@for /d /r %%c in (.svn) do @if exist %%c ( rd /s /q %%c & echo 刪除目錄%%c)
@echo off
echo "當前目錄下的svn信息已清除"
goto end
:noclean
::分支過程,取消清理工作
echo "svn信息清楚操作已取消"
goto end
:end
::退出程序
cd "%pwd%"
pause
注:最后一種方法,如果出現錯誤,就打開注冊表,找到對應的項,吧“cmd.exe /c D:\工具\批處理文件刪除SVN版本信息.bat “直接寫入注冊表中即可使用
我只用了最后一種方法:
報文件沒有關聯錯誤,找到這個注冊表項:[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
寫入:“cmd.exe /c D:\工具\批處理文件刪除SVN版本信息.bat “,注意路徑
還有一個要注意的:在使用的時候,不要在要清除的文件夾上右擊,在要清除的文件夾里面的子文件夾上右擊--》快速刪除svn版本信息
Linux下gzip命令是用來壓縮文件的。gzip不僅可以用來壓縮大的、較少使用的文件以節省磁盤空間,還可以和tar命令一起構成Linux操作系統中比較流行的壓縮文件格式。據統計,gzip命令對文本文件有60%~70%的壓縮率。 gzip命令的格式是: gzip [option] [file] gzip很容易使用。如果想壓縮某個文件或者磁帶檔案文件,可輸入下面的內容: gzip mydir.tar 在缺省的狀態下,gzip 會壓縮文件、再加上一個.gz擴展名,然后刪除掉原來的文件。如果想解壓縮文件,可以使用gzip的對應程序命令gunzip或者gzip命令的-d解壓 縮參數。但是必須保證這個用于解壓縮的文件有.gz(或者.Z、-gz、.z、-z、或者_z)擴展名,否則gzip命令和gunzip命令都會顯示出錯 信息。如果想使用自己的擴展名,可以使用-S后綴參數,如下所示: gzip -S .gzipped mydir.tar gzip 還可以處理用zip命令、compress命令和pack命令壓縮的文件包。如果想在壓縮或者解壓縮的過程中看到更多的信息,可以使用-l列清單參數看到 文件在被壓縮或解壓縮的時候的文件長度。在前一個例子中,壓縮完子目錄mydir之后,可以使用gzip命令按照下面的方法得到有關的數據: # gzip -l mydir.tar.gz compressed uncompr.ratio uncompressed_name 此外,gzip還有一個很有用的參數-t,可以用來測試壓縮文件的完整性。如果文件正常,gzip不會給出任何顯示。如果想看到OK這兩個字母,可以在測試某個文件時使用-tv參數。
312 21330 98.2% mydir.tar
#####從ftp服務器上的/home/data 到 本地的/home/databackup####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
mget *
close
bye
!
2. FTP自動登錄上傳文件。
####本地的/home/databackup to ftp服務器上的/home/data####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
hash
cd /home/data
lcd /home/databackup
prompt
mput *
close
bye
!
3. FTP自動登錄下載單個文件。
####ftp服務器上下載/home/data/a.sh to local /home/databackup####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
get a.sh a.sh
close
bye
!
4. FTP自動登錄上傳單個文件。
####把本地/home/databachup/a.sh up ftp /home/databackup 下####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
put a.sh a.sh
close
bye
!
使用.netrc文件方式自動登錄
在用戶目錄下下建.netrc的文件地址: http://www.cnblogs.com/maxianghui/archive/2006/05/11/397747.html
確實不錯,感謝這位朋友
只能輸入數字:"^[0-9]*$"。
只能輸入n位的數字:"^"d{n}$"。
只能輸入至少n位的數字:"^"d{n,}$"。
只能輸入m~n位的數字:。"^"d{m,n}$"
只能輸入零和非零開頭的數字:"^(0|[1-9][0-9]*)$"。
只能輸入有兩位小數的正實數:"^[0-9]+(.[0-9]{2})?$"。
只能輸入有1~3位小數的正實數:"^[0-9]+(.[0-9]{1,3})?$"。
只能輸入非零的正整數:"^"+?[1-9][0-9]*$"。
只能輸入非零的負整數:"^"-[1-9][]0-9"*$。
只能輸入長度為3的字符:"^.{3}$"。
只能輸入由26個英文字母組成的字符串:"^[A-Za-z]+$"。
只能輸入由26個大寫英文字母組成的字符串:"^[A-Z]+$"。
只能輸入由26個小寫英文字母組成的字符串:"^[a-z]+$"。
只能輸入由數字和26個英文字母組成的字符串:"^[A-Za-z0-9]+$"。
只能輸入由數字、26個英文字母或者下劃線組成的字符串:"^"w+$"。
驗證用戶密碼:"^[a-zA-Z]"w{5,17}$"正確格式為:以字母開頭,長度在6~18之間,只能包含字符、數字和下劃線。
驗證是否含有^%&',;=?$""等字符:"[^%&',;=?$"x22]+"。
只能輸入漢字:"^["u4e00-"u9fa5]{0,}$"
驗證Email地址:"^"w+([-+.]"w+)*@"w+([-.]"w+)*"."w+([-.]"w+)*$"。
驗證InternetURL:"^http://([/"w-]+".)+["w-]+(/["w-./?%&=]*)?$"。
驗證電話號碼:"^("("d{3,4}-)|"d{3.4}-)?"d{7,8}$"正確格式為:"XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
驗證身份證號(15位或18位數字):"^"d{15}|"d{18}$"。
驗證一年的12個月:"^(0?[1-9]|1[0-2])$"正確格式為:"01"~"09"和"1"~"12"。
驗證一個月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正確格式為;"01"~"09"和"1"~"31"。
利用正則表達式限制網頁表單里的文本框輸入內容:
用正則表達式限制只能輸入中文: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,''))"
得用正則表達式從URL地址中提取文件名的javascript程序,如下結果為page1
s="http://www.9499.net/page1.htm"
s=s.replace(/(.*"/){0,}([^".]+).*/ig,"$2")
alert(s)
匹配雙字節字符(包括漢字在內):[^"x00-"xff]
應用:計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)
String.prototype.len=function(){return this.replace([^"x00-"xff]/g,"aa").length;}
匹配空行的正則表達式:"n["s| ]*"r
匹配HTML標記的正則表達式:/<(.*)>.*<"/"1>|<(.*) "/>/
匹配首尾空格的正則表達式:(^"s*)|("s*$)
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))
符號解釋:
字符
描述
"
將下一個字符標記為一個特殊字符、或一個原義字符、或一個 向后引用、或一個八進制轉義符。例如,'n' 匹配字符 "n"。'"n' 匹配一個換行符。序列 '""' 匹配 """ 而 ""(" 則匹配 "("。
^
匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '"n' 或 '"r' 之后的位置。
$
匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '"n' 或 '"r' 之前的位置。
*
匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價于{0,}。
+
匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價于 {1,}。
?
匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等價于 {0,1}。
{n}
n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。
{n,}
n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'。'o{0,}' 則等價于 'o*'。
{n,m}
m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價于 'o?'。請注意在逗號和兩個數之間不能有空格。
?
當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m})
后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對于字符串
"oooo",'o+?' 將匹配單個 "o",而 'o+' 將匹配所有 'o'。
.
匹配除 ""n" 之外的任何單個字符。要匹配包括 '"n' 在內的任何字符,請使用象 '[."n]' 的模式。
(pattern)
匹配 pattern 并獲取這一匹配。所獲取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0…$9 屬性。要匹配圓括號字符,請使用 '"(' 或 '")'。
(?:pattern)
匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以后使用。這在使用 "或"
字符 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比
'industry|industries' 更簡略的表達式。
(?=pattern)
正向預查,在任何匹配 pattern
的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如,'Windows
(?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1"
中的
"Windows"。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。
(?!pattern)
負向預查,在任何不匹配 pattern
的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如'Windows
(?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000"
中的 "Windows"。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始
x|y
匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。
[xyz]
字符集合。匹配所包含的任意一個字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^xyz]
負值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
[a-z]
字符范圍。匹配指定范圍內的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范圍內的任意小寫字母字符。
[^a-z]
負值字符范圍。匹配任何不在指定范圍內的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范圍內的任意字符。
"b
匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er"b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
"B
匹配非單詞邊界。'er"B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
"cx
匹配由 x 指明的控制字符。例如, "cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字符。
"d
匹配一個數字字符。等價于 [0-9]。
"D
匹配一個非數字字符。等價于 [^0-9]。
"f
匹配一個換頁符。等價于 "x0c 和 "cL。
"n
匹配一個換行符。等價于 "x0a 和 "cJ。
"r
匹配一個回車符。等價于 "x0d 和 "cM。
"s
匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ "f"n"r"t"v]。
"S
匹配任何非空白字符。等價于 [^ "f"n"r"t"v]。
"t
匹配一個制表符。等價于 "x09 和 "cI。
"v
匹配一個垂直制表符。等價于 "x0b 和 "cK。
"w
匹配包括下劃線的任何單詞字符。等價于'[A-Za-z0-9_]'。
"W
匹配任何非單詞字符。等價于 '[^A-Za-z0-9_]'。
"xn
匹配 n,其中 n 為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。例如,'"x41' 匹配 "A"。'"x041' 則等價于 '"x04' & "1"。正則表達式中可以使用 ASCII 編碼。.
"num
匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。例如,'(.)"1' 匹配兩個連續的相同字符。
"n
標識一個八進制轉義值或一個向后引用。如果 "n 之前至少 n 個獲取的子表達式,則 n 為向后引用。否則,如果 n 為八進制數字 (0-7),則 n 為一個八進制轉義值。
"nm
標識一個八進制轉義值或一個向后引用。如果 "nm 之前至少有 nm 個獲得子表達式,則 nm 為向后引用。如果 "nm
之前至少有 n 個獲取,則 n 為一個后跟文字 m 的向后引用。如果前面的條件都不滿足,若 n 和 m 均為八進制數字 (0-7),則 "nm
將匹配八進制轉義值 nm。
"nml
如果 n 為八進制數字 (0-3),且 m 和 l 均為八進制數字 (0-7),則匹配八進制轉義值 nml。
"un
匹配 n,其中 n 是一個用四個十六進制數字表示的 Unicode 字符。例如, "u00A9 匹配版權符號 (?)。
想在Web中定時 處理某些任務吧?
可以在Global.asax 中定義,直接上例子:
上面 是一個定時發郵件的小例子,一舉兩得,還給大家了一個發郵件的例子 ,呵呵
建議最好是把需要啟動的事項 做成 web Service 這樣 應用范圍會更廣~
from http://www.informit.com/guides/content.aspx?g=java&seqNum=575
Last updated Jun 25, 2010.
One of the powerful things about Hibernate is that you do not typically need to manually write SQL: you build a domain model that represents your data model in an object-oriented manner and then interact with your domain model. This is the ideal, but sometimes you need to model a legacy data model or a data model that is not object-oriented in nature, which leads to either complicated Hibernate mappings or the inclusion of manual SQL. When this occurs, you do not want to have to build separate data access object classes but rather you would like to find a way to seamlessly integrate SQL into your existing data access object classes in a way that your consumers do not even realize that you're not using Hibernate Query Language (HQL) under-the-hood.
Fortunately you do not need to jump through too many hoops to integrate manual JDBC into your Hibernate classes, you just need to perform the following steps:
Listings 1 and 2 illustrate how to use the Work interface to execute a simple SQL statement.
...
public class MyDao
{
...
public String getValue( long id )
{
// Create a SQL order of work, which we will use to execute a manual SQL statement
MyWork myWork = new MyWork( id );
// Gain access to the underlying Hibernate session
Session session = getSessionFactory().openSession();
// Ask the Hibernate session to execute the unit of work
session.doWork( myWork );
// Obtain the results of the unit of work
return myWork.getValue();
}
..
}
Listing 1 defines a getValue() method that accepts an id and returns a String. It creates a new MyWork instance, passing it the id as an initialization parameter, locates a Hibernate Session, and passes the MyWork instance to the Sessions doWork() method. After the query is complete, it retrieves the value from the MyWork class.
The mechanism that you use to obtain a Hibernate Session will be dependent on the technology with which you are building your data access object. If you're using Spring by extending HibernateDaoSupport, you can invoke getSessionFactory().openSession() to create a new Session object.
Listing 2 shows the source code for the MyWork class.
public class MyWork implements Work
{
private long id;
private String value;
public MyWork( long id )
{
this.id = id;
}
public String getValue()
{
return value;
}
@Override
public void execute( Connection connection ) throws SQLException
{
PreparedStatement ps = null;
ResultSet rs = null;
try
{
ps = connection.prepareStatement( "SELECT * FROM table WHERE id = ?" );
ps.setLong( 1, id );
rs = ps.executeQuery();
while( rs.next() )
{
value = rs.getString( 1 );
}
}
catch( SQLException e ) { }
finally {
if( rs != null )
{
try {
rs.close();
}
catch( Exception e ) {}
}
if( ps != null )
{
try {
ps.close();
}
catch( Exception e ) {}
}
}
}
}
The MyWork class implements its data access logic in its execute() method. The execute() method is passed a java.sql.Connection object that you can use as you normally would to create a Statement, PreparedStatement, or CallableStatement. The doWork() method returns void, so it is up to you to develop a mechanism to return a value from your unit of work.
If you are executing SQL from which you do not necessarily need to retrieve results, you can accomplish the same results by creating an anonymous inner class:
// Gain access to the underlying Hibernate session
Session session = getSessionFactory().openSession();
// Ask the Hibernate session to execute the unit of work
session.doWork( new Work() {
@Override
public void execute( Connection connection ) {
// Implement your SQL here
}
} );
In this example we create the Work() implementation in the doWork() method invocation and override the execute() method. Depending on your background this might look a bit strange, but once you get used to it, this is a fairly elegant way to implement your solution because it reduces the number of explicit classes you need to create and it couples the logic being executed with the invocation of that logic. For complicated cases you want to loosely couple things, but for a SQL statement it is overkill to create additional classes if you do not need to. The challenge here, however, is that if you need to obtain results from the query, you're limited because the doWork() method returns void.
Hibernate offers a simple mechanism to execute SQL inside your Hibernate data access object classes by defining a unit of work and passing it to your Hibernate Session's doWork() method. You can define your unit of work explicitly by creating a class that implements org.hibernate.jdbc.Work or by creating an anonymous inner class that implements the Work interface on-the-fly. The best solution, if you are building your domain model from scratch, is to model your objects as simply as you can (remember the KISS principle: keep it simple, stupid), but if you have to create a domain model that does not lend itself easily to an object-oriented representation then you can integrate manual SQL in this manner.
轉自:http://blog.163.com/yiyun_8/blog/static/100336422201031505832337/
nowait的含義很多人都會誤解為“不用等待,立即執行”。但實際上該關鍵字的含義是“不用等待,立即返回”
如果當前請求的資源被其他會話鎖定時,會發生阻塞,nowait可以避免這一阻塞,因為
If another user is in the process of modifying that row, we will get an ORA‐00054
Resource Busy error. We are blocked and must wait for the other user to finish with
it.
可以實驗下,我用pl/sql developer鎖定表game
SQL> select * from game where game_id =1;
返回一條記錄
SQL> select * from game where game_id=1 for update nowait;
select * from game where game_id=1 for update nowait
*
ERROR位于第1行:
ORA-00054:資源正忙,要求指定NOWAIT
使用NOWAIT關鍵字,會報ORA‐00054的錯誤
如何來查看是什么資源造成這樣的情況呢?并且怎么解決呢?
查看鎖定的對象,用戶和會話
SQL> select lo.oracle_username,do.object_name,s.logon_time,lo.process,s.sid as s
ession_id
2 from v$locked_object lo,v$session s,dba_objects do
3 where lo.session_id = s.sid and do.object_id = lo.OBJECT_ID
4 /
ORACLE_USERNAME
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
LOGON_TIME PROCESS SESSION_ID
------------------- ------------ ----------
NBA---用戶名稱
GAME---操作的對象
2009-08-04 10:55:15---登錄的時間 840:5176 10
使用as sysdba
根據sid查看具體的sql語句
selectsql_textfromv$session a,v$sqltext_with_newlines b
whereDECODE(a.sql_hash_value,0, prev_hash_value, sql_hash_value)=b.hash_value
anda.sid=10;
begin :id := sys.dbms_transaction.local_transaction_id; end;
kill session
SQL> select sid,serial# from v$session where sid =10;
SID SERIAL#
---------- ----------
10 23
SQL> alter system kill session '10,23';
系統已更改。
select * from game where game_id=1 for update nowait;
有數據返回了
當兩個用戶同時更新同一條記錄是, 使用select for update,后執行者,會被阻塞,而使用select for update nowait 則會拋出:ORA-00054 resource busy and acquire with NOWAIT specified 異常,告之用戶這一行已經鎖定。
轉自:http://blog.163.com/hzd_love/blog/static/131999881201082111852520/
要使用Struts2的標簽,只需要在JSP頁面添加如下一行定義即可:
<%@ taglib prefix="s" uri="/struts-tags"%>
struts2的標簽共分為五大類:
一、邏輯控制標簽
用于進行邏輯控制輸出。主要分以下幾類:
1)條件標簽:用于執行基本的條件流轉
<s:if>:擁有一個test屬性,其表達式的值用來決定標簽里內容是否顯示。<s:if test="#request.username=='hzd'">歡迎hzd</s:if>
<s:elseif>:同上。
<s:else>
2)迭代標簽:用于遍歷集合(java.util.Collection)或者枚舉值(java.util.Iterator)類型的對象,value屬性表示集合或枚舉對象,status屬性表示當前循環的對象,在循環體內部可以引用該對象的屬性
<s:iterator value="userList" status="user">
姓名:<s:property value="user.userName" />
年齡:<s:property value="user.age" />
</s:iterator>
3)組合標簽:用于將多個枚舉值對象進行疊加,形成一個新的枚舉值列表
如將3個列表對象進行了組合,形成新的列表對象:
<s:append var="newIteratorList">
<s:param value="%{myList1}" />
<s:param value="%{myList2}" />
<s:param value="%{myList3}" />
</s:append>
輸出:
<s:iterator value="%{#newIteratorList}">
<s:property />
</s:iterator>
4)分割標簽:用于將一個字符串進行分隔,產生一個枚舉值列表
下面的代碼將分隔為3個字符串,然后循環輸出
<s:generator val="%{'aaa,bbb,ccc'}">
<s:iterator>
<s:property />
</s:iterator>
</s:generator>
5)合并標簽:用于將多個枚舉值按照數組的索引位置進行合并
<s:merge var="newMergeList">
<s:param value="%{mylist1}">--設mylist1列表中有a,b,c三個元素
<s:param value="%{mylist2}">--設mylist2列表中有1,2,3三個元素
</s:merge>
合并后新的列表的元素及其順序為:a,1,b,2,c,3
<s:iterator value="%{#newMergeList}">
<s:property />
</s:iterator>
6)排序標簽:用于對一組枚舉值進行排序,屬性comparator指向一個繼承自java.util.Comparator的比較器,該比較器可以是對應Action頁面中的一個比較器變量,source指定要排序的列表對象
<s:sort comparator="myComparator" source="myList">
<s:iterator>
<s:property value="..."/>
</s:iterator>
</s:sort>
7)子集標簽:用于取得一個枚舉列表的子集,source用于指定檢索的列表對象,start用于指定起始檢索的索引位置,count用于指定檢索的結果數量,decider屬性必須是一個org.apache.struts2.util.SubsetIteratorFilter.Decider類的子類實例,用以指定檢索的條件。例如在Action中提供了以下方法用來取得一個Decider對象:
public Decider getDecider()
{
return new Decider(){
public boolean decide(Object element) throws Exception{
int i=((Integer)element).intValue();
return (((i%2)==0)?true:false);
}
};
}
然后引用該對象篩選子集:
<s:subset source="myList" decider="decider">
</s:subset>
或者不使用Decider對象:
<s:subset source="myList" count="13" start="3">
</s:subset>
二、數據輸出標簽
數據輸出標簽用以輸出頁面中的元素、屬性、隱含變量等,即包括靜態文本的輸出,也包括struts2集成的各種變量的輸出。
1)鏈接標簽:用于創建一個<a>標簽,errorText用于顯示錯誤信息,priInvokeJS表示該鏈接執行時的javascript提示函數,href表示跳轉地址.
<s:a errorText="刪除錯誤" preInvokeJS="confirm('確認刪除?')" href="test.jsp">
<img src="/image/delete.gif" />
</s:a>
2)Action標簽:可以直接調用Action類中的函數,前提是該Action類在struts.xml中有定義,name屬性用于指向映射文件中配置的Action函數,executeResult屬性表示是否執行結果集的跳轉
<s:action name="LoginAction" executeResult="true" />--表示執行LoginAction的默認處理方法execute()
<s:action name="LoginAction!login" executeResult="true" />--表示執行LoginAction的處理方法login()
3)JavaBean標簽:用于創建一個JavaBean對象,name表示JavaBean類全名,var表示變量的實例名,并可以包含<s:param>設置實例化輸入參數
<s:bean name="xxx,xxx,xxx" var="xxx">
<s:param name="name" value="hzd" />--為該JavaBean的構造方法傳遞參數
</s:bean>
4)日期標簽:用以輸出一個格式化的日期對象,name表示要輸出的對象,format表示輸出的日期格式
<s:date name="user.birthday" format="dd/MM/yyyy" />
<s:date name="user.birthday" format="%{getText('some.i18n.key')}" />
<s:date name="user.birthday" />--默認格式
5)調用標簽:用以輸出頁面的值棧調試信息,通常在進行程序調用時使用,便于查找JSP頁面中的錯誤
6)引用資源文件標簽:用于加載資源包到值棧,它可以允許<s:text>標簽訪問任何資源包的信息,而不只是當前action相關聯的資源包。name屬性用以指定資源包的類路徑
如xxx.xxx.xxx.ApplicationMessages中定義了標簽:HelloWord=歡迎您!
則可以這樣引用:
<s:i18n name="xxx.xxx.xxx.ApplilcationMessages">
<s:text name="HelloWord" />
</s:i18n>
7)包含頁面標簽:用來包含一個Servlet的輸出(Servlet或JSP頁面),使用value屬性指定包含頁名稱,可以使用<s:param>傳遞參數給子頁
<s:include value="/test.jsp">
<s:param name="username">hzd</s:param>--參數username=hzd給test.jsp頁面
</s:include>
8)傳遞參數標簽:用來為其他標簽提供參數,所以一般是嵌套在其它標簽的內部,name屬性用來指定參數名稱,value(可選)屬性用來指定參數值
<s:param name="username" value="hzd" />--這種方式的參數值會以String格式放入stack
<s:param name="username">hzd</s:param>--這種方式的參數值會以Object的格式放入stack
9)值棧標簽:用以加入一個值到值棧中
<s:push value="user">
<s:property value="name" />--為user指定name屬性
<s:property value="age" />--為user指定age屬性
</s:push>
10)變量賦值標簽:賦予變量一個特定范圍內的值,name屬性表示變量的名字,scope表示變量的作用域(application.session.request.page.action),value變量的值
<s:set>
11)國際化標簽:用于輸出國際化信息,name屬性指定國際化資源文件中消息文本的key,可以與<s:i18n>標簽結合使用
<s:text name="HelloWord" />--它會按照一定的順序查找資源文件,直到找到定義HellowWord標簽的資源文件為止
12)鏈接標簽:用于創建一個URL鏈接,并可以通過<s:param>標簽提供request參數
<s:url id="url" value="/test.jsp">
<s:param name="username">hzd</s:param>
</s:url>
13)屬性標簽:用以輸出value屬性的值,并擁有一個default屬性,在value對象不存在時顯示。escape屬性為true,來輸出原始的HTML文本
<s:property value="getText('some.key')">
三、HTML表單標簽
HTML標簽都擁有以下3個設置樣式的屬性。
templateDir:執行模板路徑
theme:指定主題名稱,可選值包括simple、xhtml、ajax等
template:指定模板名稱
使用HTML表單標簽會生成大量格式化的HTML代碼,這些代碼是由struts2的模板生成的,這樣的好處是可以讓我們的jsp代碼十分簡單,只需要配置使用不同的主題模板,就可以顯示不同的頁面樣式。
struts2默認提供了5種主題(在此不做詳細介紹):
simple主題:最簡單的主題
XHTML主題:默認主題,使用常用的HTML技巧
CSS XHTML主題:使用CSS實現的XHTML主題
archive主題:使用文檔生成主題
AJAX主題:基于AJAX實現的主題
通過在struts.properties文件中改變struts.ui.theme,struts.ui.templateDir,struts.ui.templateSuffix三個標簽來自由切實可行換主題
由于HTML表單標簽也不少,所以還是要用的時候在網上找吧...
四、HTML非表單標簽
主要用來輸出各種錯誤和消息。
1)錯誤標簽:用以輸出Action錯誤信息
<s:actionerror />
2)消息標簽:用以輸出Action普通消息
<s:atcionmessage />
3)字段錯誤標簽:用以輸出Action校驗中某一個字段的錯誤信息或所有字段的錯誤信息
<s:fielderror />--輸出所有字段的錯誤信息
<s:fielderror>
<s:param>username</s:param>--輸出字段username的錯誤信息
<s:param>password</s:param>--輸出字段password的錯誤信息
<s:fielderror>
4)DIV標簽:用以輸出一個<div>標簽
五、AJAX標簽
AJAX標簽是struts2專門提供的一組進行AJAX操作的標簽,在使用這些標簽之前,需要在JSP頁面中添加如下引用:
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%>
1)鏈接標簽:用于創建一個<a>鏈接,并且在單擊該鏈接時執行異步的請求,該標簽的url屬性必須使用<s:url/>標簽進行設置,target屬性指向要被更新的頁面組件,showLoadingText屬性決定是否顯示文本,indicator表示異步請求時要顯示的圖片
使用form標簽:
<s:div id="targetDiv">
<s:form action="LoginAction">
<sx:a targets="targetDiv" showLoadingText="false" indicator="loadingImage" />
</s:form>
</s:div>
使用url標簽:
<s:div id="targetDiv">
<s:url id="ajaxTest" value="/LoginAction.action">
<sx:a targets="targetDiv" href="%{ajaxTest}" showLoadingText="false" indicator="loadingImage" />
</s:div>
2)自動完成標簽:是一個組合框組件,在文本框中輸入文本,能夠給出一個下拉的提示列表。list屬性用以指定一個自動提示檢索的列表集合(可以是Action中的List類型的屬性),autoComplete屬性為true時表示進行自動提示
<sx:autocompleter name="test" list="{'上海','湖南',廣東}" autoCompleter="true" />
3)自動事件綁定標簽:該標簽可以為多個對象的多個事件進行監聽,并能夠發送異步請求。src屬性指定監聽的對象源,events屬性指定監聽的事件類型(JavaScript事件),target屬性指定異步返回內容填充的目標,indicator屬性表示執行異步請求時顯示的圖片
<s:div id="targetDiv">
<s:form action="login">
<s:submit id="bin" />
<s:bind src="bin" events="onclick" targets="targetDiv" showLoadingText="false" indicator="%{getText('loadingImage')}" />
</s:form>
</s:div>
4)日期選擇標簽:用以彈出一個日期和時間的選擇窗口,displayFormat屬性指定要選擇日期的格式,name表示當前組件的屬性的對象,value表示默認值,label表示顯示的文本
<sx:datetimepicker name="order.date" label="Order Date" displayFormat="yyyy-MM-dd" value="%{'2006-01-01'}" />
5)樹標簽:用以輸出一個樹形結構
<sx:tree>
6)Tab頁標簽:使用AJAX的方式顯示多個Tab頁
<s:tabbedpanel>
回調函數還真有點像您隨身帶的BP機:告訴別人號碼,在它有事情時Call您 下面使用java回調函數來實現一個測試函數運行時間的工具類: 通過上面的文字和代碼我們可以理解了什么叫做java的回調。那么我們具體在什么時候使用回調函數呢? 在進行JDBC編程的時候,我們經常要寫到try catch語句塊,而如果采用回調技術,那么完全可以避免重復的去寫,將自己的方法體使用一個回調接口的方法來實現,每次都傳到同一個try catch當總,但是每一個方法的內容是不相同的。 再比如算法比較多的情況下,也可以采用這種實現模式來實現。最近看了SWT,發現里面好多的事件驅動都是采用回調來實現的。比如給按鈕添加事件: Button okButton = createButton(buttons, "&Ok", "Process input", 匿名內部類最常用的情況就是在回調當中的精彩表現。 回調是一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口.
回調用于層間協作,上層將本層函數安裝在下層,這個函數就是回調,而下層在一定條件下觸發回調,例如作為一個驅動,是一個底層,他在收到一個數據時,除了完成本層的處理工作外,還將進行回調,將這個數據交給上層應用層來做進一步處理,這在分層的數據通信中很普遍。
其
實回調和API非常接近,他們的共性都是跨層調用的函數。但區別是API是低層提供給高層的調用,一般這個函數對高層都是已知的;而回調正好相反,他是高
層提供給底層的調用,對于低層他是未知的,必須由高層進行安裝,這個安裝函數其實就是一個低層提供的API,安裝后低層不知道這個回調的名字,但它通過一
個函數指針來保存這個回調,在需要調用時,只需引用這個函數指針和相關的參數指針。
其實:回調就是該函數寫在高層,低層通過一個函數指針保存這個函數,在某個事件的觸發下,低層通過該函數指針調用高層那個函數。
關于回調的總結:
在Java中,通常就是編寫另外一個類或類庫的人規定一個接口,然后你來實現這個接口,然后把這個接口的一個對象作為參數傳給別人的程序,別人的程序必要時就會通過那個接口來調用你編寫的函數。
如果我們要測試一個類的方法的執行時間,通常我們會這樣做:
java 代碼
public class TestObject {
/**
* 一個用來被測試的方法,進行了一個比較耗時的循環
*/
public static void testMethod(){
for(int i=0; i<100000000; i++){
}
}
/**
* 一個簡單的測試方法執行時間的方法
*/
public void testTime(){
long begin = System.currentTimeMillis();//測試起始時間
testMethod();//測試方法
long end = System.currentTimeMillis();//測試結束時間
System.out.println("[use time]:" + (end - begin));//打印使用時間
}
public static void main(String[] args) {
TestObject test=new TestObject();
test.testTime();
}
}
大家看到了testTime()方法,就只有"http://測試方法"是需要改變的,下面我們來做一個函數實現相同功能但更靈活:
首先定一個回調接口:
java 代碼
public interface CallBack {
//執行回調操作的方法
void execute();
}
然后再寫一個工具類:
java 代碼
public class Tools {
/**
* 測試函數使用時間,通過定義CallBack接口的execute方法
* @param callBack
*/
public void testTime(CallBack callBack) {
long begin = System.currentTimeMillis();//測試起始時間
callBack.execute();///進行回調操作
long end = System.currentTimeMillis();//測試結束時間
System.out.println("[use time]:" + (end - begin));//打印使用時間
}
public static void main(String[] args) {
Tools tool = new Tools();
tool.testTime(new CallBack(){
//定義execute方法
public void execute(){
//這里可以加放一個或多個要測試運行時間的方法
TestObject.testMethod();
}
});
}
}
new MySelectionAdapter(){
public void widgetSelected(SelectionEvent e)
{
System.out.println("Name: " + nameField.getText());
System.out.println("Address: " + addrField.getText());
System.out.println("Phone number: " + phoneField.getText());
}
});
警告: No configuration found for the specified act
2008-9-6 11:35:47 org.apache.struts2.components.Form evaluateExtraParamsServletRequest
警告: No configuration found for the specified act
showmsg.jsp代碼如下
<%@ taglib prefix="s" uri="/struts-tags" %>
......
<div>
hello world
<s:form name="ShowMessage" method="post" act
<s:textfield label="user name" name="username"></s:textfield>
<s:submit></s:submit>
</s:form>
</div>
......
struts.xml配置如下:
......
<struts>
<package name="hello" extends="struts-default" namespace="/hello">
<act
<result>/digg/showmsg.jsp</result>
</act
</package>
</struts>
打開showmsg.jsp頁面時,就出現上述異常。嘗試了各種配置和訪問方法,均出現警告。搜索網絡給出的答案幾乎都說把<s:form name="ShowMessage" method="post" act
解決方法:
經過測試發現,是沒有正確使用tag的原因,這種情況下,正確的寫法應該是,<s:form name="ShowMessage" method="post" act
原因分析:
因為開始使用的struts2標簽(form)并未指定namespace屬性。所以struts2會默認從根命名空間"/" 搜索act
現在我們指定了namespace為/hello,則struts2會直接在/hello命名空間尋找。可以想象,如果在這么命名空間里找不到請求的act
注意,<s:form name="ShowMessage" method="post" act
不能寫成<s:form name="ShowMessage" method="post" act
這樣仍然有對應的警告信息,并且提交后出現無法訪問的結果。因為沒有ShowMessage.act
轉載請注明 historycreator.com
1 MPEG:
MPEG是Motion Picture Experts Group 的縮寫,它是視頻編碼格式中的一個大家族,也是我們平時所見到的最普遍的一種視頻格式。從它衍生出來的格式非常多,包括以mpg、mpe、mpa、m15、m1v、mp2等等為后綴名的視頻文件都是出自這一家族。MPEG格式包括MPEG視頻、MPEG音頻和MPEG系統(視頻、音頻同步)三個部分,MP3(MPEG-3)音頻文件就是MPEG音頻的一個典型應用,視頻方面則包括MPEG-1、MPEG-2和MPEG4。
MPEG-1壓縮算法被廣泛應用在 VCD 的制作和一些視頻片段下載方面,其中最多的就是VCD——幾乎所有VCD都是使用Mpeg-1格式壓縮的(*.dat格式的文件)。MPEG-1的壓縮算法可以把一部 120 分鐘長的電影(原始視頻文件)壓縮到1.2 GB左右大小。利用這種壓縮算法制成的文件格式一般為mpg和dat文件。
MPEG-2壓縮算法則應用在DVD的制作上(*.vob格式的文件),同時也在一些HDTV(高清晰電視廣播)和一些高要求視頻編輯、處理有相當的應用。使用MPEG-2的壓縮算法制作一部 120 分鐘長的電影(原始視頻文件)在4GB到8GB大小左右,當然其圖像質量方面的指標是MPEG-1所無法比擬的。利用這種壓縮算法制成的文件格式一般為vob文件。
MPEG-4是一種新的壓縮算法,使用這種壓縮算法可以將一部120分鐘長的電影(原始視頻文件)壓縮至300MB左右。現在,MPEG的這種壓縮算法被許多編碼格式沿用,例如ASF、DivX、Xvid、mp4(Apple公司的mpeg-4編碼格式)等等都采用了MPEG-4的壓縮算法。
2 AVI編碼格式
AVI是 Audio Video Interleave 的縮寫,這種格式在微軟WIN3.1 時代就已經出現了。它最直接的優點就是兼容好、調用方便而且圖像質量好,因此也常常與DVD相并稱。但它的缺點也是十分明顯的:體積大。2小時影像的AVI文件的體積與MPEG-2相差無計,不過這只是針對標準分辨率而言的:根據不同的應用要求,AVI的分辨率可以隨意調。窗口越大,文件的數據量也就越大。降低分辨率可以大幅減低它的體積,但圖像質量就必然受損。與MPEG-2格式文件體積差不多的情況下,AVI格式的視頻質量相對而言要差不少,但制作起來對電腦的配置要求不高,經常有人先錄制好了AVI格式的視頻,再轉換為其他格式。
這里簡單提一下nAVI。nAVI是newAVI的縮寫,這是一個名為 ShadowRealm 的地下組織發展起來的一種新視頻格式。它是由 Microsoft ASF壓縮算法的修改而來的(并不是想象中的AVI,視頻格式追求的無非是壓縮率和圖像質量,所以 n AVI為了追求這個目標,改善了原始的ASF格式的一些不足,讓nAVI可以擁有更高的幀率(frame rate)。當然,這是犧牲ASF的視頻流特性作為代價的。概括來說,nAVI就是一種去掉視頻流特性的改良型ASF格式。
3 REAL VIDEO格式
Real公司一開始定位的就是在視頻流應用方面的,也可以說是視頻流技術的始創者。它可以在用 56K MODEM 撥號上網的條件實現不間斷的視頻播放,當然,其圖像質量和 MPEG2、DIVX 等相比確實要差好多。RM主要用于在低速率的網上實時傳輸視頻的壓縮格式,它同樣具有小體積而又比較清晰的特點。RM文件的大小完全取決于制作時選擇的壓縮率。在2002年Real公司又推出了它的Real Video9編碼方式,使用該技術同上一版相比,畫質提高了30%。使用Real Video9編碼格式的文件名后綴一般為rmvb,RMVB中的VB是VBR即Variable Bit Rate的縮寫,中文是“可變比特率”。它比普通的RM文件有更高的壓縮比(同樣畫質)和更好的畫質(同樣壓縮比)。rmvb文件一般用realone播放器播放,當然也可以用安裝了相應插件的realplay播放(不過播放的時候要將rmvb改成rm)。以前的real video文件名后綴多為RM、RA、RAM。
4 ASF
ASF是 Advanced Streaming format 的縮寫,它是Windows Media技術的核心,采用的是MPEG-4壓縮算法,由于它使用了 MPEG-4 的壓縮算法,所以壓縮率和圖像的質量都很不錯。因為 ASF 是以一個可以在網上即時觀賞的視頻“流”格式存在的,所以它的圖像質量比 VCD 差一點點并不出奇,但比同是視頻流格式的 RAM 格式要好。利用這種編碼方式制成的文件名后綴一般為asf。
5 Quicktime格式
QuickTime(MOV)是Apple公司專有的一種視頻格式。在開始一段時間里,他都是以qt或mov為擴展名的,使用他們自己的編碼格式。但是自從MPEG4組織選擇了Quicktime作為MPEG4的推薦文件格式以后,它們的mov文件就以mpg或mp4為其擴展名,并且采用了MPEG4壓縮算法。Quicktime6將mp4文件作為它的第一選擇,利用quicktime6可以制作出專業級質量的、ISO兼容的MPEG4音頻和視頻文件,而且這些文件也可以被任何兼容MPEG4的播放器播放。
6 DivX
DivX視頻編碼技術可以說是針對DVD而產生的,同時它也是為了打破 ASF 的種種約束而發展起來的。正如上面所提到的那樣,它采用的是MPEG-4算法,這樣以來,壓縮一部DVD只需要2張VCD,而且播放這種編碼,對機器的要求也不高。目前DivX有兩個版本,第一個DivX版本以DivX3.11為例,而第二個版本就是后來的DivX5,但是實際上第二個編碼格式的作者跟divx3.11的作者根本不是同一個人,這兩種編碼格式的設計思路也不同。所以,如果要解壓縮按照DivX3.11編碼的媒體文件時,最好采用DivX3.11的解碼器,而不要用DivX5的解碼器來解碼。目前大部分的DivX視頻采用的是.avi的文件后綴,當然也有以DivX和Div為后綴名的。
7 Xvid格式
Xvid編碼格式是由一些精通視頻編碼的程序員(包括原DivX 3.11的開發者)設計開發出來的,它也是使用的MPEG4壓縮算法。XviD這種全新的編碼平臺,實際上與DivX 5是屬于同一技術核心,可解碼幾乎所有的DVDrip。這里需要解釋一下DVDrip,DVDrip就是指的經過DivX技術壓縮至原來DVD文件大小的1/10左右的媒體文件,其核心的技術主要分成三部分:用Mpeg4來進行視頻壓縮,用MP3或AC-3等壓縮音頻,同時結合字幕播放軟件來外掛字幕。所以一般來說,你只要安裝了Xvid解碼器,你的機器就能播放所有的DivX媒體文件。目前用Xvid技術編碼的文件大多以avi為擴展名。
8 MPEG-4標準(ISO,1999)
MPEG-4初衷是針對視頻會議、可視電話的超低比特率編碼的。但隨著芯片性價比的提高使得基于軟件平臺的壓縮編碼具有實用的可能,且人們在對視頻信息的應用需求從播放型逐漸轉到基于內容的訪問和操作型,所以它制定的新目標為支持多媒體應用(側重于對多媒體信息內容的訪問),可根據應用要求配置解碼器。
MPEG-4為了支持高效壓縮、基于內容交互和基于內容分級擴展,引入了AVO(Audio/Video Object)的概念實現基于內容的表示方法。換句話說它就是圍繞AV對象的編碼、存儲、傳輸和組合而制定的,它是第一個使用戶在接收端對畫面進行操作和交互訪問的編碼標準。
MPEG-4提供自然和合成的音頻、視頻以及圖形的基于對象的編碼工具,它為多媒體數據壓縮提供了一個更為廣闊的平臺,更注重于定義一種格式和框架,而不是具體的算法,這樣可以建立一個更自由的通信和研發環境,可以在系統中加入許多新的算法,為使用計算機軟件實現編碼和解碼提供更大的方便。它還可以將各種各樣的多媒體技術充分運用在編碼中,除包括壓縮本身的一些工具、算法外,還包括圖像分析和合成、計算機視覺、計算機圖形學、虛擬現實和語音合成技術。但是由于“基于對象的編碼”尚有技術障礙,在技術專利保護問題上遲遲難以找到有效的收費形式,因此該標準目前仍然沒有得到普遍應用。
從去年年底起,有幸也轉到了DirectShow方面開發。
在論壇中也可以為一些初學者解答一些初級問題了
見論壇中有人分不清DirectShow為何物,在這,說明一下:
DirectShow是DirectX中的一員。
Dspack是
Delphi用于做DirectShow開發的一套(免費)控件。下載地址:http://www.progdigy.com/
如果是Win2k, 安裝之前,必須先安裝DirectX9.0(DSPack2.3.4默認支持DirectX9.0)。
二、
在Delphi7.0下安裝DSPack
(又是廢話,原本在DSPack控件中說明的很清楚了,就在這略翻譯一下吧)
1 - Add this paths to your search directory:
- (DSPackDir)\src\Directx9
- (DSPackDir)\src\DSPack
譯:添加查
詢路徑,否則在編譯時發生找不到相關.dcu文件錯誤。操作:Delphi(菜單) Tools->Envioronment
Options->Library. 在Library Path處添加。
2 - Compile DirectX 9 Package (DirectX9_Dx.dpk) from the "packages"
directtory.
譯:編譯DirectX9_Dx.dpr(x為Delphi版本號),這個包只要編譯就可以了。
3 - Compile DSPack Package (DSPack_Dx.dpk) from the "packages"
directory.
譯:編譯DSPack_Dx.dpr(x為Delphi版本號),這個包只要編譯就可以了。
4- Install Design Package (DSPackDesign_Dx.dpk) from the "packages"
directory.
譯:編譯并安裝DSPackDesign_Dx.dpk(x為Delphi版本號)。