(廢話)會議通第二回合讓我歡喜讓我憂......
(第一回合是從java讓我學做asp.net,暈了二三周....)
當然應該是先讓我憂.....
一大推的問題就擺在面前..
安裝不了...
安裝成功,登陸不了...
登陸進去,視頻顯示不了....
(怎么這么豆腐渣工程??)
原先會議通的服務器都是放在上家那里的,最近上家出了點問題,我們決定自己處理.
(此時,也讓我感覺到了求人不如求已呀...)
就這樣,我們開始了會議通服務器整頓....
上面的問題也就隨之席面而來...
在大家積極猜測下(最主要是在web.config和system.xml文件配置,一些.dll),我們把大部分問題解決了,至少可以面對面(視頻)聊了(開會啦).
接下來是一些小BUG處理啦..(結束)
回到點上了,
要這么實現:
在一個頁面里直接彈出進入會議體驗室,不再讓它彈出窗口...
可萬萬沒有想到,會議通服務端就是一直會location一個viewstate!!
我暈呀!昨天花一天的時間試著用form.submit再來location.href行不通.
<iframe src="#" name="mainfrm" width="0" height="0"></iframe>
<form name="Form_Reg" method="post" action="
<input type="hidden" name="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" value="" />
<input id="strMeetId" type="hidden" value="11" name="strMeetId">
<tr? height="36">?
?<td background="/impage/IM_image/tab_05.jpg" align="center"><input name="strNickName" type="text" value="<%=sUsrName%>" id="strNickName" class="input" style="width:100px;" /></td>
?<td background="/impage/IM_image/tab_05.jpg" align="center"><input type="submit" name="Button1" value="參加會議" id="Button1" style="width:80px;"/></td>
? </tr>
</form>
就在form的target設置iframe名稱就搞定了.
iframe學著多運用,其關鍵時作用不說你也知道,呵呵:)
窄告彈出一個空白頁(以下實現不讓空白頁出來,在本地來一個說明什么的.)
<%
?? String stUrl = (String)request.getAttribute("stUrl");
?? String stUsrnth = (String)request.getAttribute("usrnth");
?? String stPsw = (String)request.getAttribute("psw");
%>
<iframe src="<%=stUrl%>" width="0"
height="0" scrolling="no" frameborder="0" name="mainfrm" id="mainfrm"
onload="parent.location.href='impage/usr/suc_narrow_login.jsp?usrnth=<%=stUsrnth%>&psw=<%=stPsw%>'">
</iframe>
src:目標url設置
onload:實現目標url后本地url
在eclipse里設置了tomcat插件就可以BUG跟蹤了,更快發現BUG,解決BUG
一:當然,在本機要安裝上tomcat;
在tomcat安裝下conf/server.xml設置;
如:D:/eclipse/Tomcat5.0/conf
................
<Connector
port="9000"?????????????? maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
?????????????? enableLookups="false" redirectPort="8443" acceptCount="100"
?????????????? debug="0" connectionTimeout="20000"
?????????????? disableUploadTimeout="true" />
..................
<Logger className="org.apache.catalina.logger.FileLogger"
???????????????? directory="logs"? prefix="localhost_log." suffix=".txt"
??????????? timestamp="true"/>
??????? <Context path="" reloadable="true" docBase="D:\eclipse\wrk1\epc\epcweb"/>
????? </Host>
...........
注意:1. 設置port="9000"http://
??????????? 2.設置<Context path="" reloadable="true" docBase="D:\eclipse\wrk1\epc\epcweb"/>
????????????????????? //整個project工作路徑
二:下載tomcat插件 http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-129.html
三:將.zip釋放到eclipse的plugins,重新打開eclipse(安裝JDK后雙擊eclipse.exe),在工具欄上出現了start tomcat,stop tomcat,restart tomcat圖標
windows----->首選項----->Tomcat? 下設置
1.Tomcat version:?????? 選擇Tomcat版本
2.Tomcat home:????????? D:\eclipse\Tomcat5.0???? //tomcat的安裝路徑
3.Context declaration? mode選Server.xml
?? 其Configuration file:????????? D:\eclipse\Tomcat5.0\conf\server.xml? //(server.xml路徑)
Tomcat?雙擊下Advanced
Tomcat base:?????????? D:\eclipse\Tomcat5.0?????? //tomcat的安裝路徑
點擊"restart tomcat"圖標,啟完后在url上
http://localhost:9000/index.jsp
(在host 添加一條記錄127.0.0.1?????? localhost)
就可以正常訪問了,設置斷點,也就可以BUG跟蹤了。
環境變量path和classpath是什么東東
path是您用的操作系統提供的環境變量,
您一定試過在命令行輸入一個命令然后它就執行了,很好玩吧。你輸入的比如說是〉ffff,
可這個文件明明在D:/****/***/ffff.exe那個路徑下,在命令行中,不管在那個路徑下輸入都能執行呢,
這就是因為,再path中設置了這個路徑。
那classpath有什么作用呢?編java程序的時候都知道import的作用吧!
當要用的class,在某一個.jar下是,你需要在編譯時引入,jvm自動去找classpath環境變量引入下面的jar包,
這就是classpath環境變量的作用
Path=.;C:\j2sdk1.4.2_05\bin;D:\DownLoads\oracle\bin;D:\DownLoads\oracle\Apache\Perl\5.00503\bin\mswin32-x86;C:\Program Files\Oracle\jre\1.1.7\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;D:\DownLoads;C:\Program Files\Symantec\pcAnywhere\;C:\Program Files\Microsoft SQL Server\80\Tools\BINN
JAVA_HOME=C:\j2sdk1.4.2_05
CLASSPATH=.\;%JAVA_HOME%\lib\tools.jar
(Path沒有用到JAVA_HOME變量)
五個小故事,告訴你遇事不要只看表象。思而后行,行必善焉。
1、 情況不同
一只小豬、一只綿羊和一頭乳牛,被關在同一個畜欄里。有一次,牧人捉住小豬,大聲號叫,猛烈地抗拒。綿羊和乳牛討厭的號叫,便說:「他常常捉我們,我們并不大呼小叫。小豬聽了回答道:「捉你們和捉我完全是兩回事,他捉你們,只是要你們的毛和乳汁,但是捉住我,卻是要我的命呢!立場不同、所處環境不同的人,很難了解對方的感受;因此對別人的失意、挫折、傷痛,不宜幸災樂禍,而應要有關懷、了解的心情。要有寬容的心!
2、 靠自己
小蝸牛問媽媽:為什么我們從生下來,就要背負這個又硬又重的殼呢?
媽媽:因為我們的身體沒有骨骼的支撐,只能爬,又爬不快。所以要這個殼的保護!
小蝸牛:毛蟲姊姊沒有骨頭,也爬不快,為什么她卻不用背這個又硬又重的殼呢?
媽媽:因為毛蟲姊姊能變成蝴蝶,天空會保護她啊。
小蝸牛:可是蚯蚓弟弟也沒骨頭爬不快,也不會變成蝴蝶他什么不背這個又硬又重的殼呢?
媽媽:因為蚯蚓弟弟會鉆土, 大地會保護他啊。
小蝸??蘖似饋恚何覀兒每蓱z,天空不保護,大地也不保護。
蝸牛媽媽安慰他:「所以我們有殼?。 刮覀儾豢刻?,也不靠地,我們靠自己。
3、 鯊魚與魚
曾有人做過實驗,將一只最兇猛的鯊魚和一群熱帶魚放在同一個池子,然后用強化玻璃隔開,最初,鯊魚每天不斷沖撞那塊看不到的玻璃,耐何這只是徒勞,它始終不能過到對面去,而實驗人員每天都有放一些鯽魚在池子里,所以鯊魚也沒缺少獵物,只是它仍想到對面去,想嘗試那美麗的滋味,每天仍是不斷的沖撞那塊玻璃,它試了每個角落,每次都是用盡全力,但每次也總是弄的傷痕累累,有好幾次都渾身破裂出血,持續了好一些日子,每當玻璃一出現裂痕,實驗人員馬上加上一塊更厚的玻璃。后來,鯊魚不再沖撞那塊玻璃了,對那些斑斕的熱帶魚也不再在意,好像他們只是墻上會動的壁畫,它開始等著每天固定會出現的鯽魚,然后用他敏捷的本能進行狩獵,好像回到海中不可一世的兇狠霸氣,但這一切只不過是假像罷了,實驗到了最后的階段,實驗人員將玻璃取走,但鯊魚卻沒有反應,每天仍是在固定的區域游著它不但對那些熱帶魚視若無睹,甚至于當那些鯽魚逃到那邊去,他就立刻放棄追逐,說什么也不愿再過去,實驗結束了,實驗人員譏笑它是海里最懦弱的魚。
可是失戀過的人都知道為什么,它怕痛。
4、 神跡
法國一個偏僻的小鎮,據傳有一個特別靈驗的水泉,常會出現神跡,可以醫治各種疾病。有一天,一個拄著拐杖,少了一條腿的退伍軍人,一跛一跛的走過鎮上的馬路,旁邊的鎮民帶著同情的回吻說:「可憐的家伙,難道他要向上帝祈求再有一條腿嗎??」這一句話被退伍的軍人聽到了,他轉過身對他們說:「我不是要向上帝祈求有一條新的腿,而是要祈求幫助我,叫我沒有一條腿后,也知道如何過日子。」試想:學習為所失去的感恩,也接納失去的事實,不管人生的得與失,總是要讓自已的生命充滿了亮麗與光彩,不再為過去掉淚,努力的活出自己的生命。
5、 釣竿
有個老人在河邊釣魚,一個小孩走過去看他釣魚,老人技巧純熟,所以沒多久就釣上了滿簍的魚,老人見小孩很可愛,要把整簍的魚送給他,小孩搖搖頭,老人驚異的問道:「你為何不要?」小孩回答:「我想要你手中的釣竿。」老人問:「你要釣竿做什么?」小孩說:「這簍魚沒多久就吃完了,要是我有釣竿,我就可以自己釣,一輩子也吃不完?!刮蚁肽阋欢〞f:好聰明的小孩。錯了,他如果只要釣竿,那他一條魚也吃不到。因為,他不懂釣魚的技巧,光有魚竿是沒用的,因為釣魚重要的不在<釣竿>,而在<釣技>有太多人認為自己擁有了人生道上的釣竿,再也無懼于路上的風雨,如此,難免會跌倒于泥濘地上。就如小孩看老人,以為只要有釣竿就有吃不完的魚,像職員看老板,以為只要坐在辦公室,就有滾進的財源。
這方面特別適合于技術開發人員.
當你遇到難解問題,不防換個角度想想,問題可能就迎刃而解,領悟更是多多
模擬鍵盤Ctrl-V
window.clipboardData.getData("Text");
java調用.dll
編寫java程序如:javacall.java
編譯java程序,如將javacall.java放到c:\test下(都可以,沒有固定) javac javacall.java
(當然你要設置環境變量:path
設置:
我的電腦-屬性-高級-環境變量中,有PATH(大小寫都
可以)這個變量(沒有就自己新建立一個)
變量名:PATH
變量值:javac等程序所在路徑.
例如我的JDK安裝在D:\JDK1.4中,那么我在D:\JDK1.4目錄
下可以搜索一下javac,得到它的位置:D:\JDK1.4\jdk\bin,
現在變量值就可以寫成
變量值:[ .;D:\JDK1.4\jdk\bin; ]
或者先設置用戶變量,系統變量再調用
在桌面上右鍵點擊“我的電腦”
然后屬性->高級->環境變量 ->系統變量(用戶變量也可以)->新建變量名里面輸入JAVA_HOME;
變量值里面輸入D:\JDK1.4\jdk\
然后再新建一個CLASSPATH
其值為:
.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar (最前面的.;一定要寫)
)
生成頭文件(javacall.h) javah -classpath "c:\test" javacall (記得要寫上路徑)
建立新DLL工程如:mycalldll(如放在:C:\Documents and Settings\Administrator\桌面\71info\)
將javacall.h復制到VC工程目錄中(如:C:\Documents and Settings\Administrator\桌面\71info\mycalldll\mycalldll\),然后編譯,如果編譯說找不到jni.h文件,可以將jni.h復制到工程目錄中,還可將javacall.h文件中的#include <jni.h>改為#include "jni.h",
將生成的.dll(如C:\Documents and Settings\Administrator\桌面\71info\mycalldll\mycalldll\Debug\mycalldll.dll)復制到C:\j2sdk1.4.2_05\bin則可在eclipse運行了
index.jsp
<%@ page contentType="text/html;charset=gb2312"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body >
<br>
<a href="<%=gateway.payment.payment.CreateUrl()%>"><img src="images/alipay_bwrx.gif" border="0"></a>
</body>
</html>
alipay_notify.jsp
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.util.*"%>
<%request.setCharacterEncoding("gb2312");
???String partner = ""; //partner合作伙伴id(必須填寫)
???String privateKey = ""; //partner 的對應交易安全校驗碼(必須填寫)
???String alipayNotifyURL = "?????+ "&partner="
?????+ partner
?????+ "¬ify_id="
?????+ request.getParameter("notify_id");
???//獲取支付寶ATN返回結果,true是正確的訂單信息,false 是無效的
???//如果你的服務器不支持https訪問的話,需要用老的接口查詢地址了,論壇上會公布
???String responseTxt = gateway.checkURL.checkURL
?????.check(alipayNotifyURL);
???Map params = new HashMap();
???//獲得POST 過來參數設置到新的params中
???Map requestParams = request.getParameterMap();
???for (Iterator iter = requestParams.keySet().iterator(); iter
?????.hasNext();) {
????String name = (String) iter.next();
????String[] values = (String[]) requestParams.get(name);
????String valueStr = "";
????for (int i = 0; i < values.length; i++) {
?????valueStr = (i == values.length - 1) ? valueStr + values[i]
???????: valueStr + values[i] + ",";
?????//valueStr = valueStr + values[i];
????}
????params.put(name, valueStr);
???}
???
???String mysign = com.alipay.util.SignatureHelper.sign(params, privateKey);
???
???//out.println(mysign+"-----"+request.getParameter("sign"));
???if (mysign.equals(request.getParameter("sign")) || responseTxt.equals("true")? ){
????
????out.println("success");
??}
??%>
retrun_url.jsp
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.util.*"%>
<%request.setCharacterEncoding("gb2312");
???//String partner = ""; //partner合作伙伴id(必須填寫)
???String privateKey = ""; //partner 的對應交易安全校驗碼(必須填寫)
??//?String alipayNotifyURL = "???//??+ "&partner="
???//??+ partner
???//??+ "¬ify_id="
???//??+ request.getParameter("notify_id");
???//獲取支付寶ATN返回結果,true是正確的訂單信息,false 是無效的
???//String responseTxt = gateway.checkURL.checkURL
???//??.check(alipayNotifyURL);
??????????? //由于return url的返回通知,notifyid為空,無法到服務器查詢真假,所以只要比對簽名就好
???
???
???Map params = new HashMap();
???//獲得POST 過來參數設置到新的params中
???Map requestParams = request.getParameterMap();
???for (Iterator iter = requestParams.keySet().iterator(); iter
?????.hasNext();) {
????String name = (String) iter.next();
????String[] values = (String[]) requestParams.get(name);
????String valueStr = "";
????for (int i = 0; i < values.length; i++) {
?????valueStr = (i == values.length - 1) ? valueStr + values[i]
???????: valueStr + values[i] + ",";
?????//valueStr = valueStr + values[i];
????}
????params.put(name, valueStr);
???}
???
???String mysign = com.alipay.util.SignatureHelper_return.sign(params, privateKey);
???
???//out.println(mysign+"-----"+request.getParameter("sign"));
???if (mysign.equals(request.getParameter("sign"))? ){
????
????
????if (request.getParameter("trade_status").equalsIgnoreCase("TRADE_FINISHED")){
??????????? //?可以做重定向,也可以用來虛擬物品發貨
????}
????
??}
??%>
SignatureHelper.java
package com.alipay.util;
import gateway.md5.Md5Encrypt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class SignatureHelper {
?public static String sign(Map params, String privateKey) {
??Properties properties = new Properties();
??for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
???String name = (String) iter.next();
???Object value = params.get(name);
???if (value == null) {
????continue;
???}
???if (name == null || name.equalsIgnoreCase("sign")
?????|| name.equalsIgnoreCase("sign_type")) {
????continue;
???}
???properties.setProperty(name, value.toString());
??}
??String content = getSignatureContent(properties);
??return sign(content, privateKey);
?}
?@SuppressWarnings("unchecked")
?public static String getSignatureContent(Properties properties) {
??StringBuffer content = new StringBuffer();
??List keys = new ArrayList(properties.keySet());
??Collections.sort(keys);
??for (int i = 0; i < keys.size(); i++) {
???String key = (String) keys.get(i);
???String value = properties.getProperty(key);
???content.append((i == 0 ? "" : "&") + key + "=" + value);
??}
??return content.toString();
?}
?public static String sign(String content, String privateKey) {
??if (privateKey == null) {
???return null;
??}
??String signBefore = content + privateKey;
??// System.out.print(Md5Encrypt.md5(signBefore));
??return Md5Encrypt.md5(signBefore);
?}
}
SignatureHelper_return.java
package com.alipay.util;
import gateway.md5.Md5Encrypt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class SignatureHelper_return {
?public static String sign(Map params, String privateKey) {
??Properties properties = new Properties();
??for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
???String name = (String) iter.next();
???Object value = params.get(name);
???if (value == null) {
????continue;
???}
???if ( name.equalsIgnoreCase("sign")
?????|| name.equalsIgnoreCase("sign_type")) {
????continue;
???}
???properties.setProperty(name, value.toString());
??}
??String content = getSignatureContent(properties);
??return sign(content, privateKey);
?}
?@SuppressWarnings("unchecked")
?public static String getSignatureContent(Properties properties) {
??StringBuffer content = new StringBuffer();
??List keys = new ArrayList(properties.keySet());
??Collections.sort(keys);
??for (int i = 0; i < keys.size(); i++) {
???String key = (String) keys.get(i);
???String value = properties.getProperty(key);
???content.append((i == 0 ? "" : "&") + key + "=" + value);
??}
??return content.toString();
?}
?public static String sign(String content, String privateKey) {
??if (privateKey == null) {
???return null;
??}
??String signBefore = content + privateKey;
??// System.out.print(Md5Encrypt.md5(signBefore));
??return Md5Encrypt.md5(signBefore);
?}
?
?
?
}
checkURL.java
?
package gateway.checkURL;
import java.net.*;
import java.io.*;
public class checkURL {
??? /**
???? * 對字符串進行MD5加密
? * @param myUrl
???? *
???? * @param url
???? *
???? * @return 獲取url內容
???? */
? public static String check(String urlvalue ) {
?
?? String inputLine = "";
??try
??{
???URL url = new URL(urlvalue);
???
???HttpURLConnection urlConnection? = (HttpURLConnection)url.openConnection();
???
???BufferedReader in? = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
??
???String stTemp = "";
???????? while((stTemp = in.readLine()) != null)
???????? {
??????????? System.out.println(stTemp);
??????????? inputLine = inputLine + stTemp;
???????? }
??}
??catch(Exception e)
??{
???e.printStackTrace();
??}
??return inputLine;
?}
? }
Md5Encrypt.java
/**
?* Alipay.com Inc. Copyright (c) 2004-2005 All Rights Reserved.
?*
?* <p>
?* Created on 2005-7-9
?* </p>
?*/
?package gateway.md5;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
?* MD5加密算法
?*/
public class Md5Encrypt {
??? /**
???? * 對字符串進行MD5加密
???? *
???? * @param text 明文
???? *
???? * @return 密文
???? */
??? public static String md5(String text) {
??????? MessageDigest msgDigest = null;
??????? try {
??????????? msgDigest = MessageDigest.getInstance("MD5");
??????? } catch (NoSuchAlgorithmException e) {
??????????? throw new IllegalStateException("System doesn't support MD5 algorithm.");
??????? }
??????? msgDigest.update(text.getBytes());
??????? byte[] bytes = msgDigest.digest();
??????? byte?? tb;
??????? char?? low;
??????? char?? high;
??????? char?? tmpChar;
??????? String md5Str = new String();
??????? for (int i = 0; i < bytes.length; i++) {
??????????? tb = bytes[i];
??????????? tmpChar = (char) ((tb >>> 4) & 0x000f);
??????????? if (tmpChar >= 10) {
??????????????? high = (char) (('a' + tmpChar) - 10);
??????????? } else {
??????????????? high = (char) ('0' + tmpChar);
??????????? }
??????????? md5Str += high;
??????????? tmpChar = (char) (tb & 0x000f);
??????????? if (tmpChar >= 10) {
??????????????? low = (char) (('a' + tmpChar) - 10);
??????????? } else {
??????????????? low = (char) ('0' + tmpChar);
??????????? }
??????????? md5Str += low;
??????? }
??????? return md5Str;
??? }
}
payment.java
package gateway.payment;
import java.util.*;
public class payment {
?
?
??
?public static String CreateUrl()
????? {??
?
??? Date out_trade_no=new Date();
??? String paygateway????=?"??? String service = "create_direct_pay_by_user";
??? String partner???=?"";??//partner合作伙伴ID(必填)
??? String sign_type?????? =?? "MD5";
??? String subject = "訂單號:" + out_trade_no;??//subject??商品名稱
??? String body = "交易地點總價包含郵費";??//body???商品描述
??? String price????? =?"100";????//price???商品單價???0.01~50000.00
??? String show_url??????? =?? "??? String quantity??????? =?? "1";
??? String payment_type??? =?? "1";
??? String logistics_type? =?? "EXPRESS";//logistic為物流信息
??? String logistics_fee?? =?? "2";
??? String logistics_payment? =?? "SELLER_PAY";
??? String logistics_type_1? =?? "EMS";
??? String logistics_fee_1?? =?? "4";
??? String logistics_payment_1? =?? "SELLER_PAY";
??? String seller_email??? =??? "";???????????? //賣家賬號(必填)
??? String key???????????? =??? "";????????????? //partner賬戶的支付寶安全校驗碼(必填)
??? String notify_url????? =??? "
???
??
??? String[] Oristr ={ "service="+service, "partner=" + partner, "subject=" + subject, "body=" + body, "out_trade_no=" + out_trade_no, "price=" + price, "show_url=" + show_url, "quantity=" + quantity, "payment_type=" + payment_type, "logistics_type=" + logistics_type, "logistics_fee=" + logistics_fee, "logistics_payment=" + logistics_payment, "logistics_type_1=" + logistics_type_1, "logistics_fee_1=" + logistics_fee_1, "logistics_payment_1=" + logistics_payment_1, "seller_email=" + seller_email, "notify_url=" + notify_url };
??? ???? ??????
??????? Arrays.sort(Oristr);//Sorts the specified array of objects into ascending order
?????????? ???? ?????//according to the natural ordering of its elements.
??????
????????? String prestr="";
?????????
????????? for (int i = 0; i < Oristr.length; i++)
???????????? {
???????????????? if (i==Oristr.length-1)
???????????????? {
???????????????????? prestr = prestr + Oristr[i] ;
???????????????? }
???????????????? else
???????????????? {
???????????????????? prestr = prestr + Oristr[i] + "&";
???????????????? }
?????????????????
???????????? }
????????? ?prestr = prestr + key;
???????????? //生成Md5摘要;
???????????? String sign = gateway.md5.Md5Encrypt.md5(prestr);
????????????
???????????? //構造支付Url;
???????????? String parameter = "";
???????????? parameter = parameter + paygateway;
???????????? for (int i = 0; i < Oristr.length; i++)
???????????? {
???????????????? parameter = parameter + Oristr[i] + "&";??????????????
???????????? }
???????????? parameter = parameter + "sign=" + sign + "&sign_type=" + sign_type;
???????????? //返回支付Url;
???????????? return parameter;
???
?
????? }
}
注意:
包的位置,
參數排序是以字母的排序排的
資料由支付寶轉載:
下載地址:http://www.blive.cn/liuz/download/new_jsp_xuni.rar
摘 要 JSSE是一個SSL和TLS的純Java實現,通過JSSE可以很容易地編程實現對HTTPS站點的訪問。但是,如果該站點的證書未經權威機構的驗證,JSSE將拒絕信任該證書從而不能訪問HTTPS站點。本文在簡要介紹JSSE的基礎上提出了兩種解決該問題的方法。
引言
過去的十幾年,網絡上已經積累了大量的Web應用。如今,無論是整合原有的Web應用系統,還是進行新的Web開發,都要求通過編程來訪問某些Web頁面。傳統的方法是使用Socket接口,但現在很多開發平臺或工具如.NET、Java或PHP等都提供了簡單的Web訪問接口,使用這些接口很容易編程實現與Web應用系統的交互訪問,即使要訪問那些采用了HTTPS而不是HTTP的Web應用系統。
HTTPS,即安全的超文本傳輸協議,采用了SSL技術,被廣泛使用以保證Web應用系統的安全性。訪問Web應用的編程接口大多封裝了SSL,使得訪問HTTPS和訪問HTTP一樣簡單。但是很多中、小型應用系統或基于局域網、校園網的應用系統所使用的證書并不是由權威的認證機構發行或者被其驗證,直接使用這些編程接口將不能訪問HTTPS。
本文將在簡要介紹JSSE的基礎上,詳細描述使用JSSE訪問HTTPS的方法,主要說明了如何訪問帶有未經驗證證書的HTTPS站點。
JSSE簡介
Java安全套接擴展 (Java Secure Socket Extension, JSSE)是實現Internet安全通信的一系列包的集合。它是一個SSL和TLS的純Java實現,可以透明地提供數據加密、服務器認證、信息完整性等功能,可以使我們像使用普通的套接字一樣使用JSSE建立的安全套接字。JSSE是一個開放的標準,不只是Sun公司才能實現一個JSSE,事實上其他公司有自己實現的JSSE。
在深入了解JSSE之前,需要了解一個有關Java安全的概念:客戶端的TrustStore文件??蛻舳说腡rustStore文件中保存著被客戶端所信任的服務器的證書信息。客戶端在進行SSL連接時,JSSE將根據這個文件中的證書決定是否信任服務器端的證書。
JSSE中,有一個信任管理器類負責決定是否信任遠端的證書,這個類有如下的處理規則:
?、?果系統屬性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安裝路徑下的lib/security/目錄中尋找并使用這個文件來檢查證書。
?、?果該系統屬性沒有指定TrustStore文件,它就會去jre安裝路徑下尋找默認的TrustStore文件,這個文件的相對路徑為:lib/security/jssecacerts。
?、?如果 jssecacerts不存在,但是cacerts存在(它隨J2SDK一起發行,含有數量有限的可信任的基本證書),那么這個默認的TrustStore文件就是cacerts。
直接使用類HttpsURLConnection訪問Web頁面
Java提供了一種非常簡潔的方法來訪問HTTPS網頁,即使用類HttpsURLConnection、URL等。這幾個類為支持HTTPS對JSSE相關類做了進一步的封裝,例子如下所示:
URL reqURL = new URL("https://www.sun.com" ); //創建URL對象 HttpsURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection();
/*下面這段代碼實現向Web頁面發送數據,實現與網頁的交互訪問 httpsConn.setDoOutput(true); OutputStreamWriter out = new OutputStreamWriter(huc.getOutputStream(), "8859_1"); out.write( "……" ); out.flush(); out.close(); */
//取得該連接的輸入流,以讀取響應內容 InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream();
//讀取服務器的響應內容并顯示 int respInt = insr.read(); while( respInt != -1){ System.out.print((char)respInt); respInt = insr.read(); } |
這段代碼能夠正常執行,然而把訪問的URL改為https://login.bjut.edu.cn時,程序將拋出異常javax.net.ssl.SSLException,這是由于https://login.bjut.edu.cn站點的安全證書不被JSSE所信任。根據JSSE簡介中對信任管理器的分析,一種解決這個問題的方法是按照信任管理器的處理規則,把站點的證書放到證書庫文件jssecacerts中,或者把證書存放到任一TrustStore文件中,然后設置系統屬性javax.net.sll.trustStore指向該文件。另一種解決方法則是自己實現信任管理器類,讓它信任我們指定的證書。下面分別介紹這兩種方法。
將證書導入到TrustStore文件中 Java提供了命令行工具keytool用于創建證書或者把證書從其它文件中導入到Java自己的TrustStore文件中。把證書從其它文件導入到TrustStore文件中的命令行格式為:
keytool -import -file src_cer_file –keystore dest_cer_store
其中,src_cer_file為存有證書信息的源文件名,dest_cer_store為目標TrustStore文件。
在使用keytool之前,首先要取得源證書文件,這個源文件可使用IE瀏覽器獲得,IE瀏覽器會把訪問過的HTTPS站點的證書保存到本地。從IE瀏覽器導出證書的方法是打開“Internet 選項”,選擇“內容”選項卡,點擊“證書…”按鈕,在打開的證書對話框中,選中一個證書,然后點擊“導出…”按鈕,按提示一步步將該證書保存到一文件中。最后就可利用keytool把該證書導入到Java的TrustStore文件中。為了能使Java程序找到該文件,應該把這個文件復制到jre安裝路徑下的lib/security/目錄中。
這樣,只需在程序中設置系統屬性javax.net.sll.trustStore指向文件dest_cer_store,就能使JSSE信任該證書,從而使程序可以訪問使用未經驗證的證書的HTTPS站點。
使用這種方法,編程非常簡單,但需要手工導出服務器的證書。當服務器證書經常變化時,就需要經常進行手工導出證書的操作。下面介紹的實現X509證書信任管理器類的方法將避免手工導出證書的問題。
X509證書信任管理器類的實現及應用
在JSSE中,證書信任管理器類就是實現了接口X509TrustManager的類。我們可以自己實現該接口,讓它信任我們指定的證書。
接口X509TrustManager有下述三個公有的方法需要我們實現:
?、?oid checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException
該方法檢查客戶端的證書,若不信任該證書則拋出異常。由于我們不需要對客戶端進行認證,因此我們只需要執行默認的信任管理器的這個方法。JSSE中,默認的信任管理器類為TrustManager。
?、?oid checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException
該方法檢查服務器的證書,若不信任該證書同樣拋出異常。通過自己實現該方法,可以使之信任我們指定的任何證書。在實現該方法時,也可以簡單的不做任何處理,即一個空的函數體,由于不會拋出異常,它就會信任任何證書。
?、?X509Certificate[] getAcceptedIssuers()
返回受信任的X509證書數組。
自己實現了信任管理器類,如何使用呢?類HttpsURLConnection似乎并沒有提供方法設置信任管理器。其實,HttpsURLConnection通過SSLSocket來建立與HTTPS的安全連接,SSLSocket對象是由SSLSocketFactory生成的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)設置它使用的SSLSocketFactory對象。SSLSocketFactory通過SSLContext對象來獲得,在初始化SSLContext對象時,可指定信任管理器對象。下面用一個圖簡單表示這幾個JSSE類的關系:
 圖1 部分JSSE類的關系圖 |
