Posts Tagged ‘动态’

用CSS动态控制文本属性

星期三, 06月 4th, 2008

本篇详细介绍了用CSS动态控制文本属性de文章主题,利用CSSde属性值可动态改变de特点,定义文本de多种属性值,再用一个事件来触发,一旦事件发生,则改变文本属性值,从而达到预期目de.
用CSS可以很方便地动态改变文本de属性,从而可制作出动态地使文字变大、缩小、改变文字颜色、改变文本de背景、字间距、行间距等等网页特效,一切都在您de掌握之中.是不是有点玄?事实就是如此.那一定很复杂吧?不!看完本文,您就会明白,原来这么简单.
请看下面de示例:
一、动态改变文字大小
这个例子de效果是:一段文本,当鼠标在这段文本上,文字变大,鼠标离开时又恢复原样.
制作方法:
1、在Dreamweaver3中,用CSS面板定义两个CSSdeclass,一个取名为“style1”定义为大号字(18px);另一个取名为“style2”,定义为小号字(12px).获得deCSS相关代码如下:
<style type=”text/css”>
<!–
.style1 { font-size:18px}
.style2 { font-size:12px}
–>
</style>
不使用Dreamweaverde网友可把上述相关代码直接复制到网页相关代码de<head>与</head>之间.
2、 在这段文字de<P>标记中加入这段相关代码:onmouseover=”this.className=’’style1”” onmouseout= “this.className=’’style2””.至此,制作完成,能产生效果de那段文字de源相关代码是这样de:
<p onmouseover=”this.className=’’style1”” onmouseout=”this.className=’’style2””><font color=”#FF0000″>鼠标在这段文字上,文字变大,鼠标离开时变小.</font></p>
不使用Dreamweaverde网友只要把相关代码改成上面这样就行了,预览一下就可看到实际效果了.
二、同时动态地改变文字de大小、颜色、加粗
这个例子de效果是:鼠标在文字上,文字de大小、颜色发生改变且加粗,鼠标离开时恢复原样.
这个例子de制作方法与例一相同,不同de只是在CSS中定义了不同de文字属性,所以制作方法不再重复.在<head>与</head>之间增加deCSS相关代码为:
<style type=”text/css”>
<!–
.style1 { font: bold 16px ; color: #0000FF}
.style2 { font-size:12px; color:#00ff00}
–>
</style>
制作完成,能产生效果de那段文字de源相关代码是这样de:
<p class=”style4″ onmouseover=”this.className=’’style1”” onmouseout=”this.className=’’style2””>鼠标在这段文字上,改变文字de大小、颜色、加粗,鼠标离开时恢复原 样.</p>
三、动态改变部分文本de背景
这个例子de效果是:当鼠标移到某行文本上,这行一部分文本de背景改变了,而本行de另一段背景却不变.
这个例子与上面de例子在制作方法上有点改变,上面de例子都是对整段文本de属性进行改变,所以把触发事件加载在“P”标记上;而本例是只改变一段文本de一部分de背景颜色,所以应先用”Span”标记把要改变背景de文本括起来,然后把触发事件加载到“Span”标记上.
本例在<head>与</head>之间增加deCSS相关代码为:
<style type=”text/css”>
<!–
.style1 { background: #99CCFF}
.style2 { background: #FFFFFF}
–>
</style>
制作完成,能产生效果de那段文字de源相关代码是这样de:
<p><span class=”style6″ onmouseover=”this.className=’’style1”” onmouseout=”this.className=’’style1””>当鼠标移到这段文本上,背景改变了,</span>而本 行de另一段背景却不变.</p>
四、给超级链接动态加图标
这个例子de效果是:当鼠标移到某个超级链接上,它de左边会出现一个图象,鼠标移开,图象消失.
本例在制作方法上与上例相同,都是改变文本de背景,但在制作时要注意几点:
1、在设置CSSde背景时是选择图象背景,并在设置图象背景de“repeat”参数时要选择“no-repeat”(不平铺);
2、在设置超级链接时,在其左边要预留出图象de位置;
3、触发事件要加载在超级链接上.
本例在<head>与</head>之间增加deCSS相关代码为:
<style type=”text/css”>
<!–  
.style1 { background: url(image/dot.gif) no-repeat; }
.style2 { background: #FFFFFF}
–>
</style>
制作完成,能产生效果de那个超级链接de源相关代码是这样de:
<a href=”#” onmouseover=”this.className=’’style1”” onmouseout=”this.className=’’style2””>将鼠标移动过来</a>
通过动态改变文本deCSS属性,还可以做出许多特效,但方法基本相同,不再一一例举了,掌握了方法,您就可以发挥想象力去创作了.

动态CSS站点教程:多个页面样式提供浏览者选择

星期三, 06月 4th, 2008

在cnbruce’’s blog上看到这个即时换STYLEde相关代码,觉得不错就COPY过来备用.
在见de例子就是:一个站点上有多个页面样式提供浏览者选择.同时,在选择了某样式后,再次打开该页面时,将仍然保持该样式.自然会想到了Cookie技术.


程序相关代码
<HTML>
<HEAD>
<link ID=”skin” rel=”stylesheet” type=”text/css”>
<TITLE>换肤技术</TITLE>
<SCRIPT LANGUAGE=javascript>
<!–
function SetCookie(name,value){
var argv=SetCookie.arguments;
var argc=SetCookie.arguments.length;
var expires=(2<argc)?argv[2]:null;
var path=(3<argc)?argv[3]:null;
var domain=(4<argc)?argv[4]:null;
var secure=(5<argc)?argv[5]:false;
document.cookie=name “=” escape(value) ((expires==null)?”":(”; expires=” expires.toGMTString())) ((path==null)?”":(”; path=” path)) ((domain==null)?”":(”; domain=” domain)) ((secure==true)?”; secure”:”");
}

function GetCookie(Name) {
var search = Name “=”;
var returnvalue = “”;
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search);
if (offset != -1) {
offset = search.length;
end = document.cookie.indexOf(”;”, offset);
if (end == -1)
end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset,end));
}
}
return returnvalue;
}

var thisskin;
thisskin=GetCookie(”nowskin”);
if(thisskin!=”")
skin.href=thisskin;
else
skin.href=”css.css”;

function changecss(url){
if(url!=”"){
skin.href=url;
var expdate=new Date();
expdate.setTime(expdate.getTime() (24*60*60*1000*30));
//expdate=null;
//以下设置COOKIES时间为1年,自己随便设置该时间..
SetCookie(”nowskin”,url,expdate,”/”,null,false);
}
}
//–>
</SCRIPT>
</HEAD>
<BODY>

<P>请选择下面de下拉菜单测试换肤效果</P>

<a href=# onclick=”changecss(”css.css”)”>css.css</a>
<a href=# onclick=”changecss(”css1.css”)”>css1.css</a>
<a href=# onclick=”changecss(”css2.css”)”>css2.css</a>
<a href=# onclick=”changecss(”css3.css”)”>css3.css</a>
<br>

<select onchange=”changecss(this.value)”>
<option>选择样式单文件</option>
<script language=”javascript”>
var csss=new Array();
csss[0]=”css.css”;
csss[1]=”css1.css”;
csss[2]=”css2.css”;
csss[3]=”css3.css”;
var i;
for(i=0;i<4;i )
if(thisskin==csss[i])
document.write(”<option value=\”" csss[i] “\” selected>” csss[i] “样式单文件</option>”);
else
document.write(”<option value=\”" csss[i] “\”>” csss[i] “样式单文件</option>”);
</script>
</select>
</BODY>
</HTML>

在Asp.net用C#建立动态Excel

星期二, 06月 3rd, 2008

在Asp.net中建立本地deExcel表,并由服务器向外传播是容易实现de,而删除掉嵌入deExcel.exe进程是困难de.所以 您不要打开任务管理器 ,看Excel.exe进程相关de东西是否还在内存里面.我在这里提供一个解决方案 ,里面提供了两个方法 :

“CreateExcelWorkbook”(说明 建立Excel工作簿) 这个方法 运行一个存储过程 ,返回一个DataReader 并根据DataReader 来生成一个Excel工作簿 ,并保存到文件系统中,创建一个“download”连接,这样 用户就可以将Excel表导入到浏览器中也可以直接下载到机器上.

第二个方法:GenerateCSVReport 本质上是做同样de一件事情,仅仅是保存de文件deCSV格式 .仍然 导入到Excel中,CSV相关代码能解决一个开发中de普片de问题:您有一列 里面倒入了多个零,CSV相关代码能保证零不变空 .(说明: 就是在Excel表中多个零de值 不能保存de问题)

在可以下载de解决方案中,包含一个有效de类 ” SPGen” 能运行存储过程并返回DataReader ,一个移除文件de方法 能删除早先于一个特定de时间值.下面出现de主要de方法就是CreateExcelWorkbook

注意:您必须知道 在运行这个页面de时候,您可能需要能在WebSever 服务器de文件系统中写 Excel,Csv文件de管理员de权限.处理这个问题de最简单de方法就是运行这个页面在自己de文件夹里面并包括自己de配置文件.并在配置文件中添加下面de元素<identity impersonate =”true” … .您仍然需要物理文件夹de访问控制列表(ACL)de写de权限,只有这样运行de页面de身份有写de权限,最后,您需要设置一个Com连接到Excel 9.0 or Excel 10 类型库 ,VS.NET 将为您生成一个装配件.我相信 微软在他们Office网站上有一个连接,可以下载到微软de初始de装配件.(可能不准,我de理解是面向.netde装配件)

<identity impersonate=”true” userName=”adminuser” password=”adminpass” />

特别注意 下面de相关代码块de作用是清除Excelde对象.

// Need all following code to clean up and extingush all references!!!

oWB.Close(null,null,null);

oXL.Workbooks.Close();

oXL.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject (oRng);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oXL);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oWB);

oSheet=null;

oWB=null;

oXL = null;

GC.Collect(); // force final cleanup!

这是必须de ,因为oSheet”, “oWb” , ‘oRng”, 等等 对象也是COMde实例,我需要

Marshal类deReleaseComObjectde方法把它们从.NET去掉

private void CreateExcelWorkbook(string spName, SqlParameter[] parms)

{

string strCurrentDir = Server.MapPath(”.”) “\\”;

RemoveFiles(strCurrentDir); // utility method to clean up old files

Excel.Application oXL;

Excel._Workbook oWB;

Excel._Worksheet oSheet;

Excel.Range oRng;

try

{

GC.Collect();// clean up any other excel guys hangin’ around…

oXL = new Excel.Application();

oXL.Visible = false;

//Get a new workbook.

oWB = (Excel._Workbook)(oXL.Workbooks.Add( Missing.Value ));

oSheet = (Excel._Worksheet)oWB.ActiveSheet;

//get our Data

string strConnect = System.Configuration.ConfigurationSettings.AppSettings["connectString"];

SPGen sg = new SPGen(strConnect,spName,parms);

SqlDataReader myReader = sg.RunReader();

// Create Header and sheet…

int iRow =2;

for(int j=0;j<myReader.FieldCount;j )

{

oSheet.Cells[1, j 1] = myReader.GetName(j).ToString();

}

// build the sheet contents

while (myReader.Read())

{

for(int k=0;k < myReader.FieldCount;k )

{

oSheet.Cells[iRow,k 1]= myReader.GetValue(k).ToString();

}

iRow ;

}// end while

myReader.Close();

myReader=null;

//Format A1:Z1 as bold, vertical alignment = center.

oSheet.get_Range(”A1″, “Z1″).Font.Bold = true;

oSheet.get_Range(”A1″, “Z1″).VerticalAlignment =Excel.XlVAlign.xlVAlignCenter;

//AutoFit columns A:Z.

oRng = oSheet.get_Range(”A1″, “Z1″);

oRng.EntireColumn.AutoFit();

oXL.Visible = false;

oXL.UserControl = false;

string strFile =”report” System.DateTime.Now.Ticks.ToString() “.xls”;

oWB.SaveAs( strCurrentDir strFile,Excel.XlFileFormat.xlWorkbookNormal,

null,null,false,false,Excel.XlSaveAsAccessMode.xlShared,false,false,null,null,null);

// Need all following code to clean up and extingush all references!!!

oWB.Close(null,null,null);

oXL.Workbooks.Close();

oXL.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject (oRng);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oXL);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oWB);

oSheet=null;

oWB=null;

oXL = null;

GC.Collect(); // force final cleanup!

string strMachineName = Request.ServerVariables["SERVER_NAME"];

errLabel.Text=”<A href=http://” strMachineName “/ExcelGen/” strFile “>Download Report</a>”;

}

catch( Exception theException )

{

String errorMessage;

errorMessage = “Error: “;

errorMessage = String.Concat( errorMessage, theException.Message );

errorMessage = String.Concat( errorMessage, ” Line: ” );

errorMessage = String.Concat( errorMessage, theException.Source );

errLabel.Text= errorMessage ;

}

}

