#
//editor 綁定click事件
var ed = $('#tt').datagrid('getEditor', {
index: 2,
field: 'name'
});
$(ed.target).bind('click', function(){
alert('clicked');
});
//editor 綁定回車事件
$('#ttt').datagrid('beginEdit', rowIndex);
var ed = $('#ttt').datagrid('getEditors', rowIndex);
for (var i = 0; i < ed.length; i++)
{
var e = ed[i];
$(e.target).bind('keyup', function()
{
if (window.event.keyCode == 13)
{
alert("you check enter key");
}
});
}
//editor綁定change 事件
function setEditing(tablename,rowIndex) {
var editors = $('#tt').datagrid('getEditors', rowIndex);
var priceEditor = editors[0];
var amountEditor = editors[1];
var sumcount = editors[2];
priceEditor.target.bind('change', function () {
// calculate();
var sum = priceEditor.target.val() * amountEditor.target.val();
alert(sum);
sumcount.attr1.val(sum);
});
amountEditor.target.bind('change', function () {
var sum = priceEditor.target.val() + amountEditor.target.val();
alert(sum);
});
在datagrid中動態生成combobox問題
$('#tt').datagrid('beginEdit', index);
var ed = $('#tt').datagrid('getEditor', {index:index, field:'productid'});
$(ed.target).combobox('reload', 'combobox_data.json');
在beginEdit時給$("input.datagrid-editable-input")添加keyup事件即可
代碼如下:
onClickRow: function(rowindex, rowData)
{
$('#ttt').datagrid('beginEdit', rowindex);
//$.each(rowData, function(k, v) { alert(k+":"+v); });
$("input.datagrid-editable-input").keyup(function() { alert('hello'); });
},
如何從網頁中下載圖片
如果做為爬蟲很有必要從網頁中下載圖片到本地,那么我們利用jsoup來進行該操作,jsoup 是一個很不錯的html解析器。
網頁中下載圖片需要這么兩步操作
1.獲取絕對路徑
很多網頁中用的是相對路徑,因此獲取圖片的絕對路徑很重要
方法一:我們就利用jsoup來獲取
Element image = document.select("img").first();
String url = image.absUrl("src");
// url = http://www.example.com/images/chicken.jpg
或者
String url = image.attr("abs:src");
他們的前提利用connect方式獲取而不是文件方式
Document doc = Jsoup.connect("http://jsoup.org").get();
Element link = doc.select("a").first();
String relHref = link.attr("href"); // == "/"
String absHref = link.attr("abs:href"); // "http://jsoup.org/"
方法二:利用jdk中url
URL url = new URL("http://www.example.com/index.html");
URI uri = url.toURI();
System.out.println(uri.resolve("images/chicken.jpg").toString());
2.第二步則就是下載圖片
URL url = new URL( "圖片地址");
URLConnection uc = url.openConnection();
InputStream is = uc.getInputStream();
File file = new File( "本地路徑 ");
FileOutputStream out = new FileOutputStream(file);
int i=0;
while ((i=is.read())!=-1) {
out.write(i);
}
is.close();
AJP是定向包協議。因為性能原因,使用二進制格式來傳輸可讀性文本。WEB服務器通過TCP連接和SERVLET容器連接。為了減少進程生成socket的花費,WEB服務器和SERVLET容器之間嘗試保持持久性的TCP連接,對多個請求/回復循環重用一個連接。一旦連接分配給一個特定的請求,在請求處理循環結束之前不會在分配。換句話說,在連接上,請求不是多元的。這個是連接兩端的編碼變得容易,雖然這導致在一時刻會有很多連接。
通常正式的應用都是由apache,nginx來解析http 協議,然后將ajp協議有應用服務器來解析,這樣可以大大提高性能。 一旦WEB服務器打開了一個到SERVLET容器的連接,連接處于下面的狀態:
空閑
這個連接上沒有處理的請求。
已分派
連接正在處理特定的請求。
一旦一個連接被分配給一個特定的請求,在連接上發送的基本請求信息是高度壓縮的。在這點,SERVLET容器大概準備開始處理請求,當它處理的時候,它能發回下面的信息給WEB服務器:
SEND_HEADERS
發送一組頭到瀏覽器。
SEND_BODY_CHUNK
發送一塊主體數據到瀏覽器。
GET_BODY_CHUNK
從請求獲得下一個數據如果還沒有全部傳輸完,如果請求內容的包長度非常大或者長度不確定,這是非常必要的。例如上載文件。注意這和HTTP的塊傳輸沒有關聯。
END_RESPONSE
結束請求處理循環。
異步 IO 模型
異步 I/O 模型大體上可以分為兩種,反應式 (Reactive) 模型和前攝式 (Proactive) 模型:
1. 傳統的 select / epoll / kqueue 模型,以及 Java NIO 模型,都是典型的反應式模型,即應用代碼對 I/O 描述符進行注冊,然后等待 I/O 事件。當某個或某些 I/O 描述符所對應的 I/O 設備上產生 I/O 事件(可讀、可寫、異常等)時,系統將發出通知,于是應用便有機會進行 I/O 操作并避免阻塞。由于在反應式模型中應用代碼需要根據相應的事件類型采取不同的動作,最常見的結構便是嵌套的 if {...} else {...} 或 switch ,并常常需要結合狀態機來完成復雜的邏輯。
2. 前攝式模型則不同。在前攝式模型中,應用代碼主動地投遞異步操作而不管 I/O 設備當前是否可讀或可寫。投遞的異步 I/O 操作被系統接管,應用代碼也并不阻塞在該操作上,而是指定一個回調函數并繼續自己的應用邏輯。當該異步操作完成時,系統將發起通知并調用應用代碼指定的回調函數。在前攝式模型中,程序邏輯由各個回調函數串聯起來:異步操作 A 的回調發起異步操作 B ,B 的回調再發起異步操作 C ,以此往復。 MINA2 便是一個前攝式的異步 I/O 框架。
1.原則: Don't call us,we will call you
2.原來構建對象,對象內如果有其他依賴對象,需要一個個構建后傳入,現在直接先注入好,構建原對象的時候
它會直接向Ioc service Provider 去要
3.注入對象的方式有
A. 構造方法方式注入
B.通過setter 方式注入
C.實現提供的接口來注入
4.Ioc service provider 有兩種功能
A. 業務對象構建管理
B. 業務對象間依賴綁定
5.Ioc service provider 簡化代碼來構建對象,但是這些依賴條件Ioc service provider
如何知道?
A.直接編碼方式知道
比如
IoContainer container=...
container.register(FXNewProvider.class,new FXNewsProvider());
B.配置文件方式
<bean id="newsProvider" ...>
....
</bean>
C.通過注解來注入
6.Spring Ioc 容器
Ioc service provider 是其中的一部分
Ioc 容器spring提供兩種類型
A.BeanFactory :基礎類型Ioc 容器 默認為延時初始化策略,啟動快需要資源有限
B.ApplicationContext:BeanFactory 基礎上構建,屬于高級容器,提供事件發布,國際化等
高級功能,需要資源相對多,啟動相對也就慢。
7.bean 的生命周期
A.singleton: 在spring Ioc 容器中只存在一個實例,他的生命周期從容器啟動并因為第一次被
請求而初始化后,將一直存活到容器退出。這里的singleton 和Gof中提出的Singleton 有點區別
bean的singleton 表示在同一個容器中存在一個實例;而Gof中的Singleton表示同一個classloader中
只存在一個實例。
B.prototype:代理
容器在接收到請求后,為之生成一個新對象實例給請求方,然后就不再有新對象的引用。
C.request,session,global session
只適用web 應用,不像上面的那么通用。通常與XmlWebApplicationContext一起用
request:每一個請求生成一個新的requestProcessor 對象,和http request的生命周期一樣
session:和http session 生命周期一個
global session:只應用在基于portlet 的web應用程序才有意義。映射到portlet的global
范圍的session
D.自定義scope類型
實現org.springframework.beans.factory.config.Scope接口
public infterface Scope{
...
}
其中get和remove 方法必須實現,參考例子
http://jroller.com/eu/entry/more_fun_with_spring_scopes
有了Scope的實現類后,需要把Scope注冊到容器中,才能提供相應的bean定義
通過ConfigurableBeanFactory的 registerScope中進行注冊。BeanFactory
通常實現ConfigurableBeanFactory接口。
如果是ApplicationContext,你還可以通過配置文件來實現,ApplicationContext
會自動識別并加載.
E.面向接口編程指以接口為導向,在類中引用接口而不是具體接口的實現類,這樣就減少和
特定實現類的耦合,比如傳統寫法
public class Foo{
private BarInterface barInstance;
public Foo()
{
barInstance = new BarInterfaceImp();
//BarInterfaceImp其實是BarInterface 接口的實現類
}
}
上面的寫法耦合很大,如果該類是由我們設計并開發的,那么還好說,我們可以通過依賴注入,
讓容器幫助我們解除接口和實現類之間的耦合性,但是,有時,我們需要依賴第三方庫,需要實例化
并通過第三方庫中的相關類,這時,接口和實現類的耦合性需要其他方式來避免。
比如工程方法模式。提供一個工廠類來實例化具體的接口實現類,這樣主體對象只需要依賴工廠類,具體使用的實現類有變革的話,只要變更工廠類。
上面的Foo可以改為:
public class Foo{
private BarInterface barInterface;
public Foo()
{
//barInterface = BarInterfaceFactory.getInstance();
或者
//barInterface =new BarInterfaceFactory().getInstance();
}
}
靜態工廠方法:
public class StaticBarInterfaceFactory
{
public static BarInterface getInstance()
{
return new BarInterfaceImpl();
}
}
spring 提供配置來支持靜態工廠方法
<bean id="bar" class="...StaticBarInterfaceFactory" factory-method="getInstance">
//如果factory-method 有參數可以,進入下面參數
<constructor-arg>
<ref bean="foobar">
</constructor-arg>
</bean>
非靜態工廠方法:
public class NoStaticBarInterfaceFactory
{
public BarInterface getInstance()
{
return new BarInterfaceImpl();
}
}
spring配置如下:
<bean id="barFactory" class="...NoStaticBarInterfaceFactory" />
<bean id="bar" factory-bean="barFactory" factory-method="getInstance" />
FactoryBean:spring 提供的生產對象的工廠bean
只需要實現org.springframework.beans.factory.FactoryBean 接口
public interface FactoryBean{
//獲取實例
Object getObject() throws Exception;
//獲取實現相對于的類型
Class getObjectType();
//表明獲取的實例在容器中是否是singleton形式
boolean isSingleton();
}
然后在spring 進行bean定義
<bean id="objectId" class="...FactoryBean"/>需要注意的是,這里的objectId不是
FactoryBean類型,而是上面實現接口的具體getObjectType的類型。
F.方法注入和方法替換。
方法替換實現org.springframework.beans.facotry.support.MethodReplacer
并在bean中定義
<replaced-method name="getAndPersistNews" replacer="providerReplacer"/>
<bean id="providerReplacer" class="...FXNewsReplacer">
其實方法替換就是對方法的攔截。
G.ApplicationContext特性
Resource:spring 定義統一的資源
ResourceLoader:有了資源,需要有加載工具。
ResourcePatternResolver:是ResourceLoader的擴展,resourceLoader每次只能根據
資源返回單個Resource實例,而ResourcePatternResolver可以一次返回多個Resource
[PHP]-register_globals使用詳解
2008年02月25日 星期一 20:12
register_globals是php.ini里的一個配置,這個配置影響到php如何接收傳遞過來的參數,如果你的問題是:為什么我的表單無法傳遞數據?為什么我的程序無法得到傳遞過來的變量?等等,那么你需要仔細的閱讀以下的內容。
register_globals的值可以設置為:On或者Off,我們舉一段代碼來分別描述它們的不同。
代碼:
<form name="frmTest" id="frmTest" action="URL">
<input type="text" name="user_name" id="user_name">
<input type="password" name="user_pass" id="user_pass">
<input type="submit" value="login">
</form>
當register_globals=Off的時候,下一個程序接收的時候應該用$_GET['user_name']和$_GET['user_pass']來接受傳遞過來的值。(注:當<form>的method屬性為post的時候應該用$_POST['user_name']和$_POST['user_pass'])
當register_globals=On的時候,下一個程序可以直接使用$user_name和$user_pass來接受值。
顧名思義,register_globals的意思就是注冊為全局變量,所以當On的時候,傳遞過來的值會被直接的注冊為全局變量直接使用,而Off的時候,我們需要到特定的數組里去得到它。所以,碰到上邊那些無法得到值的問題的朋友應該首先檢查一下你的register_globals的設置和你獲取值的方法是否匹配。(查看可以用phpinfo()函數或者直接查看php.ini)
那我們為什么要使用Off呢?原因有2:
1、php以后的新版本默認都用Off,雖然你可以設置它為On,但是當你無法控制服務器的時候,你的代碼的兼容性就成為一個大問題,所以,你最好從現在就開始用Off的風格開始編程
2、這里有兩篇文章介紹為什么要Off而不用On
http://www.linuxforum.net/forum/gshowflat.php?Cat=&Board=php3&Number=292803&page=0&view=collapsed&sb=5&o=all&fpart=
http://www.php.net/manual/en/security.registerglobals.php
現在還有一個問題就是,以前用On風格寫的大量腳本怎么辦?
如果你以前的腳本規劃得好,有個公共包含文件,比如config.inc.php一類的文件,在這個文件里加上以下的代碼來模擬一下(這個代碼不保證100%可以解決你的問題,因為我沒有大量測試,但是我覺得效果不錯)。另外,這個帖子里的解決方法也可以參考一下(http://www.chinaunix.net/forum/viewtopic.php?t=159284)。
代碼:
<?php
if ( !ini_get('register_globals') )
{
extract($_POST);
extract($_GET);
extract($_SERVER);
extract($_FILES);
extract($_ENV);
extract($_COOKIE);
if ( isset($_SESSION) )
{
extract($_SESSION);
}
}
?>
register_globals = Off的情況不僅僅影響到如何獲取從<form>、url傳遞過來的數據,也影響到session、cookie,對應的,得到session、cookie的方式應該為:$_SESSION[]、$_COOKIE。同時對于session的處理也有一些改變,比如,session_register()沒有必要而且失效,具體的變化,請查看php manual里的Session handling functions
$_REQUEST中間的內容實際上還是來源于$_GET $_POST $_COOKIE,缺點是無法判斷變量到底來自于get post 還是cookie,對要求比較嚴格的場合不適用。
php manual 寫到:
Variables provided to the script via the GET, POST, and COOKIE input mechanisms, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the PHP variables_order configuration directive.
|
一直以來,經??吹絁MX這個keyword,于是就想什么時候研究一下,看了半天的材料,看得云里霧里,大概的意思好像就是說,各式可以的系統
分布在任何地方,如何統一去管理,去監控,于是sun就引入了jmx的概念。
但是具體怎么,如何使用,心里不清楚,直接看jms spec很吃力,忽然之間想,可以先從現有的jmx 框架去一個個研究,或許就能慢慢理解他的含義。
首先選擇Jolokia:
http://www.jolokia.org。
他們的官方描述是:
Jolokia is a JMX-HTTP bridge giving an alternative to JSR-160 connectors. It is an agent based approach with support for many platforms. In addition to basic JMX operations it enhances JMX remoting with unique features like bulk requests or fine grained security policies.
廢話少說,先下載安裝再說。
在jolokia的Artifact 里面有面向不同框架方面的相關產品,
我下載了jolokia.war 他應該表示j2ee 應用服務,將 war部署到tomcat后
訪問http://127.0.0.1:8080/jolokia
發現輸出為
{"timestamp":1298621555,"status":200,"request":{"type":"version"},"value":{"protocol":"4.1","agent":"0.83","info":{"product":"tomcat","vendor":"Apache","version":"6.0.18"}}}
這是一串json字符串,里面是jmx信息,其中有我放入的容器是tomcat以及它的版本。
我想 如果我將war放入weblogic 或者其他j2ee 容器,應該對象的輸出會有相關的j2ee的信息。
Artifact里面還有osgi和jvm的,因為osgi不是很熟,暫時就不研究,那么在開始jvm對應的jar
研究jvm 首先要了解javaAgent 參數的含義,為此先補一下-javaAgent 參數的知識。
具體可以參考
http://i-giraffe.com/2010/12/javaagent-example/
這里簡要概括一下這個參數的含義,javaAgent 在main方法執行之前,執行agent的代碼;必須實現premain這個方法。
因為是在main之前執行,那么可以運用在不修改現有程序來增強或修改軟件,或者熱啟動等等。
接下來我們再回到jolokia jvm版本
首先我們下載這個jolokia_jvm_agent.jar 改為agent.jar, 下面我們需要寫一個java application;
代碼如下
public class FirstThread extends Thread{//繼承Thread重寫run方法
@Override
public void run(){
for (int i = 0; i < 300000; i++) {
System.out.println(i);
try {
Thread.sleep(100);//停100毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//////////////////main
public class MyProgram{
public static void main(String[] args) {
FirstThread fThread=new FirstThread();
fThread.start();
for (int i = 0; i < 300; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
我們打包為demo.jar
在cmd 命令下執行 java -javaagent:agent.jar -jar demo.jar
執行后我們訪問
http://127.0.0.1:8778/jolokia/
會出現json的jmx 信息
{"timestamp":1299226883,"status":200,"request":{"type":"version"},"value":{"protocol":"4.1","agent":"0.83","info":{}}}
這里需要注意兩點
如果我訪問
http://127.0.0.1:8778/jolokia 則會出現404
另外如果上面的線程循環很小,一會兒就結束了,那么這個時候再訪問就會找不到服務器。
另外agent的端口和host都可以通過參數來設定,具體可以查看jolokia jvm 相關的網頁。
到目前為止,jolokia for jvm也演示結束了。
-javaagent 這個JVM參數是JDK 5引進的.
java -help的幫助里面寫道:
-javaagent:<jarpath>[=<options>]
load Java programming language agent, see java.lang.instrument
JDK 工具文檔里面,并沒有很詳細的說明。
1. 代理 (agent) 是在你的main方法前的一個攔截器 (interceptor),也就是在main方法執行之前,執行agent的代碼。
agent的代碼與你的main方法在同一個JVM中運行,并被同一個system classloader裝載,被同一的安全策略 (security policy) 和上下文 (context) 所管理。
叫代理(agent)這個名字有點誤導的成分,它與我們一般理解的代理不大一樣。java agent使用起來比較簡單。
怎樣寫一個java agent? 只需要實現premain這個方法
public static void premain(String agentArgs, Instrumentation inst)
JDK 6 中如果找不到上面的這種premain的定義,還會嘗試調用下面的這種premain定義:
public static void premain(String agentArgs)
2. Agent 類必須打成jar包,然后里面的 META-INF/MAINIFEST.MF 必須包含 Premain-Class這個屬性。
下面是一個MANIFEST.MF的例子:
Manifest-Version: 1.0
Premain-Class:MyAgent1
Created-By:1.6.0_06
然后把MANIFEST.MF 加入到你的jar包中。
3. 所有的這些Agent的jar包,都會自動加入到程序的classpath中。所以不需要手動把他們添加到classpath。
除非你想指定classpath的順序。
4. 一個java程序中-javaagent這個參數的個數是沒有限制的,所以可以添加任意多個java agent。
所有的java agent會按照你定義的順序執行。
例如:
java -javaagent:MyAgent1.jar -javaagent:MyAgent2.jar -jar MyProgram.jar
假設MyProgram.jar里面的main函數在MyProgram中。
MyAgent1.jar, MyAgent2.jar, 這2個jar包中實現了premain的類分別是MyAgent1, MyAgent2
程序執行的順序將會是
MyAgent1.premain -> MyAgent2.premain -> MyProgram.main
5. 另外,放在main函數之后的premain是不會被執行的,
例如
java -javaagent:MyAgent1.jar -jar MyProgram.jar -javaagent:MyAgent2.jar
MyAgent2 和MyAgent3 都放在了MyProgram.jar后面,所以MyAgent2的premain都不會被執行,
所以執行的結果將是
MyAgent1.premain -> MyProgram.main
6. 每一個java agent 都可以接收一個字符串類型的參數,也就是premain中的agentArgs,這個agentArgs是通過java option中定義的。
如:
java -javaagent:MyAgent2.jar=thisIsAgentArgs -jar MyProgram.jar
MyAgent2中premain接收到的agentArgs的值將是”thisIsAgentArgs” (不包括雙引號)
7. 參數中的Instrumentation:
通過參數中的Instrumentation inst,添加自己定義的ClassFileTransformer,來改變class文件。
8. 通過java agent就可以不用修改原有的java程序代碼,通過agent的形式來修改或者增強程序了,或者做熱啟動等等。
9. JDK 6 中還增加了agentmain,
agentmain可以在JVM運行過程中做一些事情,這個遲點再研究一下。
上面我寫的例子可以在我的skydrive上面下載到:點擊下載例子
參考:
http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/lang/instrument/package-summary.html
http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html
http://javahowto.blogspot.com/2006/07/javaagent-option.html