Tomcat防止目录泄露

[不指定 2005/11/01 22:18 | by ipaddr ]
有时不输入页面,直接输入根目录下某个文件夹的名字,这个目录下的文件就会都列出来,这样是不安全的.我们需要在tomcat中进行设置:
打开tomcat的web.xml文件,加入:
<servlet>  
      <servlet-name>default</servlet-name>  
      <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>  
      <init-param>  
          <param-name>debug</param-name>  
          <param-value>0</param-value>  
      </init-param>  
      <init-param>  
          <param-name>listings</param-name>      <!--在这里加一个值-->
          <param-value>false</param-value>      <!--改成false就OK了-->  
      </init-param>  
      <load-on-startup>1</load-on-startup>  
</servlet>

JSP彩色验证码

[不指定 2005/10/25 22:22 | by ipaddr ]
生成有4个随机数字和杂乱背景的图片,数字和背景颜色会改变,服务器端刷新(用history.go(-1)也会变)
原型参考ALIBABA  http://china.alibaba.com/member/showimage

产生验证码图片的文件-----image.jsp

<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Color getRandColor(int fc,int bc){//给定范围获得随机颜色
       Random random = new Random();
       if(fc>255) fc=255;
       if(bc>255) bc=255;
       int r=fc+random.nextInt(bc-fc);
       int g=fc+random.nextInt(bc-fc);
       int b=fc+random.nextInt(bc-fc);
       return new Color(r,g,b);
       }
%>
<%
//设置页面不缓存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

// 在内存中创建图象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 获取图形上下文
Graphics g = image.getGraphics();

//生成随机类
Random random = new Random();

// 设定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

//设定字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));

//画边框
//g.setColor(new Color());
//g.drawRect(0,0,width-1,height-1);


// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
       int xl = random.nextInt(12);
       int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}

// 取随机产生的认证码(4位数字)
String sRand="";
for (int i=0;i<4;i++){
   String rand=String.valueOf(random.nextInt(10));
   sRand+=rand;
   // 将认证码显示到图象中
   g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
   g.drawString(rand,13*i+6,16);
}

// 将认证码存入SESSION
session.setAttribute("rand",sRand);


// 图象生效
g.dispose();

// 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());


%>

---------------使用验证码图片的文件---------a.jsp------------------------------------

<%@ page contentType="text/html;charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>认证码输入页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<form method=post action="check.jsp">
<table>
<tr>
<td align=left>系统产生的认证码:</td>
<td><img border=0 src="image.jsp"></td>
</tr>
<tr>
<td align=left>输入上面的认证码:</td>
<td><input type=text name=rand maxlength=4 value=""></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="提交检测"></td>
</tr>
</form>
</body>
</html>

-----------------验证的页面----------check.jsp

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<title>认证码验证页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>

<body>
<%
String rand = (String)session.getAttribute("rand");
String input = request.getParameter("rand");
%>
系统产生的认证码为: <%= rand %><br>
您输入的认证码为: <%= input %><br>
<br>
<%
 if (rand.equals(input)) {
%>
<font color=green>输入相同,认证成功!</font>
<%
 } else {
%>
<font color=red>输入不同,认证失败!</font>
<%
 }
%>
</body>
</html>

Tomcat5.0.28下AXIS完全安装手册

[不指定 2005/09/29 22:56 | by ipaddr ]
Tomcat5.0.28下AXIS完全安装手册

IPADDR(漂,一直漂,BCOMCN,ASPBIZ 马甲可真多)原创,转载请注明.

网上有一些AXIS的安装文档,不是很详细,而且,我按网上的资料安装得不是很成功,老是报错,可能是因为使用了较新版本的Tomcat,AXIS.

经过多番努力,终于配置成功,把安装过程和心得和大家分享一下.