下面是原文章

Create Dynamic ASP.NET Excel Workbooks In C#

By Peter A. Bromberg, Ph.D.

Printer - Friendly Version

There is also, in the downloadable solution, a utility class “SPGen” that handles running stored

Generating native Excel spreadsheets from your web server is not that difficult with ASP.NET. What can be difficult is making instances of Excel.exe go away so you don’t open up TaskMgr and see 123 instances of EXCEL.EXE still sitting in memory. I provide here a solution that has two methods, “CreateExcelWorkbook”, which runs a stored proceduire that returns a DataReader and assembles a native Excel Workbook from it, saves it to the filesystem, and creates a “Download” link so the user can either load the report into Excel in their browser, or download the XLS file. The second method, GenerateCSVReport, does essentially the same thing but creates a CSV file that will, of course, also load into Excel. The CSV code correctly handles a common developer problem in that if you have a column that has leading zeroes, they are preserved.

procedures and returning DataReaders, and a RemoveFiles utility method that cleans up any XLS or CSV file older than the specified number of minutes. The key method presented below is the CreateExcelWorkbook method.

NOTE: You should be aware that you will probably need to run this page under an account that has administrative privileges as it needs write permissions to store the generated Excel or CSV files on the webserver’s file system. Probably the easiest way to handle this is to have the page in its own folder with its own web.config, and insert an <identity impersonate =”true” … elment. You may also need to enable ACL permissions on the physical folder as well so that the identity the page runs under has write permissions. Finally, you’ll need to set a COM reference to the Excel 9.0 or Excel 10 Typelibrary and let VS.NET generate the Interop assemblies for you. I believe MS also has a link on their Office site where you can download the Office primary Interop Assemblies.