假設自己實現的X509TrustManager類的類名為:MyX509TrustManager,下面的代碼片斷說明了如何使用MyX509TrustManager:
//創建SSLContext對象,并使用我們指定的信任管理器初始化 TrustManager[] tm = {new MyX509TrustManager ()}; SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom());
//從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory();
//創建HttpsURLConnection對象,并設置其SSLSocketFactory對象 HttpsURLConnection httpsConn = (HttpsURLConnection)myURL.openConnection(); httpsConn.setSSLSocketFactory(ssf); |
這樣,HttpsURLConnection對象就可以正常連接HTTPS了,無論其證書是否經權威機構的驗證,只要實現了接口X509TrustManager的類MyX509TrustManager信任該證書。
小結 本文主要介紹了在HTTPS的證書未經權威機構認證的情況下,訪問HTTPS站點的兩種方法,一種方法是把該證書導入到Java的TrustStore文件中,另一種是自己實現并覆蓋JSSE缺省的證書信任管理器類。兩種方法各有優缺點,第一種方法不會影響JSSE的安全性,但需要手工導入證書;第二種方法雖然不用手工導入證書,但需要小心使用,否則會帶來一些安全隱患。
Use SQL for ODBC 1.0 是一款通過ODBC執行SQL軟件。
軟件特點:
本軟件可以保存連接配置。
本軟件可以執行多條SQL。
本軟件可以在SQL中嵌入命令。
本軟件可以導出Excel數據。
本軟件包含數據轉換工具。
本軟件可以查看數據庫的表及表項目。

