(废话)会议通第二回合让我欢喜让我忧......
(第一回合是从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="
http://netmeeting.71.com/WebMeeting/UserMgr/login.aspx" target="mainfrm">
<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"//
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、 靠自己
小蜗牛问妈妈:为什么我们从生下来,就要背负这个又硬又重的壳呢?
妈妈:因为我们的身体没有骨骼的支撑,只能爬,又爬不快。所以要这个壳的保护!
小蜗牛:毛虫姊姊没有骨头,也爬不快,为什么她却不用背这个又硬又重的壳呢?
妈妈:因为毛虫姊姊能变成蝴蝶,天空会保护她啊。
小蜗牛:可是蚯蚓弟弟也没骨头爬不快,也不会变成蝴蝶他什么不背这个又硬又重的壳呢?
妈妈:因为蚯蚓弟弟会钻土, 大地会保护他啊。
小蜗牛哭了起来:我们好可怜,天空不保护,大地也不保护。
蜗牛妈妈安慰他:「所以我们有壳啊!」我们不靠天,也不靠地,我们靠自己。
3、 鲨鱼与鱼
曾有人做过实验,将一只最凶猛的鲨鱼和一群热带鱼放在同一个池子,然后用强化玻璃隔开,最初,鲨鱼每天不断冲撞那块看不到的玻璃,耐何这只是徒劳,它始终不能过到对面去,而实验人员每天都有放一些鲫鱼在池子里,所以鲨鱼也没缺少猎物,只是它仍想到对面去,想尝试那美丽的滋味,每天仍是不断的冲撞那块玻璃,它试了每个角落,每次都是用尽全力,但每次也总是弄的伤痕累累,有好几次都浑身破裂出血,持续了好一些日子,每当玻璃一出现裂痕,实验人员马上加上一块更厚的玻璃。后来,鲨鱼不再冲撞那块玻璃了,对那些斑斓的热带鱼也不再在意,好像他们只是墙上会动的壁画,它开始等着每天固定会出现的鲫鱼,然后用他敏捷的本能进行狩猎,好像回到海中不可一世的凶狠霸气,但这一切只不过是假像罢了,实验到了最后的阶段,实验人员将玻璃取走,但鲨鱼却没有反应,每天仍是在固定的区域游着它不但对那些热带鱼视若无睹,甚至于当那些鲫鱼逃到那边去,他就立刻放弃追逐,说什么也不愿再过去,实验结束了,实验人员讥笑它是海里最懦弱的鱼。
可是失恋过的人都知道为什么,它怕痛。
4、 神迹
法国一个偏僻的小镇,据传有一个特别灵验的水泉,常会出现神迹,可以医治各种疾病。有一天,一个拄着拐杖,少了一条腿的退伍军人,一跛一跛的走过镇上的马路,旁边的镇民带着同情的回吻说:「可怜的家伙,难道他要向上帝祈求再有一条腿吗??」这一句话被退伍的军人听到了,他转过身对他们说:「我不是要向上帝祈求有一条新的腿,而是要祈求帮助我,叫我没有一条腿后,也知道如何过日子。」试想:学习为所失去的感恩,也接纳失去的事实,不管人生的得与失,总是要让自已的生命充满了亮丽与光彩,不再为过去掉泪,努力的活出自己的生命。
5、 钓竿
有个老人在河边钓鱼,一个小孩走过去看他钓鱼,老人技巧纯熟,所以没多久就钓上了满篓的鱼,老人见小孩很可爱,要把整篓的鱼送给他,小孩摇摇头,老人惊异的问道:「你为何不要?」小孩回答:「我想要你手中的钓竿。」老人问:「你要钓竿做什么?」小孩说:「这篓鱼没多久就吃完了,要是我有钓竿,我就可以自己钓,一辈子也吃不完。」我想你一定会说:好聪明的小孩。错了,他如果只要钓竿,那他一条鱼也吃不到。因为,他不懂钓鱼的技巧,光有鱼竿是没用的,因为钓鱼重要的不在<钓竿>,而在<钓技>有太多人认为自己拥有了人生道上的钓竿,再也无惧于路上的风雨,如此,难免会跌倒于泥泞地上。就如小孩看老人,以为只要有钓竿就有吃不完的鱼,像职员看老板,以为只要坐在办公室,就有滚进的财源。
这方面特别适合于技术开发人员.
当你遇到难解问题,不防换个角度想想,问题可能就迎刃而解,领悟更是多多
模拟键盘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 = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify"
+ "&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 = "http://www.alipay.com/cooperate/gateway.do?service=notify_verify"
// + "&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 = "https://www.alipay.com/cooperate/gateway.do?"; //'支付接口
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 = "www.alipay.com";
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 = "http://10.2.17.136:8081/new_jsp/alipay_notify.jsp";//"alipay_notify.jsp"文件的地址
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文件。客户端的TrustStore文件中保存着被客户端所信任的服务器的证书信息。客户端在进行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名称)
或者直接双击,也可得到结果
在我处理数据库时,数据库连接池把我搞晕了
不过,到现在有时还是会怕怕的...
一有问题就会想到是不是数据库连接池又有什么问题了...
在此想多了解些有关数据库连接池的问题,请多多指教..
先谢谢了