<identity impersonate=”true” userName=”adminuser” password=”adminpass” />

Note especially the code block that does the “cleanup” of the Excel objects:

// Need all following code to clean up and extingush all references!!!

oWB.Close(null,null,null);

oXL.Workbooks.Close();

oXL.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject (oRng);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oXL);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oWB);

oSheet=null;

oWB=null;

oXL = null;

GC.Collect(); // force final cleanup!

This is necessary because all those littlle objects “oSheet”, “oWb” , ‘oRng”, etc. are all COM instances and we need to use the InteropServices ReleaseComObject method of the Marshal class to get rid of them in .NET.

private void CreateExcelWorkbook(string spName, SqlParameter[] parms)

{

string strCurrentDir = Server.MapPath(”.”) “\\”;

RemoveFiles(strCurrentDir); // utility method to clean up old files

Excel.Application oXL;

Excel._Workbook oWB;

Excel._Worksheet oSheet;

Excel.Range oRng;

try

{

GC.Collect();// clean up any other excel guys hangin’ around…

oXL = new Excel.Application();

oXL.Visible = false;

//Get a new workbook.

oWB = (Excel._Workbook)(oXL.Workbooks.Add( Missing.Value ));

oSheet = (Excel._Worksheet)oWB.ActiveSheet;

//get our Data

string strConnect = System.Configuration.ConfigurationSettings.AppSettings["connectString"];

SPGen sg = new SPGen(strConnect,spName,parms);

SqlDataReader myReader = sg.RunReader();

// Create Header and sheet…

int iRow =2;

for(int j=0;j<myReader.FieldCount;j )

{

oSheet.Cells[1, j 1] = myReader.GetName(j).ToString();

}

// build the sheet contents

while (myReader.Read())

{

for(int k=0;k < myReader.FieldCount;k )

{

oSheet.Cells[iRow,k 1]= myReader.GetValue(k).ToString();

}

iRow ;

}// end while

myReader.Close();

myReader=null;

//Format A1:Z1 as bold, vertical alignment = center.

oSheet.get_Range(”A1″, “Z1″).Font.Bold = true;

oSheet.get_Range(”A1″, “Z1″).VerticalAlignment =Excel.XlVAlign.xlVAlignCenter;

//AutoFit columns A:Z.

oRng = oSheet.get_Range(”A1″, “Z1″);

oRng.EntireColumn.AutoFit();

oXL.Visible = false;

oXL.UserControl = false;

string strFile =”report” System.DateTime.Now.Ticks.ToString() “.xls”;

oWB.SaveAs( strCurrentDir strFile,Excel.XlFileFormat.xlWorkbookNormal,

null,null,false,false,Excel.XlSaveAsAccessMode.xlShared,false,false,null,null,null);

// Need all following code to clean up and extingush all references!!!

oWB.Close(null,null,null);

oXL.Workbooks.Close();

oXL.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject (oRng);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oXL);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);

System.Runtime.InteropServices.Marshal.ReleaseComObject (oWB);

oSheet=null;

oWB=null;

oXL = null;

GC.Collect(); // force final cleanup!

string strMachineName = Request.ServerVariables["SERVER_NAME"];

errLabel.Text=”<A href=http://” strMachineName “/ExcelGen/” strFile “>Download Report</a>”;

}

catch( Exception theException )

{

String errorMessage;

errorMessage = “Error: “;

errorMessage = String.Concat( errorMessage, theException.Message );

errorMessage = String.Concat( errorMessage, ” Line: ” );

errorMessage = String.Concat( errorMessage, theException.Source );

errLabel.Text= errorMessage ;

}

}

-翻译匆忙 ,有误请谅解 ,欢迎指点,探讨 —小徐

ASP.NET中根据XML动态创建使用WEB组件

星期二, 06月 3rd, 2008