一.简介
什么是SOAP?SOAP是一个应用程序间的基于XML的通信工具和规范.SOAP最初由MicroSoft和Userland公司开发,已经演化了好几个版本,当前的版本SOAP1.1正飞速发展.W3C的XML协议工作组正努力把它发展为一个真正的开发的标准.SOAP1.2草案已经发布,它能澄清1.1版规范的容易混淆的地方.

什么是Axis?Axis总体上是一个SOAP引擎,但又不仅仅是个引擎,它还:1)是一个简单的独立的服务器2)是一个可插入到servlet引擎(如Tomcat)中的服务3)可扩展的支持WSDL4)能根据WSDL产生JAVA文件/类5)包括一些例子程序6)包括一个可以监控TCP/IP包的工具

Axis起源于IBM的SOAP4J,是Apache SOAP的第三代产品,相对于以前的版本,它有如下特性:1)快速,它使用了基于事件的SAX解析机制.2)灵活,用户可以灵活定制扩展.3)稳定,接口将会变动很小.4)基于组件开发.5)支持WSDL1.1

二.准备
1.安装Tomcat5.0.28,这是当前稳定版本.Tomcat运行在80端口.访问http://localhost/检查Tomcat是否安装成功.
(Tomcat+Apache+Mysql的整合安装,详见另外一篇.)
2.下载AXIS:
官方站点:http://xml.apache.org/axis/index.html
下载软件:axis-bin-1_2_1.tar.gz
3.下载相关包:
a.mail.jar 下载地址:http://java.sun.com/products/javamail
b.activation.jar 下载地址:http://java.sun.com/products/javabeans/glasgow/jaf.html
c.xerces.jar 下载地址:http://xml.apache.org/xerces-j/index.html
d.xmlsec-1.2.1.jar 下载地址:http://xml.apache.org/security/