網址:
http://sqlforodbc.nease.net/
http://sqlforodbc.icpcn.com
下載地址
http://sqlforodbc.nease.net/usqlsetup.exe
http://sqlforodbc.go3.icpcn.com/usqlsetup.exe
ORACLE數據庫常用操作
對于DBA來講,熟悉ORACLE的常用操作方法有很重要的作用,下面列舉幾個方面的:
一、 Oracle 數據庫的幾個關閉方法
對于ORACLE來講,關閉的方法有三個:
在SVRMGRL下可以輸入如下語句,就可關閉數據庫,但每個語句都有自己的作用,有的語句還必須慎重使用
1、shutdown normal (從字面就可理解這是一個用正常的方式來關閉數據庫。)
2、shutdown immediate (立即方式關閉數據庫。)
當執行shutdown immediate時,數據庫并不立即關閉,而是在Oracle執行完內部的必要的工作后才關閉,shutdown immediate可以完成shutdown不能對數據庫關閉的操作。建議DBA們常用此方法關閉數據庫
3、shutdown abort (直接關閉數據庫)
這個停止的方法不推薦,因為對于正在訪問數據庫的會話會被突然終止,可能會造成數據庫的數據丟失,并且如果數據庫中有大量操作正在執行,這時執行shutdown abort后,重新啟動數據庫需要很長時間。
舉例說明:
1、停Oracle
# su – oracle
$ lsnrctl stop
$ svrmgrl
>connectinternal
>shutdown immediate
>exit
相應的啟動Oracle的方法如下:
# su – oracle 以ORACLE用戶身份進入
$ svrmgrl 打開ORACLE的管理器
>connectinternal 建立庫的連接
>startup 啟動數據庫
>exit 退出管理器
$ lsnrctl start 啟動監聽
$lsnrctl status 查看監聽的狀態
二、對 Oracle 8i 數據庫服務器操作的一些相關命令和方法:
1、sar此命令可以幫助查看哪些緩沖區高速緩存使用情況,讓我們決定哪些需要增加,哪些需要減少:
sar -b:我們可用它查看緩沖區高速緩存的活動;
sar -w:我們可用它查看內存交換活動;
sar -u:我們可用它查看CPU利用情況;
sar -r:我們可用它查看內存利用情況;
sar -p:報告Solaris內存分頁活動,此命令是:vmstat命令的一部份功能,
比如下面命令用于每5秒顯示10次分頁活動的概要情況:
$ sar -p 5 10
% vmstat 5
此命令將顯示系統每5秒鐘做的事的概要,包括進程、虛擬內存、磁盤、分頁和CPU的活動情況。
2、iostat,可監控磁盤的活動情況
3、swap,可監控交換空間的情況
以下是轉帖:
Tomcat 的數據庫連接池設置與應用
|
|
1.將數據庫驅動程序的JAR文件放在Tomcat的 common/lib 中;
2.在server.xml中設置數據源,以MySQL數據庫為例,如下: 在<GlobalNamingResources> </GlobalNamingResources>節點中加入, <Resource name="jdbc/DBPool" type="javax.sql.DataSource" password="root" driverClassName="com.mysql.jdbc.Driver" maxIdle="2" maxWait="5000" username="root" url="jdbc:mysql://127.0.0.1:3306/test" maxActive="4"/> 屬性說明:name,數據源名稱,通常取”jdbc/XXX”的格式; type,”javax.sql.DataSource”; password,數據庫用戶密碼; driveClassName,數據庫驅動; maxIdle,最大空閑數,數據庫連接的最大空閑時間。超過空閑時間,數據庫連 接將被標記為不可用,然后被釋放。設為0表示無限制。 MaxActive,連接池的最大數據庫連接數。設為0表示無限制。 maxWait ,最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示 無限制。
3.在你的web應用程序的web.xml中設置數據源參考,如下: 在<web-app></web-app>節點中加入, <resource-ref> <description>MySQL DB Connection Pool</description> <res-ref-name>jdbc/DBPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> 子節點說明: description,描述信息; res-ref-name,參考數據源名字,同上一步的屬性name; res-type,資源類型,”javax.sql.DataSource”; res-auth,”Container”; res-sharing-scope,”Shareable”;
4.在web應用程序的context.xml中設置數據源鏈接,如下: 在<Context></Context>節點中加入, <ResourceLink name="jdbc/DBPool" type="javax.sql.DataSource" global="jdbc/DBPool"/> 屬性說明:name,同第2步和第3步的屬性name值,和子節點res-ref-name值; type,同樣取”javax.sql.DataSource”; global,同name值。 至此,設置完成,下面是如何使用數據庫連接池。 1.建立一個連接池類,DBPool.java,用來創建連接池,代碼如下: import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource;
public class DBPool { private static DataSource pool; static { Context env = null; try { env = (Context) new InitialContext().lookup("java:comp/env"); pool = (DataSource)env.lookup("jdbc/DBPool"); if(pool==null) System.err.println("'DBPool' is an unknown DataSource"); } catch(NamingException ne) { ne.printStackTrace(); } } public static DataSource getPool() { return pool; } }
2.在要用到數據庫操作的類或jsp頁面中,用DBPool.getPool().getConnection(), 獲得一個Connection對象,就可以進行數據庫操作, 最后別忘了對Connection對象調用close()方法, 注意:這里不會關閉這個Connection,而是將這個Connection放回數據庫連接池。
也是可以直接連的: 如連接oracle public class ConnectionProvider { public static DataSource ds;
static { DriverAdapterCPDS cpds = new DriverAdapterCPDS();
try { cpds.setDriver("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { String msg = "Could not find driver in the classpath "; System.out.println(msg); throw new RuntimeException(msg); } cpds.setUrl("jdbc:oracle:thin:@192.168.0.167:1521:epcora"); cpds.setUser("71c"); cpds.setPassword("123456");
Jdbc2PoolDataSource tds = new Jdbc2PoolDataSource(); tds.setConnectionPoolDataSource(cpds); tds.setDefaultMaxActive(20); tds.setDefaultMaxWait(50); ds = tds; } } 這樣就不用在server.xml,web.xml設置了。
還是若用eclipse跟蹤bug,設置連接數據庫則須在“Java構建路徑”-“庫”里添加上 數據庫驅動程序的JAR文件即可。
|
以下是轉貼:
談談Java語言的垃圾收集器
? ?垃圾收集器是Java語言區別于其他程序設計語言的一大特色。它把程序員從手工回收內存空間的繁重工作中解脫了出來。在SUN公司的Java程序員(Java Programmer)認證考試中,垃圾收集器是必考的內容,一般最多可以占總分值的6%左右。但是由于SUN公司的Java Programming Language SL-275 課程的標準教材中,對有關垃圾收集器的內容只做了非常簡單的介紹,而另外的一些關于Java技術的書籍,比如《Java 2 核心技術》(Core Java 2)、《Java編程思想》(Thinking in Java)、《精通Java 2》等等,里面關于垃圾收集器的內容也幾乎沒有,或者只是簡單地提兩句,所以很多參加Java Programmer認證考試的中國考生,在垃圾收集器這一部分的得分都為0分(筆者曾認識一位SUN公司授權的中國Java培訓班的老師,其考試總分為89%,但垃圾收集器的部分竟然也為0分)。鑒于此,筆者總結了這個垃圾收集器的專題,希望對廣大Java技術的愛好者和準備認證考試的考生們有所幫助。
我們知道,許多程序設計語言都允許在程序運行期動態地分配內存空間。分配內存的方式多種多樣,取決于該種語言的語法結構。但不論是哪一種語言的內存分配方式,最后都要返回所分配的內存塊的起始地址,即返回一個指針到內存塊的首地址。
當已經分配的內存空間不再需要時,換句話說當指向該內存塊的句柄超出了使用范圍的時候,該程序或其運行環境就應該回收該內存空間,以節省寶貴的內存資源。
在C,C++或其他程序設計語言中,無論是對象還是動態配置的資源或內存,都必須由程序員自行聲明產生和回收,否則其中的資源將消耗,造成資源的浪費甚至死機。但手工回收內存往往是一項復雜而艱巨的工作。因為要預先確定占用的內存空間是否應該被回收是非常困難的!如果一段程序不能回收內存空間,而且在程序運行時系統中又沒有了可以分配的內存空間時,這段程序就只能崩潰。通常,我們把分配出去后,卻無法回收的內存空間稱為"內存滲漏體(Memory Leaks)"。
以上這種程序設計的潛在危險性在Java這樣以嚴謹、安全著稱的語言中是不允許的。但是Java語言既不能限制程序員編寫程序的自由性,又不能把聲明對象的部分去除(否則就不是面向對象的程序語言了),那么最好的解決辦法就是從Java程序語言本身的特性入手。于是,Java技術提供了一個系統級的線程(Thread),即垃圾收集器線程(Garbage Collection Thread),來跟蹤每一塊分配出去的內存空間,當Java 虛擬機(Java Virtual Machine)處于空閑循環時,垃圾收集器線程會自動檢查每一快分配出去的內存空間,然后自動回收每一快可以回收的無用的內存塊。
垃圾收集器線程是一種低優先級的線程,在一個Java程序的生命周期中,它只有在內存空閑的時候才有機會運行。它有效地防止了內存滲漏體的出現,并極大可能地節省了寶貴的內存資源。但是,通過Java虛擬機來執行垃圾收集器的方案可以是多種多樣的。
下面介紹垃圾收集器的特點和它的執行機制:
垃圾收集器系統有自己的一套方案來判斷哪個內存塊是應該被回收的,哪個是不符合要求暫不回收的。垃圾收集器在一個Java程序中的執行是自動的,不能強制執行,即使程序員能明確地判斷出有一塊內存已經無用了,是應該回收的,程序員也不能強制垃圾收集器回收該內存塊。程序員唯一能做的就是通過調用System. gc 方法來"建議"執行垃圾收集器,但其是否可以執行,什么時候執行卻都是不可知的。這也是垃圾收集器的最主要的缺點。當然相對于它給程序員帶來的巨大方便性而言,這個缺點是瑕不掩瑜的。
垃圾收集器的主要特點有:
1.垃圾收集器的工作目標是回收已經無用的對象的內存空間,從而避免內存滲漏體的產生,節省內存資源,避免程序代碼的崩潰。
2.垃圾收集器判斷一個對象的內存空間是否無用的標準是:如果該對象不能再被程序中任何一個"活動的部分"所引用,此時我們就說,該對象的內存空間已經無用。所謂"活動的部分",是指程序中某部分參與程序的調用,正在執行過程中,尚未執行完畢。
3.垃圾收集器線程雖然是作為低優先級的線程運行,但在系統可用內存量過低的時候,它可能會突發地執行來挽救內存資源。當然其執行與否也是不可預知的。
4.垃圾收集器不可以被強制執行,但程序員可以通過調用System. gc方法來建議執行垃圾收集器。
5.不能保證一個無用的對象一定會被垃圾收集器收集,也不能保證垃圾收集器在一段Java語言代碼中一定會執行。因此在程序執行過程中被分配出去的內存空間可能會一直保留到該程序執行完畢,除非該空間被重新分配或被其他方法回收。由此可見,完全徹底地根絕內存滲漏體的產生也是不可能的。但是請不要忘記,Java的垃圾收集器畢竟使程序員從手工回收內存空間的繁重工作中解脫了出來。設想一個程序員要用C或C++來編寫一段10萬行語句的代碼,那么他一定會充分體會到Java的垃圾收集器的優點!
6.同樣沒有辦法預知在一組均符合垃圾收集器收集標準的對象中,哪一個會被首先收集。
7.循環引用對象不會影響其被垃圾收集器收集。
8.可以通過將對象的引用變量(reference variables,即句柄handles)初始化為null值,來暗示垃圾收集器來收集該對象。但此時,如果該對象連接有事件監聽器(典型的 AWT組件),那它還是不可以被收集。所以在設一個引用變量為null值之前,應注意該引用變量指向的對象是否被監聽,若有,要首先除去監聽器,然后才可以賦空值。
9.每一個對象都有一個finalize( )方法,這個方法是從Object類繼承來的。
10.finalize( )方法用來回收內存以外的系統資源,就像是文件處理器和網絡連接器。該方法的調用順序和用來調用該方法的對象的創建順序是無關的。換句話說,書寫程序時該方法的順序和方法的實際調用順序是不相干的。請注意這只是finalize( )方法的特點。
11.每個對象只能調用finalize( )方法一次。如果在finalize( )方法執行時產生異常(exception),則該對象仍可以被垃圾收集器收集。
12.垃圾收集器跟蹤每一個對象,收集那些不可到達的對象(即該對象沒有被程序的任何"活的部分"所調用),回收其占有的內存空間。但在進行垃圾收集的時候,垃圾收集器會調用finalize( )方法,通過讓其他對象知道它的存在,而使不可到達的對象再次"復蘇"為可到達的對象。既然每個對象只能調用一次finalize( )方法,所以每個對象也只可能"復蘇"一次。
13.finalize( )方法可以明確地被調用,但它卻不能進行垃圾收集。
14.finalize( )方法可以被重載(overload),但只有具備初始的finalize( )方法特點的方法才可以被垃圾收集器調用。
15.子類的finalize( )方法可以明確地調用父類的finalize( )方法,作為該子類對象的最后一次適當的操作。但Java編譯器卻不認為這是一次覆蓋操作(overriding),所以也不會對其調用進行檢查。
16.當finalize( )方法尚未被調用時,System. runFinalization( )方法可以用來調用finalize( )方法,并實現相同的效果,對無用對象進行垃圾收集。
17.當一個方法執行完畢,其中的局部變量就會超出使用范圍,此時可以被當作垃圾收集,但以后每當該方法再次被調用時,其中的局部變量便會被重新創建。
18.Java語言使用了一種"標記交換區的垃圾收集算法"。該算法會遍歷程序中每一個對象的句柄,為被引用的對象做標記,然后回收尚未做標記的對象。所謂遍歷可以簡單地理解為"檢查每一個"。
19.Java語言允許程序員為任何方法添加finalize( )方法,該方法會在垃圾收集器交換回收對象之前被調用。但不要過分依賴該方法對系統資源進行回收和再利用,因為該方法調用后的執行結果是不可預知的。
通過以上對垃圾收集器特點的了解,你應該可以明確垃圾收集器的作用,和垃圾收集器判斷一塊內存空間是否無用的標準。簡單地說,當你為一個對象賦值為null并且重新定向了該對象的引用者,此時該對象就符合垃圾收集器的收集標準。
判斷一個對象是否符合垃圾收集器的收集標準,這是SUN公司程序員認證考試中垃圾收集器部分的重要考點(可以說,這是唯一的考點)。所以,考生在一段給定的代碼中,應該能夠判斷出哪個對象符合垃圾收集器收集的標準,哪個不符合。下面結合幾種認證考試中可能出現的題型來具體講解:
Object obj = new Object ( ) ;
我們知道,obj為Object的一個句柄。當出現new關鍵字時,就給新建的對象分配內存空間,而obj的值就是新分配的內存空間的首地址,即該對象的值(請特別注意,對象的值和對象的內容是不同含義的兩個概念:對象的值就是指其內存塊的首地址,即對象的句柄;而對象的內容則是其具體的內存塊)。此時如果有 obj = null; 則obj指向的內存塊此時就無用了,因為下面再沒有調用該變量了。
請再看以下三種認證考試時可能出現的題型:
程序段1:
1.fobj = new Object ( ) ;
2.fobj. Method ( ) ;
3.fobj = new Object ( ) ;
4.fobj. Method ( ) ;
問:這段代碼中,第幾行的fobj 符合垃圾收集器的收集標準?
答:第3行。因為第3行的fobj被賦了新值,產生了一個新的對象,即換了一塊新的內存空間,也相當于為第1行中的fobj賦了null值。這種類型的題在認證0考試中是最簡單的。
程序段2:
1.Object sobj = new Object ( ) ;
2.Object sobj = null ;
3.Object sobj = new Object ( ) ;
4.sobj = new Object ( ) ;
問:這段代碼中,第幾行的內存空間符合垃圾收集器的收集標準?
答:第1行和第3行。因為第2行為sobj賦值為null,所以在此第1行的sobj符合垃圾收集器的收集標準。而第4行相當于為sobj賦值為null,所以在此第3行的sobj也符合垃圾收集器的收集標準。
如果有一個對象的句柄a,且你把a作為某個構造器的參數,即 new Constructor ( a )的時候,即使你給a賦值為null,a也不符合垃圾收集器的收集標準。直到由上面構造器構造的新對象被賦空值時,a才可以被垃圾收集器收集。
程序段3:
1.Object aobj = new Object ( ) ;
2.Object bobj = new Object ( ) ;
3.Object cobj = new Object ( ) ;
4.aobj = bobj;
5.aobj = cobj;
6.cobj = null;
7.aobj = null;
問:這段代碼中,第幾行的內存空間符合垃圾收集器的收集標準?
答:第7行。注意這類題型是認證考試中可能遇到的最難題型了。
行1-3分別創建了Object類的三個對象:aobj,bobj,cobj
行4:此時對象aobj的句柄指向bobj,所以該行的執行不能使aobj符合垃圾收集器的收集標準。
行5:此時對象aobj的句柄指向cobj,所以該行的執行不能使aobj符合垃圾收集器的收集標準。
行6:此時仍沒有任何一個對象符合垃圾收集器的收集標準。
行7:對象cobj符合了垃圾收集器的收集標準,因為cobj的句柄指向單一的地址空間。在第6行的時候,cobj已經被賦值為null,但由cobj同時還指向了aobj(第5行),所以此時cobj并不符合垃圾收集器的收集標準。而在第7行,aobj所指向的地址空間也被賦予了空值null,這就說明了,由cobj所指向的地址空間已經被完全地賦予了空值。所以此時cobj最終符合了垃圾收集器的收集標準。 但對于aobj和bobj,仍然無法判斷其是否符合收集標準。
總之,在Java語言中,判斷一塊內存空間是否符合垃圾收集器收集標準的標準只有兩個:
1.給對象賦予了空值null,以下再沒有調用過。
2.給對象賦予了新值,既重新分配了內存空間。
最后再次提醒一下,一塊內存空間符合了垃圾收集器的收集標準,并不意味著這塊內存空間就一定會被垃圾收集器收集。
eclipse有很多插件可以用;
前兩天用了一個打包.jar可執行插件,感覺真的很不錯,所有的packege都已寫入MANIFEST.MF
下載地址
http://sourceforge.net/project/showfiles.php?group_id=115990當然先要在eclipse plugins導入net.sf.fjep.fatjar_0.0.23(也即net.sf.fjep.fatjar_0.0.23.zip)
(下載路徑: http://fjep.sourceforge.net/)
也就可在eclipse中右擊選擇"Build Fat Jar"了
最主要一點就是選擇Main-Class,點擊"Browse"選擇
生成的.jar(名稱沒有限制)在該工作區下;可以把該.jar copy到任何一路徑下執行
執行命令格式:
cd d:\test (切換到.jar存放路徑 d:)
java -jar epc.jar(.jar名稱)
或者直接雙擊,也可得到結果
在我處理數據庫時,數據庫連接池把我搞暈了
不過,到現在有時還是會怕怕的...
一有問題就會想到是不是數據庫連接池又有什么問題了...
在此想多了解些有關數據庫連接池的問題,請多多指教..
先謝謝了