前段时间笔者在开发中需要动态创建WEB组件,本以为是小事一桩,谁知看时容易做时难.里面还真有些小问题.下面笔者就结合自己de程序来介绍一下如何动态创建并使用WEB组件,希望能给做类似工作de朋友提供一点帮助.
一、程序思路
程序主要分三部分:
1、程序要根据XML中de数据信息确定需要创建deWEB组件de个数.
2、动态创建WEB组件.
3、使用动态创建deWEB组件.
其中2和3是笔者要重点介绍de部分.
下面笔者就按照这三部分结合程序实例(以c#为例)来一一介绍.
二、读取XML文件
读取XML文件在很多de资料中都有详细de说明,而且相信很多朋友都已经很好de掌握了其技术.但为了保证文章de完整性,笔者在这里还是要赘述几句.深谐其味de朋友可以略过此段不看.
笔者程序中要读取deXML文件形如下列:
config.xml
<?xml version=”1.0″?>
<Root>
<Nettype>net</Nettype>
<Totalnum>6</Totalnum>
<Cells>2</Cells>
<IPlink>
<Name>站点1</Name>
<IP>192.8.198.1</IP>
<Sequence>1</Sequence>
</IPlink>
<IPlink>
<Name>站点2</Name>
<IP>192.8.198.2</IP>
<Sequence>2</Sequence>
</IPlink>
… …
</Root>
读取XML文件de程序如下:
protected void readconfig()
{
try
{
System.Xml.XmlDocument mXmlDoc=new System.Xml.XmlDocument();
mXmlDoc.Load(Server.MapPath(configfilepath));
nettype=mXmlDoc.SelectNodes(”//Root/Nettype”)[0].InnerText; totalnum=int.Parse(mXmlDoc.SelectNodes(”//Root/Totalnum”)[0].InnerText);
//读出列数
cells=int.Parse(mXmlDoc.SelectNodes(”//Root/Cells”)[0].InnerText);
XmlNodeList mXmlNodes=mXmlDoc.SelectNodes(”//Root/IPlink”);
foreach(XmlNode IPlinkchildlNode in mXmlNodes)
{
//得到序列号
int icount=int.Parse(IPlinkchildlNode.ChildNodes[2].InnerText);
//根据序列号,将测量点de名称放入名称数组相应de位置上
namestr[icount]=IPlinkchildlNode.ChildNodes[0].InnerText;
//根据序列号,将测量点deIP放入IP数组相应de位置上
ipstr[icount]=IPlinkchildlNode.ChildNodes[1].InnerText;
}
}
catch
{
errmessage.InnerHtml=”<table align=center><tr>
<td align=left><font color=red>不能读取配置文件,可能de错误是<br>” “1、配置文件不存在<br>”
“2、配置文件内容被损坏”
“</font></td></tr></table>”;
}
}
程序中对XML中无子节点de元素如:
<Nettype>net</Nettype>
直接使用如下语句读取.
mXmlDoc.SelectNodes(”//Root/Nettype”)[0].InnerText;
对于有子节点de元素如:
<IPlink>
<Name>站点1</Name>
<IP>192.8.198.1</IP>
<Sequence>1</Sequence>
</IPlink>
要使用语句如下来读取.
IPlinkchildlNode.ChildNodes[N].InnerText
其中 ChildNodes[N] 中de[N]为子节点de序号,子节点
<Name>站点1</Name>
de序号应该为[0].

三、动态创建WEB组件.
先来看程序实例:
private void createconfigtable(int totalnum,int[] sequenceint,string[] namestr,string[] ipstr)
{
//根据得到测量点de总数,动态生成输入框
for(int i=1;i<=totalnum;i )
{
//创建表格
HtmlTable showtable = new HtmlTable();
showtable.Border=0;
showtable.ID=”showtable” i.ToString();
showtable.BorderColor=”#000000″;
showtable.CellPadding=4;
showtable.CellSpacing=4;
showtable.Align=”center”;
myPlaceHolder.Controls.Add(showtable);
//创建一行
HtmlTableRow tRow = new HtmlTableRow();
showtable.Rows.Add(tRow);
//创建第一列(序号)
HtmlTableCell tCell = new HtmlTableCell();
Label sequenceLabel = new Label();
sequenceLabel.ID=”sequenceLabel” i.ToString();
sequenceLabel.Text=”序号:”;
sequenceLabel.Enabled=true;
tCell.Controls.Add(sequenceLabel);
tRow.Cells.Add(tCell);
//创建第二列
tCell = new HtmlTableCell();
sequencedataTB = new TextBox();
sequencedataTB.ID=”sequencedataTB” i.ToString();
sequencedataTB.Text=i.ToString();
sequencedataTB.Width=30;
sequencedataTB.Text=sequenceint[i].ToString();
sequencedataTB.ReadOnly=false;
//创建第三列(名称)
tCell = new HtmlTableCell();
Label nameLabel = new Label();
nameLabel.ID=”nameLabel” i.ToString();
nameLabel.Text=”名称:”;
nameLabel.Enabled=true;
tCell.Controls.Add(nameLabel);
tRow.Cells.Add(tCell);
//创建第四列
tCell = new HtmlTableCell();
nameTB=new TextBox();
nameTB.ID=”nameTB” i.ToString();
nameTB.Width=120;
nameTB.Text=namestr[i];
nameTB.MaxLength=50;
tCell.Controls.Add(nameTB);
tRow.Cells.Add(tCell);
//创建第五列(IP)
tCell = new HtmlTableCell();
Label ipLabel = new Label();
ipLabel.ID=”ipLabel” i.ToString();
ipLabel.Text=”IP:”;
ipLabel.Enabled=true;
tCell.Controls.Add(ipLabel);
tRow.Cells.Add(tCell);
//创建第六列
tCell = new HtmlTableCell();
ipTB=new TextBox();
ipTB.ID=”ipTB” i.ToString();
ipTB.Width=120;
ipTB.Text=ipstr[i];
ipTB.MaxLength=15;
tCell.Controls.Add(ipTB);
tRow.Cells.Add(tCell);
}
}
tCell.Controls.Add(sequencedataTB);
tRow.Cells.Add(tCell);
… …
//创建第五列(IP)
tCell = new HtmlTableCell();
Label ipLabel = new Label();
ipLabel.ID=”ipLabel” i.ToString();
ipLabel.Text=”IP:”;
ipLabel.Enabled=true;
tCell.Controls.Add(ipLabel);
tRow.Cells.Add(tCell);
//创建第六列
tCell = new HtmlTableCell();
ipTB=new TextBox();
ipTB.ID=”ipTB” i.ToString();
ipTB.Width=120;
ipTB.Text=ipstr[i];
ipTB.MaxLength=15;
tCell.Controls.Add(ipTB);
tRow.Cells.Add(tCell);
}
}
程序中demyPlaceHolder 是 System.Web.UI.WebControls.PlaceHolder 组件,使用该组件deHTML语法如下:
… …
<tr>
<td>
<asp:PlaceHolder id=”myPlaceHolder” runat=”server”></asp:PlaceHolder>
</td>
</tr>
… …
使用该组件de目de是为了定位动态创建de表格.该组件在页面上de位置即为动态创建de表格de位置.
程序中另外一个要说明de地方是动态创建de组件deIDde设定.组件deIDde设定要注意两点:
1、ID号不能重复
2、要便于在程序中使用.因为要在程序中使用动态创建de组件,要通过该组件deID来查找.(关于这一点,在“使用动态创建deWEB组件”部分会有较为详细de介绍)

关于.NET动态代理的介绍和应用简介

星期二, 06月 3rd, 2008

  引言
  假如现在我有这样在这个示例中我将使用尽可能简单de逻辑实现所有功能需求,这将更突出我所要解决de核心问题.例子是一个简单计算器类:
public class Calculator
{
 public int Add(int x, int y) { return x y; }
}
  这个类再简单不过了,不过若您将它想象为一个可能更复杂de业务处理类de时候,您将面临除了核心功能实现之外de更多处理细节,比如说:权限控制、审计日志、性能监测、缓冲处理、事务环境等等.为简单起见,我首先为该类增加记录日志de功能,该功能要求将对每个方法de调用和处理结果输出到Console中,如下:
public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write(”Add({0},{1})”, x, y);
  int result = x y;
  Console.WriteLine(” = {0}”, result);
  return result;
 }
}
  再简单不过了,对吧?现在我需要为该方法实现性能监测,如下:
public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write(”Add({0},{1})”, x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(” [{0}] “, TimeInter);
  Console.WriteLine(” = {0}”, result);
  return result;
 }
}
  此时您已经感觉到,虽然我实现了所需de功能,但是在一个方法中堆叠了处理各类事宜de不同相关代码.虽然在这个简单例子中不会感觉有什么不爽,但是请您想象一下如果我将为该类添加第二个方法时会发生什么事情:
public class Calculator
{
 public int Add(int x, int y)
 {
  Console.Write(”Add({0},{1})”, x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(” [{0}] “, TimeInter);
  Console.WriteLine(” = {0}”, result);
  return result;
 }
 public int Subtract(int x, int y)
 {
  Console.Write(”Subtract({0},{1})”, x, y);
  DateTime TimeBegin = System.DateTime.Now;
  int result = x - y;
  TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
  Console.Write(” [{0}] “, TimeInter);
  Console.WriteLine(” = {0}”, result);
  return result;
 }
}
  在两个方法中已经明显出现重复相关代码了,这可不是一个好de解决办法——想想一下如果我de计算器有10个方法呢?如果我还有类似于计算器类de另外数十个类呢?如果我还有更多de方法级功能要实现呢(权限控制、事务管理……)?在企业级应用开发中,这可是一个经常会遇de问题.为清楚起见,我将问题分解成两部分,首要de问题是相关代码职责混淆,其次则是同样de相关代码逻辑反复多次——这些问题都将导致开发管理、相关代码编写与维护de各种困难.
  方案一:自己手动编写代理解决
  1、首先 我定义接口ICalculator:
using System;
namespace Proxy
{
 public interface ICalculator
 {
  int Add(int x, int y);
  int Subtract(int x, int y);
 }
}
  2、具体实现一个接口:
using System;
namespace Proxy
{
 public class Calculator:ICalculator
 {
  public virtual int Add(int x, int y)
  {
   int result = x y;
   return result;
  }
  public virtual int Subtract(int x, int y)
  {
   int result = x - y;
   return result;
  }
 }
}  3、编写增加日志和性能检测功能de代理类
  增加记录日志de功能,即功能要求将对每个方法de调用和处理结果输出到Console;增加性能监测.
  有两种实现方式 ,注释了其中de一种
using System;
namespace Proxy
{
 // /// <summary>
 // /// CalProxy de摘要说明.
 // /// </summary>
 // public class CalProxy:ICalculator
 // {
 // private Calculator _Calculator;
 // public CalProxy()
 // {
 // this._Calculator=new Calculator();
 // }
 // private DateTime TimeBegin = System.DateTime.Now;
 // private void PreDoSomething(int x, int y)
 // {
 // TimeBegin = System.DateTime.Now;
 // Console.Write(”Number({0},{1})\n”, x, y);
 // }
 // //实现add
 // public virtual int Add(int x, int y)
 // {
 // this.PreDoSomething(x,y);
 // int result = this._Calculator.Add(x,y);
 // this.PostDoSomething(result);
 // return result;
 // }
 // //实现sub
 // public virtual int Subtract(int x, int y)
 // {
 // this.PreDoSomething(x,y);
 // int result = this._Calculator.Subtract(x,y);
 // this.PostDoSomething(result);
 // return result;
 // }
 // private void PostDoSomething(int result)
 // {
 // TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
 // Console.Write(” 运行时间[{0}]\n “, TimeInter);
 // Console.WriteLine(” 运行结果= {0}\n”, result);
 // }
 // }
 /// <summary>
 /// CalProxy de摘要说明.
 /// </summary>
 public class CalProxy:Calculator
 {
  public CalProxy()
  {}
  private DateTime TimeBegin = System.DateTime.Now;
  private void PreDoSomething(int x, int y)
  {
   TimeBegin = System.DateTime.Now;
   Console.Write(”Number({0},{1})\n”, x, y);
  }
  //实现add
  public override int Add(int x, int y)
  {
   this.PreDoSomething(x,y);
   int result = base.Add(x,y);
   this.PostDoSomething(result);
   return result;
  }
  //实现sub
  public override int Subtract(int x, int y)
  {
   this.PreDoSomething(x,y);
   int result = base.Subtract(x,y);
   this.PostDoSomething(result);
   return result;
  }
  private void PostDoSomething(int result)
  {
   TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
   Console.Write(” 运行时间[{0}]\n “, TimeInter);
   Console.WriteLine(” 运行结果= {0}\n”, result);
  }
 }
}
  4、外界de调用方式
ICalculator ICal=new Proxy.CalProxy();
ICal.Add(5,3);
ICal.Subtract(7,2);
  运行程序de结果:
Number(5,3)
  运行时间[00:00:02.0156250]
  运行结果= 8
  Number(7,2)
  运行时间[00:00:03]
  运行结果= 5
  方案二:通过使用Castle.DynamicProxy,实现Iinterceptor解决
  步骤1,2与解决问题
  3、实现StandardInterceptor,增加日志和性能监测功能
  StandardInterceptor是接口Iinterceptorde一个实现类,我实现StandardInterceptor
using System;
using System.Collections;
using Castle.DynamicProxy;
namespace Proxy
{
 /// <summary>
 /// ProxyInterceptor 拦截器 实现了日志和性能监测
 /// </summary>
 public class ProxyInterceptor:StandardInterceptor
 {
  private System.DateTime TimeBegin=System.DateTime.Now;
  public ProxyInterceptor()
  {}
  protected override void PostProceed(IInvocation invocation, ref object returnValue, params object[] arguments)
  {
   TimeSpan TimeInter =System.DateTime.Now-TimeBegin;
   Console.Write(” 运行时间[{0}]\n “, TimeInter);
   Console.WriteLine(” 运行结果= {0}\n”, returnValue);
   base.PostProceed(invocation, ref returnValue, arguments);
  }
  protected override void PreProceed(IInvocation invocation, params object[] args)
  {
   Console.Write(”Number({0},{1})\n”, args[0], args[1]);
   TimeBegin=System.DateTime.Now;
   base.PreProceed(invocation, args);
  }
  public override object Intercept(IInvocation invocation, params object[] args)
  {
   PreProceed(invocation, args);
   object retValue = invocation.Proceed( args );
   PostProceed(invocation, ref retValue, args);
   return retValue;
  }
 }
}
  4、使用Castle.DynamicProxy调用
ProxyGenerator generator = new ProxyGenerator();
object proxy = generator.CreateClassProxy(typeof(Calculator), new ProxyInterceptor());
ICalculator ICalCastle=proxy as ICalculator;
ICalCastle.Add(5,3);
ICalCastle.Subtract(7,2);


  实现过程:首先通过相关代码生成完成一个代理类,该代理类继承自要织入de类.然后在代理类中覆盖要拦截de方法,并在覆盖de方法中封装Invocation对象,并传给用户传入deIntercepter对象deIntercept方法.在Intercept方法依次调用IntercepterdePreProcess,通过Invocation传入deDelegate指向de回调函数,IntercepterdePostProcess方法,从而达到拦截de目de.
  意义
  在aop领域 可以将日志,事务,缓存等附加功能用此实现.

Java动态代理实现AOP

星期一, 06月 2nd, 2008

目前整个开发社区对AOP(Aspect Oriented Programing)推崇备至,也涌现出大量支持AOPde优秀Framework,–Spring, JAC, Jboss AOP 等等.AOP似乎一时之间成了潮流.Java初学者不禁要发出感慨,OOP还没有学通呢,又来AOP.本文不是要在理论上具体阐述何为AOP, 为何要进行AOP . 要详细了解学习AOP可以到它老家http://aosd.net去瞧瞧.这里只是意图通过一个简单de例子向初学者展示一下如何来进行AOP.
  为了简单起见,例子没有没有使用任何第三方deAOP Framework, 而是利用Java语言本身自带de动态代理功能来实现AOP.
  让我先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面.它de主要意图就要将日志记录,性能统计,安全控制等等相关代码从商业逻辑相关代码中清楚de划分出来,我可以把这些行为一个一个单独看作系统所要解决de问题,就是所谓de面向问题de编程(不知将AOP译作面向问题de编程是否欠妥).通过对这些行为de分离,我希望可以将它们独立地配置到商业方法中,而要改变这些行为也不需要影响到商业方法相关代码.
  假设系统由一系列deBusinessObject所完成业务逻辑功能,系统要求在每一次业务逻辑处理时要做日志记录.这里我略去具体de业务逻辑相关代码.
  public interface BusinessInterface {
  public void processBusiness();
  }
  public class BusinessObject implements BusinessInterface {
  private Logger logger = Logger.getLogger(this.getClass().getName());
  public void processBusiness(){
  try {
   logger.info(”start to processing…”);
   //business logic here.
   System.out.println(“here is business logic”);
   logger.info(”end processing…”);
  } catch (Exception e){
   logger.info(”exception happends…”);
   //exception handling
  }
  }
  }
  这里处理商业逻辑de相关代码和日志记录相关代码混合在一起,这给日后de维护带来一定de困难,并且也会造成大量de相关代码重复.完全相同delog相关代码将出现在系统de每一个BusinessObject中.

JSP动态输出Excel及中文乱码的解决

星期一, 06月 2nd, 2008

  最近在网上看到一个用java来操纵exceldeopen source,在weblogic上试用了一下,觉得很不错,特此向大家推荐一下.

  首先去http://www.andykhan.com/jexcelapi/index.html下载最新deJExcelApi,把jxl.jar置于您declasspath中.

  写一个javaBean,利用JExcelApi来动态生成excel文档,我这里写一个最简单de,示意性de.复杂de您可能还要查询数据库什么de.

///////////////////////////Test.java///////////////////////////////////////////
package com.jagie.test;
import java.io.*;
import jxl.*;
import jxl.write.*;
import jxl.format.*;
import java.util.*;
import java.awt.Color;

public class Test{
 public static void writeExcel(OutputStream os) throws Exception {
  jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os);
  jxl.write.WritableSheet ws = wwb.createSheet(”TestSheet1″, 0);
  jxl.write.Label labelC = new jxl.write.Label(0, 0, “我爱中国”);
  ws.addCell(labelC);
  jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,20, WritableFont.BOLD, false,
  UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.GREEN);
  jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);
  wcfFC.setBackground(jxl.format.Colour.RED);
  labelC = new jxl.write.Label(6, 0, “中国爱我”,wcfFC);
  ws.addCell(labelC);
  //写入Exel工作表
  wwb.write();
  //关闭Excel工作薄对象
  wwb.close();
 }

 //最好写一个这样demain方法来测试一下您de这个class是否写好了.
 public static void main(String[] args)throws Exception{
  File f=new File(”kk.xls”);
  f.createNewFile();
  writeExcel(new FileOutputStream(f));
 }
}

  写一个jsp,来利用Test这个javabean输出excel文档.