三.安装
1.将四个相关包,全部拷到<CATALINA_HOME>/common/lib目录(Tomcat安装目录下的common/lib)下
2.解压axis-bin-1_2_1.tar.gz,将压缩包里的webapps/axis拷到网站根目录下(如果Tomcat是默认配置,那就是<CATALINA_HOME>/webapps/ROOT目录).
3.
修改Tomcat的配置文件server.xml(<CATALINA_HOME>/conf/server.conf)
在</Host>前加入:
<Context path="/axis" docBase="C:\Program Files\Apache Software Foundation\Tomcat\webapps\ROOT\axis" debug="0" reloadable="true" > </Context>
(docBase里是你的实际axis存放的目录)
注意,此步至关重要,AXIS的安装文档中没有提到此步,导致很多人安装不成功.
如果没有此步,访问http://localhost/axis时,提示如下错误:
Can't find bundle for base name i18n, locale en_US(zh_CN)
表面是上看i18n国际化的问题,但既使i18n.properties,i18n_zh_cn.properties存在,也无法找到.
网上很多朋友安装到此,无法继续下去,我也找了很多资料,都没有解决.后来查看Tomcat的文档,猜测是Tomcat配置的问题,经测试,终于成功.
可能Tomcat的前期版本,不需此设置.没有测试过.
另外,也可以将axis/WEB-INF/classes/*,axis/WEB-INF/lib/*的所有文件,拷到<CATALINA_HOME>/common/lib/这个方法比较麻烦.
注:AXIS客户端,需要拷贝axis/WEB-INF/lib/*到<CATALINA_HOME>/common/lib/

四.测试
重新启动Tomcat.
1.访问:http://localhost/axis
点击:Validation - Validate the local installation's configuration测试是否有错.
2.
写个小程序:
public class HelloService
{
public String sayHello(String username)
{
 return "Hello:"+username;
}
}
另存为axis目录下HelloService.jws
再能过WEB访问:
http://loalhost/axis/HelloService.jws
http://loalhost/axis/HelloService.jws?method=sayHello&parameter=ipaddr


另外,如果是Apache+Tomcat整合在一块,以上配置后,还需要更改Apache的配置,在httpd.conf中加入:
JkMount /axis/* ajp13
通过Apache可以访问axis的Servlet

五.AXIS介绍补充
Apache Axis是Apache WebService项目中的子项目,其最初起源于IBM的"SOAP4J",应该属于最早的一批用于构造基于SOAP应用的Framework。

目前Apache Axis已经发展到了第三代,其核心是一个SOAP处理器,用于开发包括客户端,服务器端,SOAP Gateway等各种应用。事实上Apache Axis在了1.0版后,其发行版本还包括了完整的J2EE服务器插件, WSDL支持和生成,TCP/IP监视器等组件,从这个意义上来说Apahce Axis已不仅仅是个SOAP框架了,它包含了除了UDDI外对整个Web Service协议栈(Protocol Stack)的支持。

对大多数关心Macromedia产品的人来说,Macromedia是Axis小组的核心成员之一,他们在几乎所有J2EE服务器端的产品线中包含了Axis,也就是说Macromedia对WebService的支持是通过Apache Axis实现的,这其中包括了JRun, Flex, ColdFusion。即便是Flash Remoting,由于其核心还是SOAP,所以也是使用了Axis的SOAP框架。

和.NET的WS不同,Axis是一个非常易于扩展的体系结构,其设计的核心思想是建立一个数据处理的管道,通过把handler编织成一条处理链从而无限扩展其可能性。打个比方,在输入部分开发人员既可以编写基于HTTP Basic Authentication的用户验证模块也可以插入SOAP Auth模块用于验证请求,而输出部分既可以通过XML binding把结果输出为SOAP XML也可以象Flash Remoting那样把结果输出成binary格式。

同时Axis也提供了所有的处理模块,使得用户能在最快的时间把服务器组件发布成WS.总的来说Axis有以下几个特点:


速度 - Axis 使用 SAX 而不是 DOM 来处理XML请求,所以速度上有很大的改善。
灵活性 - 刚才也提到了,Axis的体系结构是一个全开放式的处理器,所以扩展模块极为方便。面向组件的发布方式 - 处理链上可重复使用组件来完成类似的操作。
Transport 框架 - Axis的核心和底层的transport完全分离,也就是说不管WS的Transport是HTTP, FTP, MAIL, MESSAGE QUEUE,只要插入对应的Transport模块即可,而不需改动其他部分。
WSDL1.1支持 - 可自动由Java Object生成WSDL


Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。

Lucene的作者:Lucene的贡献者Doug Cutting是一位资深全文索引/检索专家,曾经是V-Twin搜索引擎(Apple的Copland操作系统的成就之一)的主要开发者,后在Excite担任高级系统架构设计师,目前从事于一些INTERNET底层架构的研究。他贡献出的Lucene的目标是为各种中小型应用程序加入全文检索功能。

Lucene的发展历程:早先发布在作者自己的www.lucene.com,后来发布在SourceForge,2001年年底成为APACHE基金会jakarta的一个子项目:http://jakarta.apache.org/lucene/

参考:

http://www.chedong.com/tech/lucene.html

http://hedong.3322.org/archives/000206.html

WindowXP(2000)下Apache2+Tomcat+PHP4+Mysql的安装

#Ipaddr(bcomcn)原创笔记,转载请注明

一.安装Apache2
下载地址:http://www.apache.org
下载installer的安装版本,直接根据提示安装完成。
配置httpd.conf


二.安装PHP
下载地址:http://www.php.net
下载Windows的ZIP包,解压到c:\php
1.将c:\php加入到系统环境变量PATH
如果不加入环境变量,很多库需要拷到系统目录,我觉得还是加环境变量方便
2.将c:\php\php4ts.dll文件拷到c:\windows(2000是c:\winnt)
此步不可省略
3.修改php.ini-recommand为php.ini,修改php.ini,移动到c:\windows
注:如果php.ini不拷到c:\windows,则需要在httpd.conf里配置PHPInDir="C:\php"
doc_root = c:\website\htdocs
extension_dir = c:\php\extensions
session.save_path = c:\phptemp

4.修改httpd.conf
加入:
LoadModule php4_module "c:/php/sapi/php4apache2.dll"
#注:网上很多文章此处有错误,误写成"c:/php/php4apache2.dll"
AddType application/x-httpd-php .php
DirectoryIndex ....   index.php (在索引页中,加入index.php)

三.安装Mysql
直接到www.mysql.org下载For Windows版的,根据提示安装即可。

四.安装phpmyadmin
到www.phpmyadmin.net下载最新版的phpmyadmin
解压到网站根目录的/mysql中
将config.inc.php里的auth_type改为http
如果是4.1版本以上的Mysql,需要将认证密码改一下:
use mysql
update user set Password=old_password('zhoutang');
flush privileges;

五.安装Tomcat
三步安装Tomcat
在Wind2000系统上都已经成功安装Tomcat,只需要三步:

第一步:

下载准备必备文件:
1.jakarta-tomcat-4.1.31.exe (安装文件)        http://jakarta.apache.org/tomcat/index.html
2.j2sdk-1_4_2_09-windows-i586-p.exe (Jdk1.4)         http://java.sun.com/j2se/1.4/download.html
3.mysql-connector-java-3.1.10.zip (支持数据库)               http://www.mysql.com/downloads/api-jdbc.html

第二步:
运行j2sdk-1_4_2_09-windows-i586-p.exe,安装在c:\program files\jsdk

在windows2000的控制面板 中 选择 '系统',在'高级'页 选择'环境变量'
新增:

JAVA_HOME=c:\program files\jsdk
CLASSPATH=.;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

第一行是设置Windows下JAVA_HOME环境变量,是必须设定的,后面两行主要对Windows下命令窗口起作用(DOS窗口)。注意CLASSPATH的第一

个参数是“.”,如果这个不设置,使用java hello.helloWorld 会报Exception in thread "main" java.lang.NoClassDefFoundError

第三步:

运行jakarta-tomcat-4.1.31.exe,并且,将Tomcat安装为Windows的服务运行。
解压mysql-connector-java-3.1.10.zip,我们需要里面的mysql-connector-java-3.1.10-bin.jar文件,拷贝这个文件到tomcat的安装目录的

common/lib下面

启动Tomcat,只需启动Windows服务里的Tomcat就行

在浏览器键入http://localhost:8080/ 看到Tomcat的启动页面.


测试:
Tomcat+JDK+mySQL完整测试:
a.在tomcat/webapps下建立子目录test
b.复制目录(注意是整个目录)tomcat/webapps/ROOT/WEB-INF到新建的test目录下  
c.在test目录下新建index.jsp文件:
<%@ page contentType="text/html;charset=gb2312"%>  
<%@ page import="java.sql.*"%>  
<html><title测试JSP连接Mysql页面</title><body>
<%Class.forName("org.gjt.mm.mysql.Driver").newInstance();  
String url ="jdbc:mysql://localhost:3306/mysql?user=root&password=&useUnicode=true&characterEncoding=GB2312";  
Connection conn= DriverManager.getConnection(url);  
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);  
String sql="select * from user";  
ResultSet rs=stmt.executeQuery(sql); %>  
<table><tr><td>您的第一个字段内容为:</td>  
<td>您的第二个字段内容为:</td>  
</tr>
<%while(rs.next()) {%>  
<tr><td>  
<%=rs.getString(1)%> </td><td>  
<%=rs.getString(2)%> </td></tr>  
<%}%>  
</table>  
<%out.print("Tomcat+JDK+mySQL完整测试,恭喜你,数据库操作成功!#Ipaddr原创笔记,转载请注明");%>  
<%rs.close();  
stmt.close();  
conn.close();  
%>
</body>
</html>
d.在浏览器中输入:http://localhost:8080/test,若出现“Tomcat+JDK+mySQL完整测试,恭喜你,数据库操作成功!”,则说明你的Tomcat+JDK+mySQL整体配置成功。

SugarCRM的JPGraph中文乱码解

[不指定 2005/06/25 22:25 | by ipaddr ]
SugarCRM是一个开源的CRM软件.

基于PHP+Mysql的B/S系统.

2.0版的使用JPGraph生成统计图形,但中文会乱码.

原创:一直漂(e.it(at)163.com) 转载请说明

处理办法:

1.修改:

modules/Opportunities/Chars.php

第36行,直接加入一行:

return FF_SIMSUN;

2.修改:

jpgraph/src/jpg-config.inc

定义如下TTF目录(Linux是这个目录,Windows是winnt/fonts)

DEFINE("TTF_DIR","/usr/X11R6/lib/X11/fonts/TTF/");

修改以下定义:

DEFINE('USE_TRUECOLOR',false);

(修改后字体颜色正常.)

3.上传

simhei.ttf

simsun.ttc

这两个字体文件,到服务器的/usr/X11R6/lib/X11/fonts/TTF/

项目的需要,要使用crystal做报表显示,水晶报表功能就是强大,做的报表就是漂亮,不过在使用过程中经常会遇到一些问题,很是麻烦,最可气的是其随软件的帮助有时都会误导你。下面我将我这次的经历展示一下,以免同道再走我的弯路。


我的开发环境是win xp professional + visual studio for .net 2002 + crystal for .net。


先是设计程序,设计报表rpt,关于怎么设计报表,这是个很复杂的事情,不过在这不是问题,也不是我要叙述的重点,反正我在上述环境下设计出来了一个可以显示报表的dotnet window应用程序,在这个开发环境下运行正常。


我尝试着把这个程序制作成一个MSI安装文件,然后去部署到没有visual studio for .net 2002 + crystal for .net的机器上。过程是这样的:


1.      在vs.net中的当前当前解决方案中新建一个安装项目。


2.      添加一个项目输出,把上述那个程序项目的主输出加入。


3.      系统会把这个引入的项目的相关依赖项都包含到“检测到的依赖项”文件夹中,这些依赖项都会被打包到MSI中。


4.      build


以为系统会自动侦测出涉及到crystal for .net要使用到的组件,打包完后去目标机器安装(目标机器一共三台,分别是win98第二版,win2000 server,win xp professional),结果三台机器安装完后运行结果一样,当显示报表时,出现一下错误:






Cannot find KeycodeV2.dll, or invalid keycode






查找vs.net带的MSDN,发现部署Crystal Reports 运行时的说明:


分发应用程序时,须确定您的安装中所需要的 Crystal Decisions 文件。您要包括的文件取决于是否在报表中使用图表、地图和其他公式语言函数,同时也取决于报表所用的数据源以及您希望向最终用户提供的导出选项。幸运的是,如果您在使用 Microsoft Installer (MSI),则可以在您的安装包中包括的合并模块 (MSM) 以简化分发。


MSI 合并模块可在“C:\Program Files\Common Files\Merge Modules”目录中找到。根据您正在分发的组件和语言,您可选用不同的合并模块。这些合并模块分为三类:托管组件、数据库访问和密钥号码。


托管组件 MSM 处理所有托管组件的分发,其中包括 Windows 窗体查看器、Web 窗体查看器和所有 Crystal Decisions 命名空间。对于使报表运行所需的所有其他文件,由数据库访问 MSM 处理其分发。其中包括数据库、导出和图表驱动程序。KeyCode MSM 处理 Crystal Decisions 密钥号码的安装,这样您的用户在查看报表时,就不会被要求注册他们的 Crystal 版本。






具体操作步骤:


1.      打开 Windows 应用程序。


在解决方案资源管理器中,右击 Windows 应用程序解决方案,指向“添加”,然后单击“新建项目”。

在“添加新项目”对话框中,选择“项目类型”窗格中的“安装和部署项目”,然后选择“模板”窗格中的“安装项目”。单击“确定”按钮。

在解决方案资源管理中,右击安装项目,指向“添加”,然后单击“项目输出”。

在“添加项目输出组”中,选择“主输出”,然后单击“确定”。

将自动添加所有依赖项,如 Managed.msm。


在解决方案资源管理器中,右击安装项目,指向“添加”,然后单击“合并模块”。

在“添加模块”对话框中,选择下列要添加到安装项目的合并模块,然后单击“打开”:

Database_Access.msm

Database_Access_enu.msm

regwiz.msm

VC_CRT.msm、VC_STL.msm( 如果您部署的 Windows 应用程序使用 ADO.NET 数据集,则还需要包括 VC_CRT 和 VC_STL 合并模块)

在解决方案资源管理器中,右击 regwiz.msm 文件,然后选择“属性”。

在“属性”窗口中,展开 MergeModuleProperties,然后在“许可证密钥”属性框中输入一个有效的许可证密钥(密钥AAP5GKS0000GDE100DS)。

注意   每当部署 Crystal Reports 应用程序时,必须提供许可证密钥。


从“生成”菜单中,选择“生成解决方案”以生成应用程序。

按照上述步骤制作MSI安装文件,再次部署到目标机器(当部署到客户机或服务器时,应始终确保该计算机安装了 .NET Framework)。同样是安装到上述win98第二版,win2000 server,win xp professional这三台机器,结果是:


1.        win98第二版,win xp professional这两台机器上运行正常,报表显示正常,报表导出也正常。


2.        win2000 server机器上安装正常,显示报表正常,可是一旦点击了报表显示器中的导出图标,整个程序就死掉了,在任务管理器显示“未响应”,只能强行关掉。


这个结果勉强还可以接受,大不了这个程序不在win2000运行就是了。不过又发现一个新的问题,就是导出的word文档跟在报表显示器中显示的不是严格一致的,有一些差别,而且这个差别到了不可忍受的地步:


1.        在报表显示器中表格中的文字显示正常,在word中这些表格中的文字被转换成图文框中的,可是转换的图文框高度小了,导致了显示的文字的下面有一小部分显示不出来,效果就是一行文字都被吃掉了下面一部分。


2.        一张报表在报表显示器中显示的正好是一页纸,边距都很准确,可是导出的word文档,报表的内容的尾部跑到了页面以外。在设计crystal报表时页面设置是A4的,估计是导出到word文档时纸张的尺寸变了,不是A4了,而且导出的word文档的“页面设置”是暗的,不允许修改。


而这个软件中的报表一定是要导出到word的,这样的导出效果是不能接受的,于是想到是不是可是升级到crystal9 试试看。


crystal9是完全支持dotnet的,Crystal Reports 9 将其功能整合到了 Visual Studio .NET 集成开发环境 (IDE) 中,代替原先Crystal Reports for .net,从而增强了 Visual Studio .NET (VS .NET) 的开发效能。


安装了Crystal Report 9 Advanced Edtion 中文版,看vs.net的帮助中关于,看到crystal的信息显示为:Crystal Reports 9 for Visual Studio .NET,升级成功。


重新编译程序,在开发机器上运行程序,报表显示正常,主要是要看导出word文档显示是否正常,在报表显示器中点击导出按钮,导出word文档,结果是word文档显示同报表显示器中显示的报表一模一样,心中暗喜,问题解决了。


OK,现在要到部署的问题了。


在编程的时候,经常遇到要判断一个字符串中的字符是否全部是数字(0-9),本来是一个很容易实现的功能,但程序员首先会想到的是,这样简单的功能有没有现成的函数可以用呢?VB.NET中有个IsNumeric(object),C#中只有判断单个字符的Char.IsNumber(),IsNumeric可以判断double类型的数字字符串,但无法排除正负号和小数点,如果判断字符串是否是一个数的话用它挺合适,但不能用来判断字符串是否全部由数字组成的。没现成的方法了,只好自己写函数:

public static bool IsNum(String str)
{
   for(int i=0;i    {
       if(!Char.IsNumber(str,i))
       return false;
   }
   return true;
}

或用正则表达式:"^\d+$"

还可以用Int32.Parse()抛出的Exception来判断:

try
{
   Int32.Parse(toBeTested);
}
catch
{
   //发生了异常,那么就不是数字了。
}

那么哪一种方法最好呢?各有优劣。我顺手写了一个程序对每一种方法所需要的时间进行了测试。测试程序Main()内容如下:

Regex isNumeric = new Regex(@"^\d+$");
int times = 10000000;
int start, end;
int i;
string toBeTested = "6741s";

#region Test user function
start = System.Environment.TickCount;
for(i=0; i{
TimingTest.IsNum(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("User function Time: " + (end-start)/1000.0 + " Seconds");
#endregion

#region Test Regular Expression
start = System.Environment.TickCount;
for(i=0; i{
isNumeric.IsMatch(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("Regular Expression Time: " + (end-start)/1000.0 + " Seconds");
#endregion

#region Test Exception
start = System.Environment.TickCount;
for(i=0; i{
try
{
 Int32.Parse(toBeTested);
}
catch
{
 //发生了异常,那么就不是数字了。
}

}
end = System.Environment.TickCount;
Console.WriteLine("Exception Time: " + (end-start)/10.0 + " Seconds");
#endregion

#region Test VB.NET IsNumeric()
start = System.Environment.TickCount;
for(i=0; i{
Microsoft.VisualBasic.Information.IsNumeric(toBeTested);
}
end = System.Environment.TickCount;
Console.WriteLine("VB.NET IsNumeric() Time: " + (end-start)/100.0 + " Seconds");
#endregion


   因为Exception所用的时间太长,所以只测试了1/100,这样不太严谨,但是数量级不会错的。

三次运行的结果是:
User function Time: 1.938 Seconds
Regular Expression Time: 11.921 Seconds
Exception Time: 600 Seconds
VB.NET IsNumeric() Time: 40.797 Seconds
User function Time: 1.953 Seconds
Regular Expression Time: 12.016 Seconds
Exception Time: 590.6 Seconds
VB.NET IsNumeric() Time: 40 Seconds
User function Time: 2.000 Seconds
Regular Expression Time: 12 Seconds
Exception Time: 595.3 Seconds
VB.NET IsNumeric() Time: 39.69 Seconds
平均时间:

1.964
11.979
595.3
40.162

速度之比依次约为:303 : 49.7 : 1 : 14.82

结果很明显,自定义函数速度最快,异常的速度最慢。假如不需要抛异常的话string toBeTested = "67412";结果就成了:

User function Time: 1.922 Seconds
Regular Expression Time: 9.64 Seconds
Exception Time: 3.1 Seconds
VB.NET IsNumeric() Time: 39.07 Seconds
速度之比依次约为:20.33 : 4.05 : 12.60 : 1

结论:

   自定义函数可以获得最大的灵活性和最高的性能,而且复杂性也不高,是最佳的方法。
   正则表达式法和IsNumeric速度在同一个数量级上,但正则表达式可以确定一种字符串的格式,比如规定一定要有或没有小数点等,而IsNumeric无法做到。
   使用异常是应该避免的。建议仅把Exception作为处理异常的一种手段,而不是作为控制流程的一种手段。测试也表明,当有异常抛出时,要消耗大量的资源。
   IsNumeric是现成的函数,用起来最省事,只能判断所给的参数是否是数值(boolean/byte/int16/int32/int64/single/double/decimal),无法作进一步的要求(是否有小数点等)。但IsNumeric的参数是object,不局限于string。

   写到这里,我不禁想,还有没有比自定义函数更快的方法呢?答案是肯定的。在前面的自定义函数中,用的是Char.IsNumber()函数,这个函数不仅能判断标准ASCII码中的'1',甚至对全角中文的'1'的判断也是true,可见Char.IsNumber()判断的是所有的Unicode字符中的数字,其他语言中的数字也包括了。假如我们只允许ASCII中的'1'的话,我们可以这样改:

public static bool IsNum(String str)
{
for(int i=0;i {
 if(str[i]<'0' || str[i]>'9')
  return false;
}
return true;
}

   测试结果也令我吃惊,这样比原来的IsNum速度提高了近10倍,平均执行时间是0.205秒!

   结果全部出来了,该怎样选择大家心里肯定已经有数了,我也不需要再说什么了。


Vs.net中部置应用程序卸载

[不指定 2005/04/20 22:29 | by ipaddr ]
     相信很多人都做过安装程序,目前最大功能最全的当属InstallShield,但是InstallShield的语法学习起来实在费劲,相对而言vs.net自带的安装部署短小精悍,且使用C#语法,对于一般C#开发者来说使用起来就极为简便,在对其作了一些研究之后,发现vs.net的安装部署项目的功能也已经非常好用,一般的程序安装都可以轻松实现,当然,在研究的过程中也发现了一些缺陷,最主要一个问题是安装后卸载不方便,一定要去控制面板里。可以按如下的方法解决,在程序里添加一个卸载的快捷方式。


1.新建一C# Windows From项目,完成项目的工作

2.菜单-》文件-》添加项目-》新建项-》安装部署项目-》安装向导

选择上面那个项目的主输出。

在安装项目的属性栏中会显示出"XXX部署项目属性",在第一个AddRemoveProgramsIcon属性后"浏览"到你的ICO图标,接着在下面Author输入作者名,也就是你的名字,其他Localization是语言属性,Manufacturer,ProductName的属性将是用户在安装时默认设置的文件夹路径一部分了,设置Title为你的应用程序标题名称。

3.右击"安装项目"上,选择文件系统视图

在应用程序文件夹,添加一个文件,如果是WIN98下的安装,请选择WIN98操作系统目录下的msiexec.exe文件(一般在c:\windows\system目录下);如果是其他,比如WIN2K系列,请选择该操作系统目录下的msiexec.exe文件(一般在\winnt\system32目录下)。

4.在文件系统视图的"用户程序菜单"里,添加一个目录,命名为项目的名字,

并且,在这个目录里,添加一个快捷方式,指向项目的主输出,

再添加一个快捷方式,指向加入的文件Msiexec.exe,命名为:"卸载",

5.在解决方案里,选择安装项目,再打开属性视图,打开安装项目的属性面板,里面有一项:

ProductCode  {5284694C-24C1-4FCF-A705-D4B9A0081274}

把后面的{5284694C-24C1-4FCF-A705-D4B9A0081274},复制一下。

6.在"卸载"快捷方式的属性里,有一个叫Arguments的属性栏,在属性栏中首先填入"/x"后加一个空格,再"粘贴",将ProductCode的属性值COPY至此。

7、再在VS.Net的顶部菜单栏中"生成"-"生成 XXXX"(XXXX为你的项目名称)

8、从微软网站上http://www.microsoft.com/downloads/直接下载Microsoft® .NET Framework 1.1 版可再发行组件包(dotnetfx.exe文件),COPY到您的发布生成的目录中,再放上你的安装说明及提示文件等。安装说明中提示用户首先安装dotnetfx.exe,再点击你的应用程序进行运行即可。

参考:

http://www.microsoft.com/China/Community/program/originalarticles/TechDoc/deployNETApp.mspx
分页: 12/13 第一页 上页 7 8 9 10 11 12 13 下页 最后页 [ 显示模式: 摘要 | 列表 ]