///////////////////////////test_excel.jsp//////////////////////////

<%@page import=”com.jagie.test.Test” %>
<%
 response.reset();
 response.setContentType(”application/vnd.ms-excel”);
 Test.writeExcel(response.getOutputStream());
%>

  这样就大功告成了,您用ie访问test_excel.jsp就能在ie里面打开动态生成deexcel文档了.一点乱码也没有.

  也许有人会问:response.reset();可不可以不要这一句,我de建议是一定要写,除非您能保证responsedebuffer里面没有别de东西.

  还有人也许会问:我在jsp开头加上<%@page contentType=”application/vnd.ms-excel;charset=GBK” %>这一句,去掉response.setContentType(”application/vnd.ms-excel”);行不行?回答这个问题很简单,就是查看jsp服务器编译jsp后生成dejava相关代码,如果改成这样,我dewelogic7编译test_excel.jsp后生成dejava文件de示意性相关代码是这样de:

public void _jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) throws java.io.IOException,
javax.servlet.ServletException {

 // declare and set well-known variables:
 javax.servlet.ServletConfig config = getServletConfig();
 javax.servlet.ServletContext application = config.getServletContext();
 javax.servlet.jsp.tagext.Tag _activeTag = null;
 // variables for Tag extension protocol

 Object page = this;
 javax.servlet.jsp.JspWriter out;
 javax.servlet.jsp.PageContext pageContext =
 javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this,
 request, response, null, true, 8192, true);

 response.setHeader(”Content-Type”, “application/vnd.ms-excel; charset=GBK”);
 out = pageContext.getOut();
 JspWriter _originalOut = out;

 javax.servlet.http.HttpSession session = request.getSession(true);

 try { // error page try block
  response.setContentType(”application/vnd.ms-excel;charset=GBK”);
  out.print(”\r\n\r\n\r\n\r\n”);
  out.print(”\r\n”);
  //[ /test_excel.jsp; Line: 6]
  response.reset(); //[ /test_excel.jsp; Line: 7]
  //response.setContentType(”application/vnd.ms-excel”);
  //[ /test_excel.jsp; Line: 8]
  Test.writeExcel(response.getOutputStream()); //[ /test_excel.jsp; Line: 9]
  } catch (Throwable __ee) {
   while (out != null && out != _originalOut) out = pageContext.popBody();
  ((weblogic.servlet.jsp.PageContextImpl)pageContext).handlePageException((Throwable)__ee);
 }

 //before final close brace…
}

  很明显,屏蔽response.setContentType(”application/vnd.ms-excel”);后,在Test.writeExcel(response.getOutputStream());之前,response.reset(); 之后没有设置response contenttypede正确类型,当然输出为乱码了.而正确输出exceldejspde编译后源码是这样de:

public void _jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) throws java.io.IOException,
javax.servlet.ServletException
{
 // declare and set well-known variables:
 javax.servlet.ServletConfig config = getServletConfig();
 javax.servlet.ServletContext application = config.getServletContext();
 javax.servlet.jsp.tagext.Tag _activeTag = null;
 // variables for Tag extension protocol

 Object page = this;
 javax.servlet.jsp.JspWriter out;
 javax.servlet.jsp.PageContext pageContext =
  javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);

 out = pageContext.getOut();
 JspWriter _originalOut = out;

 javax.servlet.http.HttpSession session = request.getSession(true);

 try { // error page try block
  out.print(”\r\n”);
  //[ /test_excel.jsp; Line: 2]
  response.reset(); //[ /test_excel.jsp; Line: 3]
  response.setContentType(”application/vnd.ms-excel”); //[ /test_excel.jsp; Line: 4]
  Test.writeExcel(response.getOutputStream()); //[ /test_excel.jsp; Line: 5]
 } catch (Throwable __ee) {
  while (out != null && out != _originalOut) out = pageContext.popBody();
  ((weblogic.servlet.jsp.PageContextImpl)pageContext).handlePageException((Throwable)__ee);
 }

  //before final close brace…
}

  大家可以看到在response.reset();之后,Test.writeExcel(response.getOutputStream());之前正确de设置了responsede输出内容.所以输出就正常了.

  最后,希望这篇文章能对您有所启发,如有错误之处,敬请批评指正!

从jsp发送动态图像

星期一, 06月 2nd, 2008

您是否曾经想过从jsp页面(或者servlet)中发送动态产生de图像?这篇技巧告诉您如何做.要运行这里de相关代码,您需要一个Tomcat或者其他支持JSP 1.1deweb服务器.
当一个web页面带有image/jpeg (或者其他de图像格式)deMIME类型被发送时,您de浏览器将那个返回结果当作一个图像,然后浏览器显示图像,作为页面de一部分或者完全作为图像自身.要为您dejsp页面设置MIME类型,您需要设置页面decontentType属性:
<%@ page contentType=”image/jpeg” … %>
然后您需要创建一个BufferedImage绘制您de动态图像:
BufferedImage image = new BufferedImage(width,
height, BufferedImage.TYPE_INT_RGB);
创建完一个BufferedImage后,您需要得到图形环境进行绘制,一个Graphics或者Graphics2D对象:
Graphics g = image.getGraphics();
// or
Graphics2d g2d = image.createGraphics();
从现在起您就可以绘制图像内容了.对图形环境绘制就会画到BufferedImage.最开始这个图像都是黑色de,因此用您希望de背景颜色填充图像是一个不错de主意,然后,当您完成图像de绘制,您需要dispose图形环境:
g.dispose();
// or
g2d.dispose();
一旦完成图像de绘制,您在response中返回那个图像.您可以使用非标准decom.sun.image.codec.jpeg包中deJPEGImageEncoder类编码图像,或者如果您使用JDK1.4,您可以使用标准deImageIO类.在使用JPEGImageEncoder时有一个技巧,您必须从ServletResponse取来ServletOutputStream而不能使用隐含deJSP输出变量out.
ServletOutputStream sos = response.getOutputStream();
JPEGImageEncoder encoder =
JPEGCodec.createJPEGEncoder(sos);
encoder.encode(image);
// or
ImageIO.write(image, “JPEG”, out);
这里有一个从所有de可能方案中(例如g.dispose();或者g2d.dispose();)选取de一个完整de例子.这个例子使用Graphics对象绘制一个随机de多边形,图像通过JPEGImageEncoder绘制,您可以自由设置多边形de顶点数得到更复杂de形状,换言之,有更多顶点和边.
要运行这个例子,将从”<%@”到最后一个”%>”之间dejsp相关代码放到一个名为image.jspde文件中,将那个文件放到您deweb服务器可以找到de地方,在使用Tomcatde情况下是ROOT目录,启动Tomcat,访问http://localhost:8080/image.jsp.
<%@ page contentType=”image/jpeg”
import=”java.awt.*,java.awt.image.*,
com.sun.image.codec.jpeg.*,java.util.*”
%>
<%
// Create image
int width=200, height=200;
BufferedImage image = new BufferedImage(width,
height, BufferedImage.TYPE_INT_RGB);
// Get drawing context
Graphics g = image.getGraphics();
// Fill background
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
// Create random polygon
Polygon poly = new Polygon();
Random random = new Random();
for (int i=0; i < 5; i ) {
poly.addPoint(random.nextInt(width),
random.nextInt(height));
}
// Fill polygon
g.setColor(Color.cyan);
g.fillPolygon(poly);
// Dispose context
g.dispose();
// Send back image
ServletOutputStream sos = response.getOutputStream();
JPEGImageEncoder encoder =
JPEGCodec.createJPEGEncoder(sos);
encoder.encode(image);
%>

JSP技术生成动态web页面

星期一, 06月 2nd, 2008

随着WEB技术de发展,WEB内容从一些静态de页到内容丰富de动态页.对于广大WEB开发人员来讲动态页面de生成是一个挑战.有许多de方法来试图解决这个问题,如plug-in技术及基于服务器端deAPIs等方法,但存在de一个问题是这些方法是针对某个特定deweb服务器,如Microsoft提供deASP技术就只针对它deIIS及Personal web服务器.
目前用于生成动态网页较为流行de方法有CGI、PHP及JavaServer Page(JSP)技术等.其中:CGI通过访问其它应用程序来获取信息并返回给浏览器,CGI程序通常用C或PERL语言来开发;Jsp则通过将Jsp组件编译成Java Servlet在服务器端运行来实现动态内容.下面从几个方面比较Jsp与传统CGIde特性:
可移植性:
大多WEB服务器支持CGI接口,但CGI程序自身并不能跨平台运行; Java Servlet程序则具有JAVA程序de优点,可运行在任何平台之上,大多数WEB及应用服务器都支持JAVA及servlet API.
性能上:
传统deCGI环境下,每一次client对CGI程序de请求,都使服务器产生一个新de进程来装载、执行CGI程序.大量de并行请求大大降低了其性能;JSP则没有这个局限,每个程序装载一次,并驻留在服务器内存为以后请求服务.另外JSP在多线程de编写与控制方面比CGI容易得多.
开发及发布:
由于Java Servelt具有JAVAde所有优点,开发起来也相对容易,java简化了对异常de处理;它de面向对象特性使开发人员de协作成为一件简单de事.JSP技术从如下几个方面加快动态网站开发:
1) 将静态页面de开发和动态内容de生成分开
JSP中通过使用HTML或XML标记来规划、设计WEB页de布局和风格;而用JSP标记来实现动态de内容,生成动态内容de部分被封装起来运行于服务器端;这样页面布局和风格可单独编辑与调试而不影响动态内容生成.
2) 组件de重用
多数JSP页通过重用无平台无关de组件—javaBeans来完成复杂de要求.这些组件可在开发人员中重复使用.
3) 通过标记来简化页面开发
通过JSP提供了标记,开发人员可以很容易使用beans组件,设置和访问它们de属性.同时JSP也允许用户自定义标记,还可接受第三方开发de标记,从而可以方便使用第三方提供de功能组件.
在对JSPde特点有所了解之后,接下来就谈谈JSPde安装与开发实例.(操作系统以Nt4.0为例)
为运行JSP page需要安装jdk及jswdk.首先安装jdk,在jdk安装完成后,要确保javac及java能正常工作.然后安装jswdk,实际上只需把jswdk解压到一个目录即可.为了使jswdk正常运行,还需要对环境变量CLASSPATH做如下修改:
如果使用JDK1.1,则不需修改CLASSPATH;如果使用JDK1.2,则设置环境变量JAVA_HOME,使其指向JDK安装路径.
完成上述工作后,就可以启动Java WebServer了.
执行jswdk目录下destartserver.bat文件来启动Java Server,该Web server使用de默认端口为8080.如果Web server新动后,需要重新启动则需要先停止已启动deWeb server,执行stopserver.bat可停止达到此目de.
JavaServer启动后,如果正常则在浏览器de地址中输入:http://localhost:8080/ 就可显示介绍Java Webserver Pagede页面.在jswdk目录下还有一个examples目录,这是jswdk中自带de一个web 应用, 一个web应用包含jsps, servlets,html files, images等资源.我也可以创建一个新deweb应用,从而把自己相关de文件放入其中.让我来分析一下如何创建一个新deweb 应用.
要创建一个新deweb 应用,需要在jswdk安装目录下新建一个目录,如创建一个名为mywebdeweb应用,其目录结构如下:

jswdk_inatall myweb web-inf
servlets
jsp beans
webapp.properties
servlets.properties
mime.properties
mappings.properties
其中:jswdk_install表示jswdkde安装目录;以properties为后缀de四个文件为属性文件,可从jswkd_install/web-inf下拷贝得到.修改jswdk_install目录下dewebserver.xml文件,加入如下一行,其作用是把myapp作相应de映射: <WebApplication id=”mybase1″ mapping=”/myweb” docBase=”myweb”/>
同时修改startserver.bat文件,把 myweb/web-info/jsp/beans目录加到相应de环境变量beanJars中;也可通过在CLASSPATH环境变量中加入该路径来实现.
要加入jsp文件,可把文件放到myweb目录下或它de下一级目录中;要加入servlet,只需把编译正确deservlet放到servlets中;而把编译正确dejava beans放到beans目录下.
请注意在对beans或servlet修改后,要使修改生效,需要重新启动Web Server.
了解这些规则之后,下面就创建第一个JSP文件 myfirst.jsp,其内容如下:
<html>
<head><title> My first Jsp file<titile>
</head>
<body>
<% out.println(”this is my first jsp file”); %>
</body>
</html>
将该文件放在jswkd_install\myweb目录下,如果Web server已启动,则在游览器地址中输入:
http://localhost:8080/myweb/myfirst.jsp
我就可以看到执行de结果.在完成第一个简单dejsp文件后,我可以编写一个java beans,并在jsp文件中调用该beans.
java bean源程序HelloWorld.java内容如下:
public class helloWorld {
public String name ;
public boolean setHello(String name){
this.name = new String(name);
}
public String sayHello()
{
return name;
}

}
用JDK编译该文件:
javac helloWorld.java
在成功编译后,将生成de字节码文件HelloWorld.class放到myweb/web-inf/jsp/beans目录下;
在下面jsp文件test.jsp中调用helloWorld,test.jsp内容如下:
<html>
<head>
<title> Jsp and java bean </title>
</head>
<body>
<jsp:useBean id=”helloBean” scope=”session” class=”HelloWorld” />
<%
String hello = “this is a bean test”;
helloBean.setHello(hello);
out.println(helloBean.sayHello() “<br>”);
%>
</body>
</html>
将该jsp文件放到jswdk_install\myweb\目录下
重新启动web Server,在浏览器地地址中输入:
http://localhost:8080/myweb/test.jsp
就可以显示执行结果;
注意到在test.jsp中
<jsp:useBean id=”helloBean” scope=”session” class=”HelloWorld” /> descope = “session”表明该对象创建后可在同一会话(session)de其它页引用.如我可以在aftertest.jsp中引用test.jsp中创建de对象,aftertest.jsp内容包含下面de相关代码:
<%
helloWorld rebean = (helloWorld)session.getValue(”helloBean”);
out.println(”bean used in aftertest.jsp” rebean.sayHello());
%>
要注意de是要引用de对象必须已创建,否则会出现异常.
下面看看在jsp中使用访问数据dejava beans例子.我所使用de数据库是oracle8,通过SQL*Net创建de数据库连接串名为begpinter,数据库服务器运行在名为begpinterserverde机器上,下面是JspJdbc.javade内容:
// You need to import the java.sql package to use JDBC
import java.sql.*;
import oracle.jdbc.driver.* ;
public class JspJdbc
{
Connection conn = null;

Public ResultSet rset = null;
public JdbcCheckup(){
// Load the Oracle JDBC driver
try{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
}catch(SQLException e1) {
System.err.println(”executeQuery: ” e1.getMessage());
}
}

public ResultSet executeQuery(String sql) {
rset = null;
try {
conn = DriverManager.getConnection
(”jdbc:oracle:thin:@bgpinterserver:1521:bgpinter”,”SCOTT”, “TIGER”);
Statement stmt = conn.createStatement();
rset = stmt.executeQuery(sql);
}catch(SQLException e1) {
System.err.println(”error: ” e1.getMessage());
}
return rset;
}
}
编译后将JspJdbc.class文件放入myweb\web-inf\jsp\beans目录下.在下面dejsp文件中调用beans,jspdb.jsp内容如下:
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<title>Database in Jsp</title>
</head>
<body>

<%@ page language=”java” import=”java.sql.*,oracle.jdbc.driver.*” errorPage=”errorpage.jsp” %>
<jsp:useBean id=”jspdatabase” scope=”page” class=”JspJdbc” />
<%
ResultSet rset = jspdatabase.executeQuery(”SELECT * FROM emp”);
out.println(”<table><tr><th>number</th><th>name</th></tr>”);
while (reset.next()) {
out.println(”<tr><td>” rset.getInt(”eptno”) “</td>”);
out.println(”<td>” rset.getString(”enameeptno”) “</td></tr>”);
}
rest.close();
out.println(”</table>”);
%>
</body>
</html>
其中用于显示异常deerrorpage.jsp内容为:
<html>
<body bgcolor=”red”>
<%@ page isErrorPage=”true” %>
<h1> The exception <%= exception.getMessage() %>
</body>
</html>
重新启动Web server使新创建dejava beans生效,如果与数据服务器连接正常,则在浏览器地址中输入
http://localhost:8080/myweb/jspdb.jsp
将显示查询结果.
通过上面de介绍,相信大家对Jsp有所了解.要进一步了解Jsp技术可访问下面de站点:
http://java.sun.com/products/jsp

JSP由浅入深(3)—— 通过表达式增加动态内容

星期一, 06月 2nd, 2008

在我前面de章节中,任何deHTML文件都可以转变成JSP文件,做法是通过改变它de扩展名为.jsp.当然,我要知道是什么使得JSP有用呢?答案是嵌入Javade能力.将下列文本放置在一个以.jsp为扩展名de文件中,比如说这个文件为myjsp.jsp,然后将这个文件放置到您deJSP目录下并且在浏览器上看它.以下是具体de相关代码:
<HTML>
<BODY>
Hello! The time is now <%= new java.util.Date() %>
</BODY>
</HTML>
这里要注意,每次您在浏览器中重载网页de时候,它就出现当前时间.字符系列<%= and %>de作用是圈起Java表达式,这个表达式将在运行de时候被计算.
正因为这样,使用JSP产生动态HTML网页来响应用户de动作才变为可能.
好吧,教程结束之后您最好作个练习:为不同de系统属性编写一个JSP用来输出由System.getProperty返回de数值,比如java.version、java.home、os.name、user.home以及user.dir等等.