|
2006年8月9日
lxq@lxq:~/tmp$ tree
.
|-- Makefile
|-- bin
| `-- Makefile
|-- hello
| |-- Makefile
| |-- hello
| `-- hello.c
`-- tmp
3 directories, 5 files
cat Makefile
SRCBASE := $(shell pwd) #获取当前目录
ELEASEDIR := $(shell (cd $(SRCBASE)/.. && pwd -P))
print:
echo ${ELEASEDIR}
install: all
install -d ${ELEASEDIR}/tmp
$(MAKE) -C ./hello clean #切换到hello目录执行clean目标
$(MAKE) -C ./hello hello #切换到hello目录执行hello目标
$(MAKE) -C ./hello $@ #切换到hello目录执行install目标
all clean:
ifneq ($(wildcard hell),) #如果有hell这个文件就执行里面的动作
$(MAKE) -C ./bin $@ #切换到hello目录执行all\clean目标
endif
.PHONY: all clean install
cat hello/Makefile
clean:
ifneq ($(wildcard hello),)
rm hello
endif
hello:
gcc -o hello hello.c
install:
-cp hello ../bin/
cat hello/hello.c
#include <stdio.h>
int main()
{
printf("hello");
exit(0);
}
新员工培训建议
开始模式
开发的软件(VI,代码
开发的技巧(如VI的使用,如果新员工较熟悉,可略过)
1.代码规范 编码质量要求
关于代码文档 发送 由经验比较丰富的程序员讲解一下要求,对新员工的前几次编码进行检查
2。项目架构
项目的文档(原理图,开发文档)
项目的整体架构
1。(硬件构成 CPU,模块,最好有相关的原理图)
2。软件整体结构,可从makefile编译开始讲起
用到的开源的软件包,将各种二进制文件打包,数据流程,进程启动通信机制(如果有相应的架构图,流程图最好)
与工作相关的(现在或将来要做的和急需要了解的协议,资料)
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229651
发表时间: 2008年06月09日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
过滤器总结 一、Servlet过滤器的概念:
Servlet过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改。
Servlet过滤器本身并不产生请求和响应对象,它只能提供过滤作用。Servlet过期能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和Response内容。
Servlet过期负责过滤的Web组件可以是Servlet、JSP或者HTML文件。
二、Servlet过滤器的特点:
A.Servlet过滤器可以检查和修改ServletRequest和ServletResponse对象 B.Servlet过滤器可以被指定和特定的URL关联,只有当客户请求访问该URL时,才会触发过滤器 C.Servlet过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象
三、Servlet过滤器的作用:
A.查询请求并作出相应的行动。 B.阻塞请求-响应对,使其不能进一步传递。 C.修改请求的头部和数据。用户可以提供自定义的请求。 D.修改响应的头部和数据。用户可以通过提供定制的响应版本实现。 E.与外部资源进行交互。
四、Servlet过滤器的适用场合:
A.认证过滤 B.登录和审核过滤 C.图像转换过滤 D.数据压缩过滤 E.加密过滤 F.令牌过滤 G.资源访问触发事件过滤 H.XSL/T过滤 I.Mime-type过滤
五、Servlet过滤器接口的构成:
所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:
A.init(FilterConfig): 这是Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数
B.doFilter(ServletRequest,ServletResponse,FilterChain): 这个方法完成实际的过滤操作,当客户请求访问于过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器
B.destroy(): Servlet容器在销毁过滤器实例前调用该方法,这个方法中可以释放Servlet过滤器占用的资源
六、Servlet过滤器的创建步骤:
A.实现javax.servlet.Filter接口 B.实现init方法,读取过滤器的初始化函数 C.实现doFilter方法,完成对请求或过滤的响应 D.调用FilterChain接口对象的doFilter方法,向后续的过滤器传递请求或响应 E.销毁过滤器
七、Servlet过滤器对请求的过滤:
A.Servlet容器创建一个过滤器实例 B.过滤器实例调用init方法,读取过滤器的初始化参数 C.过滤器实例调用doFilter方法,根据初始化参数的值判断该请求是否合法 D.如果该请求不合法则阻塞该请求 E.如果该请求合法则调用chain.doFilter方法将该请求向后续传递
八、Servlet过滤器对响应的过滤:
A.过滤器截获客户端的请求 B.重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流 C.将请求向后续传递 D.Web组件产生响应 E.从封装后的ServletResponse中获取用户自定义的输出流 F.将响应内容通过用户自定义的输出流写入到缓冲流中 G.在缓冲流中修改响应的内容后清空缓冲流,输出响应内容
九、Servlet过滤器的发布:
A.发布Servlet过滤器时,必须在web.xml文件中加入<filter>元素和<filter-mapping>元素。
B.<filter>元素用来定义一个过滤器: 属性 含义 filter-name 指定过滤器的名字 filter-class 指定过滤器的类名 init-param 为过滤器实例提供初始化参数,可以有多个
C.<filter-mapping>元素用于将过滤器和URL关联: 属性 含义 filter-name 指定过滤器的名字 url-pattern 指定和过滤器关联的URL,为"/"表示所有URL
十一、Servlet过滤器使用的注意事项
A.由于Filter、FilterConfig、FilterChain都是位于javax.servlet包下,并非HTTP包所特有的,所以其中所用到的请求、响应对象ServletRequest、ServletResponse在使用前都必须先转换成HttpServletRequest、HttpServletResponse再进行下一步操作。
B.在web.xml中配置Servlet和Servlet过滤器,应该先声明过滤器元素,再声明Servlet元素
C.如果要在Servlet中观察过滤器生成的日志,应该确保在server.xml的localhost对应的<host>元素中配置如下<logger>元素: <Logger className = "org.apache.catalina.logger.FileLogger" directory = "logs" prefix = "localhost_log."suffix=".txt" timestamp = "true"/>
常用的过滤器实例:
//对整站编码的过滤
public void doFilter(ServletRequest request, ServletResponse sresponse,FilterChain chain) {
try{
request.setCharacterEncoding("GBK");
chain.doFilter(request, sresponse);
}catch(Exception e){
e.printStackTrace();
}
}
//对用户登陆进行验证
public void doFilter(ServletRequest srequest, ServletResponse sresponse,FilterChain chain) {
try {
HttpServletRequest request = (HttpServletRequest) srequest;
HttpServletResponse response = (HttpServletResponse) sresponse;
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null) {
response.sendRedirect("/test/index.html");
} else {
chain.doFilter(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//对用户权限进行过滤
public void doFilter(ServletRequest srequest, ServletResponse sresponse,FilterChain chain) {
try {
HttpServletRequest requst = (HttpServletRequest) srequest;
HttpServletResponse response = (HttpServletResponse) sresponse;
HttpSession session = requst.getSession();
User user = (User) session.getAttribute("user");
String ad=user.getIsAdmin().toString();
if (user == null || ad.equals("0")) {
response.sendRedirect("/test/main.jsp");
} else {
chain.doFilter(srequest, sresponse);
}
} catch (Exception e) {
e.printStackTrace();
}
}
web.xml中的配置
encodingfilter
filter.EncodingFilter
firstfilter
filter.FirstFilter
secondfilter
filter.SecondFilter
encodingfilter
/*
firstfilter
/web/*
secondfilter
/web/Charge.jsp
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229649
发表时间: 2008年06月10日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
commons-logging和log4j总结
简单的说log4j就是帮助开发人员进行日志输出管理的API类库。它最重要的特点就
可以配置文件灵活的设置日志信息的优先级、日志信息的输出目的地以及日志信息的输出格式。
Log4j除了可以记录程序运行日志信息外还有一重要的功能就是用来显示调试信息。程序员经常会遇到脱离java ide环境调试程序的情况,这时大多数人会选择使用System.out.println语句输出某个变量值的方法进行调试。这样会带来一个非常麻烦的问题:一旦哪天程序员决定不要显示这些System.out.println的东西了就只能一行行的把这些垃圾语句注释掉。若哪天又需调试变量值,则只能再一行行去掉这些注释恢复System.out.println语句。使用log4j可以很好的处理类似情况。
log4j使用方法
1、定义配置文件
首先使用配置文件将使我们的应用程序更加灵活配置log日志输出方式包括输出优先级、输出目的地、输出格式。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件log4j.properties(键=值)。下面将介绍使用log4j.properties文件作为配置文件的方法:
①配置根Logger,其语法为:0
log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。
②配置日志信息输出目的地Appender,其语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class log4j.appender.appenderName.option1 = value1 … log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种: org.apache.log4j.ConsoleAppender(控制台), org.apache.log4j.FileAppender(文件), org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件), org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件), org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
③配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class log4j.appender.appenderName.layout.option1 = value1 … log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种: org.apache.log4j.HTMLLayout(以HTML表格形式布局), org.apache.log4j.PatternLayout(可以灵活地指定布局模式), org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %m 输出代码中指定的消息
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) %c 输出日志信息所属的类的全名 %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28 %f 输出日志信息所属的类的类名 %m 输出代码中指定的信息,如log(message)中的message %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推 %r 输出自应用启动到输出该日志信息所耗费的毫秒数 %t 输出产生该日志事件的线程名 2 .程序中如何打印出Log日志 结合 commons-logging.jar log4j-1.2.9.jar Log log = LogFactory.getLog(Test.class); log.debug("XXXX");
配置实例log4j.properties log4j.rootLogger=DEBUG, stdout,R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm}]%-5p(%F:%L) - %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender log4j.appender.R.File=log.txt log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm}]%-5p(%F:%L) - %m%n
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229647
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
就网站建设方面与广大读者一起探讨,如网站规划、域名选择及软硬件平台对提升浏览率的作用问题。
-、网站规划及域名选择
网站规划的第一步是选择域名。域名被视为企业的网上商标,其重要性不言而喻。一般来说,注册一个好的域名要注意以下几点:
1、 使用企业或机构的注册商标名称。如IBM、Microsoft;
2、 使用企业或机构名称的中、英文缩写。如香港印艺学会域名www.gaahk.org.hk即本会英文名称Graphic Arts Association of Hong Kong的缩写;
3、 与企业广告语一致的英文内容;
4、 域名力求简短、便于记忆,一般以5--8个字母为佳;
5、 注册域名时别忘了注册几个与公司或商标名称相近的保护性域名 。
注册域名一般是先拟订好几个中意的域名 ,然后到一些提供域名查询的网站查询该域名是否被注册。《世界网络》的在线测试栏目(http://www.linkwan.com.cn/gb/broadmeter/)就提供域名查询服务。
可供查询的域名包括国际域名 (以.com .net .org 结尾),国内域名 (以.cn结尾)以及香港本地域名 (以.hk结尾)。如果域名已经被注册,则会列出该域名的详细注册资讯;如果域名没有被注册,则可以直接点击下面的链结进入“世界网络”的两岸三地的域名注册代理机构列表中(http://www.linkwan.com/gb/broadmarket/service/vhost/),选择合适的域名 注册代理机构注册。
香港地区朋友可以访问http://networksolutions.com网站直接注册并用信用卡支付注册费。国际域名 每年US$35,五年US$95。也可委托香港知名网页储存商Newsbook Limited 代办, (http://www.newsbook.net),国际域名 每两年HK$256,香港本地域名 每年HK$200,国内域名 每两年HK$800。Newsbook Limited优惠印艺学会会员,国际域名 每两年HK$160,国内域名 每两年HK$500。
网站规划的另外一个方面就是合理规划建站方向,确定网站类型,通常有以下几种常见的网站类型:
1、 产品展示型:通过分类、建立索引和搜索功能,将产品的图片及相关文字有条理地组织起来,形成便于查寻的在线商品目录,适用于以生产、经销为主的企业和店面。
2、 资讯发布型:这类网站相当于一个新闻中心,及时发布关于某一领域或行业的最新动态消息,或者综合性新闻,一般适合较专业性的站点。
3、 服务中心型:这类网站通常包含一个详尽的服务说明和FAQ(常见问题解答),并通过一些交互程式完成订单提交、在线支付、在线服务的定制和管理、软件升级等工作,并且提供一个意见反馈视窗(在线留言或电子邮件),用来解答问题和处理用户意见,从而形成一个友好、便捷的在线服务中心。
4、 论坛型:针对某些话题(或课题)的讨论型网站,为业内人士、专家、爱好者或普通大众提供一个讨论和发表看法的场所,例如发烧友论坛、学术论坛等。
5、 网上商城型:这种网站实际上是产品展示型网站的扩展,在清晰而详尽的商品目录的基础上,实现在线支付功能,并提供一种比较完善的订单处理机制,以确保订单的正确处理和货物的投递。与一般的企业用产品展示型网站相比,网上商城的商品数量通常庞大得多,而且一般是面向大众的,为了能让用户在失去耐心之前迅速地找到想要的商品,必须建立一个强大的商品搜索引擎。
根据建站不同的目的,我们要选择合适的软硬件平台。保证访问的稳定性和持续性是网站获得口碑和持续提高访问量的前提。不同网站的类型可以考虑不同软硬件平台,以期获得最大的性价比。
二、软件平台的选择
网站软件平台的选择主要是在网站功能需求和费用之间寻求最大的性价比。根据网站功能的规划,我们可以在作业系统、动态页面技术、资料库系统等几个方面做出选择。
目前普通网站的伺服器作业系统以微软的Windows系统和Linux占大多数。Windows优点是操作简便,为大家熟知,配置和管理伺服器容易上手,但是费用较贵,而且需要的硬件配置也较Linux要求高。Linux最大的优点是其全免费而且可供配套的免费软件丰富,缺点是操作复杂,需要专门的技术人员维护。
读者可以根据网站建设目标规划和财务预算作合理选择。如果有相关技术人员,可以考虑使用Linux系统,配合php或jsp动态网页技术和MySQL资料库系统。
当然,对于大多数企业来说,以Windows系统作为网站伺服器,可以降低维护成本和更新难度。如果目标是“产品展示型”网站,只需采用静态页面网站。不用使用动态网页技术,页面制作简单。如果需要制作“资讯发布型”或“服务中心型”网站,则可以适当使用动态网页技术(ASP技术)和微软office中的小型资料库系统Access即可实现。如果考虑“论坛型”和“网上商城型”网站,则建议使用一些大型的资料库如微软的SQL Server或甲骨文的Oracle资料库,以提供稳定的服务和支撑大的访问量和资料处理需求。
在软件平台的建设方面还需要考虑到系统的安全性,所以伺服器系统一定要注意安装防毒软件并定期升级系统及安装(Service Pack)补丁程式,以防止黑客利用系统的漏洞入侵网站。
软件平台根据印刷行业特别的需求,可能需要一些特别的网络技术支援。如Web FTP,用于交收印刷产品电子文档,香港的汇能印艺 www.artechgraphics.com.hk 已经有实际应用。另外,企业为降低伺服器成本,利用现有动态IP(互联网络通讯协定)宽带上网的电脑充当伺服器作为FTP(档案传送协定)伺服器供客户传送印刷文档,可以考虑使用动态域名 技术,该技术是将一个特定的域名 和您电脑当前的IP做对应,每当您的电脑在线,就会定时刷新域名 所对应的IP,使得访问该域名 的用户都能转向到当前您的电脑所使用的IP。DNS2Go就是利用这项技术提供服务的网站之一。读者有兴趣可以访问世界网络(http://www.linkwan.com/gb/broadtech/article/dns2go.htm)了解详细的使用方法。
三、硬件平台的选择
网站硬件平台的选择很大程度上决定了网站能够提供服务的能力和稳定性。所以选择硬件平台之前可以根据网站的规划目标预测一下访问者的流量,以及考虑所选择的软件平台的系统负荷合理选择硬件平台。
目前可供选择的硬件平台方式大致有以下几种:虚拟主机、伺服器租用、自购品牌伺服器托管、DIY组装伺服器托管、租用专线自建机房。
1. 虚拟主机
采用这种方式适应于预期访问量不是很大,页面多为静态页面,系统负荷较小的网站。此方式租用费最为低廉,且无需维护知识,维护成本低,适合小型的网站采用。目前两岸三地有很多虚拟主机商提供此项服务,有兴趣的读者可以到http://www.linkwan.com/gb/broadmarket/service/vhost/查询,香港地区的用户推荐Newsbook Limited (http://www.newsbook.net),印艺学会会员享受八折优惠。
2. 伺服器租用
包括伺服器租用连托管服务计划。一般无须购买硬件(伺服器)的费用,月费只需HK$1300左右(价格视乎伺服器配置而定)。伺服器性能可满足一般的需求,特别适合印刷厂作网站及设置FTP伺服器。由于租用伺服器连托管,公司技术人员不必有对伺服器有太专业知识,此方案最实用,广受欢迎。
3. 自买品牌伺服器托管
选择1U/2U品牌厂机伺服器,对于企业用户来说是不失为最快捷稳当做法。品牌伺服器可选择IBM、HP、SUN、DELL等。品牌伺服器质量有保证,而且售后服务周到。相比伺服器租用,虽然前期要投入购置费用,但是月托管费用较低,适合需求稳定、伺服器长时间运作的企业网站。
4. DIY组装伺服器托管
此方式适合具备一定硬件技术人员的企业。性价比对购买品牌伺服器来说占很大优势。当前推介配置Intel S875WP1-E主板,P4 3.2G(800 FSB) CPU,1G DDR400 RAM,WD36DG一万转36G SATA硬碟,连1U机箱,总价格约HK$8,800。文件吞吐率270Mbps左右,整数和浮点性能都达到较高的水准。选用优质机箱配合强风量(CFM) CPU散热风扇、小型鼓风机(BLOWER),上述配置CPU温度idle温度 32度 ,full loading 温度58度,完全满足长期运转的需要。有兴趣读者可以联系本文作者,探讨经验。
5. 租用专线自建机房
此方式适合有一定技术实力和经济实力的大型企业。通常租用宽频服务供应商提供的专用数据线路,在自身办公地点建立数据中心(机房),对内提供企业自身IT服务,对外提供网站服务,邮件服务以及FTP等。
以上几种方式在硬件安全性方面,无论是托管环境还是自建机房一定要具备温度调节、湿度调节装备以及断电保护装置(USP),以确保稳定性以及资料安全。
下面介绍一些对硬件网络服务性能进行测试的一些软件,希望能够帮助读者分析伺服器硬件是否满足性能要求。
NETMECHANIC.COM伺服器测试,此网站提供伺服器性能测试(Server Check)的免费服务。您只需将要测试的网站的域名 以及您的Email地址填写提交,netmechanic.com的伺服器即会在以后的8小时内每隔15分钟监测您指定网站的伺服器。并在8小时以后将检测结果发送到您指定的Email地址。可以到http://www.linkwan.com/gb/broadmeter/htmltest/netmechanic.htm参看说明提交测试。本测试仅提供作本地网站相对参考比较,因为测试是由美国发起,对于测试香港或内地的速度可能与当地访问差别很大。
还有一些在伺服器安装的伺服器性能测试工具,以动态页面技术制作,安装在被测试的伺服器web伺服器上即可测试。Windows系统推荐使用“阿江ASP探针”(演示>>),此工具可以探测伺服器基本资讯;伺服器元件支援情况;伺服器硬盘讯息;当前文件夹资讯;伺服器脚本解释和执行速度。Linux系统下推荐使用C1G的PHP探针,可以进行PHP web伺服器的特性、PHP基本特性、元件支援状况、伺服器性能检测等测试。另有一款可以在远端电脑上安装的监视伺服器状态的软件sMonitor 3.08,此软件可以在您的PC连接上网际网络后,不断地经常监视伺服器主机网络状况,包括监视检查Ping、FTP、HTTP、SMTP、POP3、DNS等伺服器主机。sMonitor 3.08可以测试和监视伺服器的稳定度。这三个软件均可以到http://www.linkwan.com/gb/download/下载,套装软件包括相关的使用说明和作者资讯。
四、网络拓扑(Topology)位置的选择
不论是虚拟空间或托管伺服器,都要选择放置在好的网络拓扑位置,以发挥其功效。简单来说就是选择好的资料中心非常重要。如何对数据中心的性能做评测呢?下面介绍几点供读者参考。
1. 收集资料,了解数据中心出口带宽。
这些资料可以帮助我们根据网站的预期访问者情况选择合适的数据中心地理位置。目前“世界网络”网站中有内地、香港、台湾等地的相关资料,读者可以参考(http://www.linkwan.com/gb/broadmarket/)。 香港的内部交换带宽可以看http://www.linkwan.com/gb/broadmarket/bandwidth/hkinteral.htm,香港的国际专用线路容量可以看http://www.linkwan.com/gb/broadmarket/bandwidth/hkoversea.htm等等。香港有五大宽频上网ISP,分别是网上行 www.netvigator.com、和记环球电讯 www.hgc.com.hk、有线宽频 www.i-cable.com、香港宽频 www.hkbn.net和So-net www.so-net.com.hk ,就香港本地应用速度来看,速度相差不远,有线宽频速度略好。就海外的上网速度而言,网上行占尽优势。
香港网络骨干主要是用电讯盈科与和记环球电讯网络。近年来香港海外出口接驳商不断增加,例:新加坡电讯、NTT、MCI,但目前海外出口仍以恒通Reach 、和记环球电讯为主流。宽频连线速度主要取决网络骨干品质和连接HKIX、海外出口流量、ISP伺服器等条件。在浏览中国大陆网站及交收电子档案方面,网上行有明显优势,香港宽频则有时浏览中国大陆网站则有时不畅顺(其原因是要经由美国才连接到中国大陆网站)。
内地方面,2003年底计中国国际出口带宽的总容量为27,689M (大部份是中国电信拥有),读者可以到“世界网络”参看最新带宽图(http://www.linkwan.com/gb/broadmarket/bandwidth/cnnic.htm),至台湾2.13G 、至香港 4.672G 、至澳门45M 以及至美国13.997G。虽然近年来网通、联通、长城宽带、铁通均有数据中心,收费也较便宜,但如希望较好出口带宽的话还是选中国电信系统资料中心为宜。
台湾地区出口以美国为主,近年两岸三地交流/贸易增长多,频宽也不断增加。当地数据中心对虚拟空间和伺服器托管收费较贵,提供本地线路网络服务的网络公司也不多。 如有需要在台湾找虚拟空间或伺服器托管,其中一间战国策www.hotels.com.tw 收费及速度还可以。
2. 通过一些显示路由和测试速度的软件比较
利用软件方法测试各数据中心的实际速度不失为客观评价资料中心优劣的一个重要手段。下面介绍几个适用的软件方法供读者参考。
最简单使用的工具莫过于使用Ping测试资料中心的反应速度。Ping是测试网络联接状况以及资讯包发送和接收状况非常有用的工具,是网络测试最常用的命令。Ping向目标伺服器(位址)发送一个回送请求资料包,要求目标伺服器收到请求后给予答复,从而判断网络的回应时间。详细使用方法及技巧可以参看http://www.linkwan.com/gb/broadmeter/article/pinghelp.htm。
“世界网络”已与美国Fortel公司达成协定,成为该公司VisualRoute路由软件在亚太地区的测试点。已在北京、台北、香港、上海四地建立了一整套路由测试系统(http://www.linkwan.com/vrhk/)。该软件可以清晰显示例如从北京、台北、香港、上海等地到您想访问的网址,路由线路并用图形的形式表现出来,可以清晰看到访问路径,以此也可以对一个数据中心的路由情况做一个直观了解。
此外,“世界网络”的速度测试也是一个比较各地连线速度的好工具。目前该网站收集了1000多个速度测试点的资讯,其中不乏虚拟主机或托管提供商的测试点。读者可以到http://www.linkwan.com/gb/broadmeter/SpeedAuto/,自己亲自测试一下到各地的连线速度,为选择一个好的数据中心做比较。
要测试至香港的连线速度,读者可到电讯盈科http://home.netvigator.com/~cfs05/ 或世界网络 http://www.linkwan.com/gb/broadmeter/SpeedAuto/default.asp?keyword=香港 进行速度测试。
总而言之,一个好的域名 应有较强的标示性、易懂易记,并与网站内容相符,会为提升浏览率奠下基础;同时,一个切合实际的、优秀的软硬件平台和网络方案将为资讯的流通建立可靠平台。
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229643
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
建立网站的目的虽各有不同,但小至个人主页,大至世界顶尖产品制造商的网站,都有一个共同的目的-那就是希望有大量的人来浏览自己的网站。商业网站在设立时更是谨慎考虑,如:怎样方便客户随时随地查阅新产品的资料;怎样让潜在的客户更容易地找到自己的网站等等。中国有句老话“酒香也怕巷子深”,在数以亿计、浩如苄海的Internet潮中,如何令自己的网站异军突起?如何以最低的成本做到最大的效果?网络推广一直是业界关心最多、议论最多的话题之一。
网络推广的目的是使网站的浏览率不断提升,浏览率是网站广告收费的重要依据,也是评估网站价值的重要依据之一。而浏览率的80%-90%来自於网站在各大搜索引擎中的排名,一般来讲排名在20名之外的网站被访问到的概率将大大下降,排名在100名之外的网站将鲜有人问津。於是,我们总是想让自己的网站信息优先出现在搜索结果中,以便吸引更多访问者。也便有了专门的顾问公司帮客户进行网络推广服务,以提高在搜索引擎中的排位。
一直以来,人们关注的焦点是某一特定网站在各大搜索引擎中(如Google、Yahoo!、AltaVista、MSN等)的排位问题,但这一排位是基於关键字(Keywords)搜索结果的,由於关键字选用上的随意性或文化差异因素,往往导致搜索结果和排位的不同,而且各个搜索引擎的排位规则、更新周期和收录的URL不尽相同,缺乏一个评价指标来对一个网站的世界排名进行综合评估,这时便需要参考Alexa所提供的网站浏览率及网站世界排名数据。
网站世界排名权威-Alexa
Alexa(www.alexa.com)是一家专门发布网站世界排名的网站。以搜索引擎起家的Alexa创建於1996年4月,目的是让互联网网友在分享虚拟世界资源的同时,更多地参与互联网资源的组织。2002年5月Alexa放弃了自己的搜索引擎转而与Google合作。Alexa每天在网上搜集超过1,000GB的信息,然后进行整合发布,现在他搜集的URL数量已经超过了Google。下图是他们自己给出的一个信息量比较图。纵轴为已有的URL地址数量,以十亿为单位。也就是说在量上,Alexa位居世界四大搜索引擎第一位,已超过35亿。
虽然Alexa的搜索引擎很好用,但是网站浏览率统计和世界排名却是它最吸引人的地方,Alexa不仅给出多达几十亿的网址链接,而且为其中的每一个网站进行了排名。可以说,Alexa是当前拥有URL数量最庞大,排名信息发布最详尽的网站。
Alexa的网站世界排名主要分两种:综合排名和分类排名。综合排名也叫绝对排名,即特定的一个网站在所有网站中的名次。Alexa每三个月公布一次新的网站综合排名。此排名的依据是用户链接数(Users Reach)和页面浏览数(Page Views)三个月累积的几何平均值。如当前世界排名最靠前的网站:雅虎(www.yahoo.com)高居榜首(每日Internet用户中每百万人平均有308,000人会访问雅虎),MSN(www.msn.com)紧跟其后,第五名是最有名的搜索引擎Google(www.google.com)等。
Alexa分类排名,一是按主题分类,比如新闻、娱乐、购物等,Alexa给出某个特定网站在同一类网站中的名次。Alexa将其收集到的网站共分了16个大类,每个类下又分为多个主题。二是按语言分类,目前共分21种语言,比如英文网站、中文网站等,给出特定站点在所有此类语言网站中的名次,其中中文网站分成简体和繁体两种来统计。对於中文网站的排名,目前只发布排在前100名的网站名单。两岸三地一些著名中文网站当前的世界排名情况如下。
新浪www.sina.com.cn 7名
网易www.163.com 11名
搜狐www.sohu.com 12名
Tom.com www.tom.com 17名
HiNet www.hinet.net 43名
网路家庭www.pchome.com.tw 56名
番薯藤www.yam.com 115名
澳门彩票www.macauslot.com 208名
联合早报www.zaobao.com 234名
凤凰卫视www.phoenixtv.com 287名
网上行www.netvigator.com 358名
MSN 香港www.msn.com.hk 442名
Alexa工具条及Alexa使用详解
Alexa的浏览率统计是根据用户安装Alexa工具条(Alexa Toolbar)的信息反馈及参考IP来源的区域分布作基数综合统计来排名。如果IE中嵌入了Alexa工具条,那么每访问一个网站,其综合排名就会显示出来。我们可到下列地址下载Alexa工具条:http://download.alexa.com/alexa7/startpage.html?p=TrafficDet_W_t_40_B2
以世界网络(www.linkwan.com)为例,显示其综合排名为6,014(2004年2月3日数据,下同)。
如果通过Alexa查看一个网站,首先看到的就是该网站的综合排名,并且配有当日网站首页截图,和网站内容的简单文字说明。Alexa还会根据网民对网站的评论,在综合排名信息中,用"星"来给网站评一个等级,最高为"5星"。
Alexa将综合排名500强网站在自己网站上强力推荐。每个通过Alexa访问的网站,Alexa首先给出了有关该网站的信息:综合排名、相关网站链接、网站基本情况、联系方式、关於该网站的评论等。如以下是linkwan.com站点的信息:
上图显示了网友最多从哪些站点访问到该站,下图显示了该站的基本情况。
通过网页上的链接"See Traffic Details",可以查看到有关该网站浏览率的详细统计数据和图表。以世界网络(http://www.linkwan.com)为例,除了网站综合排名简介外,还有如下信息:
1.距当日最近的前3个月、前6个月、一年和二年的访问量排名数据。下图为linkwan.com自2004年2月3日上溯6个月来的访问量排名走势图:
由上图可见,linkwan.com的访问量排名总体呈上升趋势,连续2个多月排名在6000名左右。
2.综合排名统计表,包括:今日排名、1周前排名、3个月前排名,以及与上一季度比较排名是上升还是下降。以下是linkwan.com的综合排名。
3.当日访问用户数、一周前每日平均访问用户数、前三个月的每日平均访问用户数(每百万人为单位)和当日、前一周、前三个月按访问用户数的排名,以及3个月来这些数量的变化。如下图所示:
4.每个用户平均浏览页面数,分为:当日、前一周、前3个月分别统计。
除此之外,还有按被访页面数的排名,3个月来页面浏览量和以此为排名的名次两项变化。
既然Alexa世界排名能提供如此详尽的浏览率及世界排名信息,大家如果想在自己网站公开自己Alexa世界排名,可安装上Alexa按键吧!因此就把Alexa排名按键为各位介绍一下(安装此按键不影响世界排名)。
排名按键可显示网站的排名。如世界网络(http://www.linkwan.com)的排名为6,014位,一般显示的排名是两天前的排名。如果希望显示你的网站的排名信息,只需将代码中红色文字(网址)部分替换成你的网站地址,并放在网站相应的位置即可。
各位可在下列地址:http://www.alexa.com/site/site_stats/signup详细了解Alexa按键的相关信息。
提升网站的浏览率
如此大量的网站地址,如此详尽的数据和统计,确立了Alexa的网站世界排名的权威。Alexa给出的排名无疑吊起众多与网站密切相关者的胃口。人们难免会思考:为什么我们的网站排在他们的之后?怎样才能排得靠前一些?怎样才能提升网站的浏览率?也有人会问:这个排名科学吗?公正吗?为此,我们有必要了解一下Alexa的浏览率统计和排名机制。
一.Alexa浏览率统计和排名的先决条件
Alexa的网站排名是按照每个特定网站的被浏览率进行排名的。浏览率越大,排名越靠前。
浏览率是针对定义在域上的网站进行统计的。如:www.sina.com.cn、news.sina.com.cn 和tech.sina.com.cn将被视作同一网站进行计数,因为它们同属於sina.com.cn这个域。但是也有例外,如个人主页,如果系统能够自动从URL地址分辨的话,将被视为彼此独立的网站。
提供同样内容的网站将被视为同一网站计算。比如,大中华印艺网使用www.cgan.com和www.cgan.org两个域名发布同样的内容,那么将被作为同一个网站来计算。
纳入统计的访问量仅来自使用Alexa工具栏(Alexa Toolbar)的用户。也就是说,只有用户下载了Alexa工具栏,并将其嵌入自己的浏览器。这样,该用户访问某个网站的话,访问的记录才能算作被访问网站的访问量。据Alexa统计,现在使用该工具栏的用户达数百万。
Alexa工具栏仅在windows操作系统下,Internet Explorer浏览器中使用有效,使用其它操作系统或者浏览器的访问将不能被计数。
遇到有安全保护或加密的站点,Alexa工具栏将自动关闭,因此那些安全系数高的网站,Alexa将不能对其进行搜索和统计排名。
二.Alexa浏览率算法
某个特定网站被排名时,依据的浏览率数据是基於该网站3个月访问量记录的累积。也就是说Alexa每三个月发布一次排名结果,即通常说的名次。它的计算主要取决於访问用户数(Users Reach)和页面浏览数(Page Views)。Alexa系统每天对每个网站的访问用户数和页面浏览数进行统计,通过这两个量的三个月累积值的几何平均得出当前名次。
访问用户数(Users Reach)指通过Internet访问某个特定网站的人数。用访问某个特定网站的人数占所有Internet用户数的比例来表示。即:访问用户数=(访问人数/全部Alexa用户数)x 100%,Alexa以每百万人作为计数单位。以世界网络(linkwan.com)为例,如果它的访问用户数为2%的话,就是说,随意抽取一百万的Internet用户,其中有20,000人访问世界网络。
页面浏览数(Page Views)是指用户访问了某个特定网站的多少个页面。是所有访问该网站的用户浏览的页面数之和。每个用户浏览的页面数取平均值,是所有访问该网站的用户每天每人浏览的独立页面数的平均。同一人、同一天、对同一页面的多次浏览只记一次。
三.影响Alexa排名的其他因素
Alexa Toolbar的采用率在全球各地有所差异,受用户的语言、地域、文化等各方面的影响。因此英文网站相对於其它语言的网站,访问量数据更容易被充分地统计。
容易受网站对自己宣传的程度、做广告的多少、别的网站为其建立链接的多少的影响。
排名的网站最好主动将自己的URL地址添加到Alexa中,否则访问量的统计会受到影响,而且Alexa不提供这些网站访问量的详细统计。
浏览率太小的网站统计数字可能不准确,总体上排名越靠前(浏览率越大)的网站统计数字就越可靠。一般来说,月访问量1000以下或排名100,000以后的网站统计数字是不准确的。
可以肯定,任何的计算方法都不完美,所以我们也无法评述Alexa排名的公正性和科学性。但既然Alexa将相关统计信息通过Internet全球公开发布,大家又都用Alexa的统计作为标杆,从中国到世界各国权威的新闻媒体在讨论一个著名网站的规模时,莫不以Alexa为标准。世界上也没有第二个像Alexa那样的网站不需要你在网页中插入他的代码等等来计算排名,他对全世界所有网站一视同仁,我们就姑且相信其专业性和权威性。
最重要的是,您是否找到了提升自己网站浏览率和使排名靠前的方法?希望通过以上的介绍,对大家有所启发。当然,并不是通过对Alexa的了解和相关工具的使用,就可以保证网站浏览率和排名的提升,浏览率也与网站的品牌、规模和内容、专业程度、网页质量、服务器等很多因素相关,后将继续为大家介绍。
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229641
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
企业建站还需要考虑诸如规划网站内容、网络应用,以及如何改进,甚至变革企业的经营管理模式以适应随之而来的网络经济浪潮等问题。
目前,全世界的网站总数已超过了6,000万个,其中也包括了数以万计的印刷类网站,并且还在不断地增加。因此,搜索引擎对于那些在互联网上寻找信息的人们已经变得越来越重要了。如何使自己的网站脱颖而出,并取得成效,关键是提升网站的知名度和浏览率,而对网站内容进行详细规划和网络应用则是提高网站浏览率的重要途径。企业网站就如同企业在网上的产品橱窗,一是要让你的网站很容易被找到;二是要让感兴趣的潜在客户不虚此行,找到有用的资料和得到想要的服务。
从最新的网络统计分析报告中得知,网站访问率的78%来自于搜索引擎,而网站在搜索引擎中的排位与网站的内容有很大的关系。本期笔者将就网站内容规划、网络应用以及提高搜索引擎排名的一些小技巧谈谈自己的经验所得。
一.网站内容规划
1.网站内容的组织原则
网站内容的组织并不是现成的企业简介和产品目录的翻版。笔者就见过很多企业的网站并没有很好地组织网站的内容,这恰好也是这些网站访问量低的一个重要原因。
知己知彼,百战不殆。建站之初,你必须花点力气,通过搜索引擎找出同类网站排名前20位的名单,逐个访问名单上所有的网站,然后做一个简单的表格,列出你认为是竞争对手的企业名称、所在地、产品搜述、产品价格、网站特点等等,从中找出你的产品优于或不同于其他竞争对手产品的优点或特色;同时,你也应该清楚地认识到自己产品的不足之处,思考如何改进使产品更具竞争力,并制定出如何改进的方案。这实际上也是一个企业找出如何与网络相结合的经营策略,以适应日益竞争的国际化市场。
在充分了解了网上竞争对手的情况并研究了他们的产品和网页的基础后,你就可以集众家之所长,参照以下内容组织原则,制订出更能体现产品特点的网页内容。
网站内容的组织原则:
清晰性:网站内容必须简洁明暸,直奔主题,非常有效地讲清楚你想说的内容。
创造性:你的观点会使访问者产生共鸣,发出内心的认同吗?这是访问者判断一间公司是否有实力,从而影响到购买动机的重要依据。
突出三个重点:
突出你的产品的优点和与众不同的特色;
突出帮助访问者辨别、判断同类产品优劣方面的内容;
突出内容的无庸置疑的正确性。
2.网站内容的组织方法-栏目设置
网站内容组织或取舍的方法是将网站想象成企业的产品陈列室,如果你是推销员,那么你将如何向客户推销你的产品吗?
A.首先问自己三个问题
访问者访问我的网站的目的是甚么?
从网上获取资讯始终是访问者的主要目的之一。因此你的网站内容必须提供和你的产品或服务相关的丰富资讯。以专业角度去描述产品的规格和性能,和同类产品或服务相比较,告诉访问者各自的优点之处及不同特点,帮助访问者做出最好的选择。
访问者为甚么要经常访问我的网站?
一般情况下,访问者要在访问你的网站4-5次后,才会有实质性的购买行动。因此,你的网站要让他们觉得值得回访。不断更新你的产品或服务资讯,不断力上你认为会吸引访问者的内容,加深良好印象,会使你的潜在客户回访网站。
访问者在众多的同类产品或服务中,为甚么会选择我的产品或服务?
详细描述你产品或服务的特点,给出确凿的资料。如果你的产品或服务没有特色,那么潜在客户购买你的产品或服务的动机将会大大降低。
认真地回答以上三个问题,就可以清楚地知道自己的产品有哪些优势,并在内容组织及栏目设置中尽量体现。
B.按重要程度列出答案所需的内容、资料,有时还需要图示或加入产品图片。如果有必要,将上述问题整理成问卷,分发给同事、客户、朋友去做。
C.将他们的答案分门别类的整理出来,再根据上述"网站内容的组织原则"重新取舍,并尽可能地提出共性的东西,这样需要哪些栏目和内容就很清楚了。如有需要,提请有关部门提供栏目所需的内容和资料。
D.网站栏目的设置一定要突出重要,方便用户。网站栏目的实质是一个网站内容的大纲索引,就好比一本书的目录,集中了各个章节的名称及页码,索引应该引导浏览者寻找网站里最主要有用的东西。在设置栏目时,要仔细考虑内容的轻重缓急,合理安排,突出重点。
值得一提的是笔者见过太多的网站只是说自己的产品最好、规模最大等等,却找不出任何支持其说法的资料;也有很多网站经常说自己的产品或服务最好,价格又最低,却没有实例来证明。以笔者的经验来看,网站推荐产品的手法大致可分为两类:第一,以优良的品质取胜,最好的产品或服务往往需要最好的生产工艺、原材料和人力投入,而这些将大大增加产品的成本,也提高了产品的价格,但推荐者要令客人明白这是值得的,因为高价保证了产品有一定的品质。第二,网站可以以价廉物美的手法来推销,通过大规模或特殊的生产方式以达致产品质优价廉,从而增加客人对产品的吸引力和信心。
二.关键字和链结
1.关键字
在制作网页之前(不是在制作好网页之后),确定你的关键字。首先列出前十强竞争对手的关键字和链结伙伴,分析他们的首页设置和内容,然后制定出赶超他们的方案,然后以最重要的25个左右的关键字为基本元素来组织你的网页内容,包括:
网页媒介标签META的应用
大部分搜索引擎例如Alta Vista是以正文的头几百个字与标题(Title)、页面描述(Description)和关键字(Keywords)的符合程度来决定网页的搜索结果排位,而Excit、Yahoo是纯粹以搜索的关键字与正文的相关程度及在正文中的重复频率来决定搜索结果的排位。
META标签(metatag)的作用是提供有关HTML文档资讯,它所包含的内容并不出现在网页上。有很多网页制作者很少注意这个标签,因为它并没有影响网页的外观。META最大的作用就是提供搜索引擎关于本站的描述关建字。简单地说,当搜索引擎搜索到你的网站时,会首先检查META所描述的关键字,然后把这些关键字加入到资料库中。所以适当地利用META标签会让你在搜索引擎中被搜索到的机会大大增加。
META标签的用法是这样的:
<metaname="Keywords"CONTENT="关键字,关键字,关键字">
在CONTENT处,你尽可能把热门的关键字列在这里。比如与印刷相关的网站,放入"Print(印刷)"。这还有个技巧,你可以重复某一个关键字,这样可以提高自己网站的排行位置,如:
<metaname="Keywords"CONTENT="print,print,print,...>下面,让我们以全球最著名的搜索引擎-雅虎(http://cn.yahoo.com/)为例,在搜索框中输入"印刷"关键字,搜索结果中排名最前两位的是"慧聪网印刷行业频道"和"中国印刷市场",用浏览器工具栏中的"查看一原始档案"看看这些排名最前的竞争对手是如何使用META标签的。
"中国印刷市场"的META标签:
<title>中国印刷市场/印刷包装企业大全:印刷厂/包装厂/印刷机/包装机械/印刷技术/包装技术/印刷材料/包装材料/网上印刷报价<title>
<meta http-equiv="Content-Type"content="text/html;charset=gb2312">
<meta name="KEYWORDS"content="中国印刷市场,印刷公司,印刷设备厂商,印刷院校,China print market,印刷相关法律,印刷社会团体,印刷网站,印刷杂志">
<meta name="DESCRIPTION"content="全面介绍中国印刷市场业界行情,中国印刷企业名录,印刷设备厂商,印刷材料供应,印刷市场供需,印刷网上报价,印刷技术报道,印刷专业院校,印刷相关法律,印刷社会团体,印刷网站介绍,印刷专业期刊杂志等,为中国印刷及相关产业提供全方位的服务。">
可以看出,在其13个关键字中,竟然包含了12个"印刷",另外一个关键字也有英文的印刷单词(China print market),如此多的关键字设计,当然会有好的搜索引擎排位。反之,让我们再看看3-5位的META标签,居然3个网站都没有使用keywords和description标签。相信如果使用META标签后,其网站排位应会有所提升。
在不影响内容的前提下,在网页内容中尽可能多些重复这些关键字。
由于现在新的搜索引擎(如Google、Alexa)不再关注META标筮了,可能是认为那是个骗局,所以机器人(或称"网络爬虫",一种仿照人类浏览网页行为设计的程式,随时随地游走于网络之间,可以自行进入网站读取网页资讯的软体)避开了META标签,只是来扫描你的网页,并把出现最多的词作为关键字,或者把网页顶部的词作为关键字。这样,META失去了作用,那么怎么办呢?其实,这没有问题,"道高一尺,魔高一丈",我们还有更多的方法"欺骗"机器人。
你可以把热门的关键字放到网页开始的地方。一般的做法是将网站的栏目功能表放在首页,因为这些栏目名称包含了反映网站主要内容的关键字(记得使用文本方式,有些网页设计者为了美化外观就把栏自功能表设计成图片,这样搜索引擎就读不到了)。这样机器人就能看到很多关键字了。我们也可以设法把关键字隐藏到网页面,怎样做?很简单,把关键字与背景颜色弄成一致就可以了。
还有一个更好的方法,专门制作一个网页,把你知道的关键字全部放在这个网页上,想怎么放就怎么放,因为这一页只是给机器人看的,你可以利用以上方法设置关键字。要记住,你还要做一个链结,将这一关键字页连接到你的网站,这样做的目的是你可以尽可能提供机器人最全面,最好,最热的关键字,而这一页是没有人看到的,只是让机器人知道这些关键字与网站有关。
2.链结
链结交换被许多网站利用,但即使用了链结,也并没有带来更多的访客,原因何在呢?
首先,让我们来看第一种链结-友情链结,这是目前使用最多的链结交换。许多站点互相交换着LOGO(甚至还有联盟呢!),但可惜的是有些链结并没有起到太大的作用。所以,很多站点提出了条件。第一,访问量相当;第二,首页交换。以笔者的经验,当与一个站点交换链结时,要注意对方把我的LOGO放到了友情链结的那一页或是首页。专门的友情链结那一页包含了许多其他的链结交换,在众多的交换LOGO中很少会有人会注意到你,并且很少会有人访问友情链结页。一般来说,友情链结页是给机器人读的,要想通过链结交换带来访客,还得遵从上面两个条件:首页交换和访问量相当。
接下来,第二种就是所谓的商业链结交换了。提供这种服务的交换商有很多,国内的,国外的,交换的规则很简单,表面上是很公平的,至少我还没有发现问题,所姈也没有更多的技巧给你,只是提醒你,选择一个热门的链结交换商,这是个很简单的技巧,但并没有多少人注意。值得一提的是,链结交换并不会带来直接的访问量,但可以提高网站的搜索引擎排名。因为,多数搜索引擎规则中认为,你被链结的次数越多,就证明你的网站越知名,越受人欢迎,网站排位自然会被推前。所以,交换链结时千万记得检查别人是否回链到你的网站。
三.网络应用
网站犹如企业门户,除了具有企业形象视窗、产品宣传和通讯联络功能外,网站还可以提供许多其他的网络应用。从广告发布,生意招揽到网上报价;从档案收发、看样校对到远端备份;从物料采购,外发加工到送货收款,网络应用正日益发展壮大,无处不及。
尽管本文探讨的主题是如何通过网站内容的组织规划来提升网站的浏览率,非网络应用专文,但广义说网络应用也是网站内容的一部分。现今网络界精英们也纷纷意识到从"内容为主"转向"应用为主",此乃网络发展最新趋势,印刷人应及早准备。因此,笔者就目前印刷企业网站可实施的一些基本可行的网络应用作一简要介绍,以期抛砖引玉,引起印刷同人的注意,积极探讨和实践网络技术在印刷界的应用,争取更多商机。
1.清楚的操作介面及网页内容查询功能
一个好的网站必须要有良好的操作介面,能使浏览者在最短时间进入要想去浏览的区域。在有些网站内,查询往往答非所问,若能让浏览者在短时间内查询到想要的主题是重要关键,故提供强力的查询功能是网站需着眼的方向。
首页设计要简单大方,有些网站在进入首页时使用FLASH设计的动画或JAVA点选往往要花去数十秒才能出现画面,这样的设计虽然很酷,但容易引起读者的抱怨网站速度太慢。
2.查询与回馈互动环境
网站要考虑到适当的互动,这项功能可加强浏览者的意愿与兴趣。以后才会经常进网站来浏览。设立动态互动的问题谘询/反馈页面,倾听客户声音,保持良好、及时的沟通。具体应用可参看http://www.brainnew.com.tw。
3.产品查询、展示功能
网站是企业产品展示橱窗,可通过公司设备、先进技术、设计创意、质量控制和作业规格等更好地突出产品特点。开发产品查询系统,让客户可自行键入相关资料以查询所需的产品,必要时配以精美的样品图和价格资料,甚至采3D视像技术,充分展示你产品的优势。
对商务型网站而言,产品销售是第一要务,若能使用最少篇幅将产品的特性表达清楚,对商品的销售有很大的助益。有些网站对它们的商品无法用简短的文字介绍清楚,在竞争上就失去了优势。
4.网上接单
可开发应用网上产品查询、自动报价、接订单和订单管理系统。进一步的应用还有在线支付、邮购寄发,甚至物流配送到府等。
作为一个网上接单的例子,让我们来看看内地的一家输出公司-深圳龙辉菲林输出中心(http://www.szlh158.com/)的具体运作。该公司的主要业务就是为客户提供菲林输出服务,其网站的主要功能就是提供一个在线上接订单的功能,并提供了简单的用户注册机制。进入了落订单介面,我们可以看到用户可以通过网页的交互介面设置订单内容,包括文件格式、尺寸、分色、线数、阴阳片、药膜面、打样与否、打样纸要求等等,并且能够选择要出菲林的文件上传,从而初步实现了电子商务的基本功能-客户在线上落订单。
当然,更进一步的应用还可以扩展为购物车、订单管理、客户管理、线上支付等。
5.档案传输和远端备份(FTP伺服器)
网站可设置专门的FTP伺服器,公司业务档案可以上载存于伺服器,员工可按授权程度随时下载读取档案。基于保密目的,应将公司档案加密上传备份。
现在一般的虚拟主机提供商和一些拥有主机的专业网站都可以提供FTP服务,根据用户的需要开设一定大子限额的空间,用户就可以使用FTP软体自由上传和下载文件资料了。明峻科技有限公司【传文易】文件管理系统http://cht.mydocuit.com.hk目前就可以提供此类服务。
6.网上教育网站建立内部使用系统,公司员工可用分配的用户名、密码登录进入,读取下载内部培训资料或交流,下载软体程式,观看VCD教材等。
四.提高网站浏览率的小技巧
1.间接网页策略
看了本文后,你应该可以对你的网页如内容规划、META标签和链结、网络应用等进行改善了吧。假设大家的网页设计已经优化,功能上也相差无几,那么网站的展现机会就几乎均等了。所以最近大型企业网站均趋向采取化整为零的间接网页策略,并视此为秘密武器未向世人公开。
所谓间接网页策略,就好比一根钓鱼杆装上好几个钓鱼饵。例如Procter &Gamble为全球性日用品公司,产品包罗万象,Procter &Gamble当然有一个主网页,包括产品和公司机构,但设计再完美仍只是一个网页,所以该公司就依据消费大众的普通需求设计了很多支网页并链结到搜索引擎。例如在搜索引擎中打入Shampoo,就会出现"Head &Shoulders、A Year of Beautiful Hair Sweepstakes"。此网页是一个Procter &Gamble的名牌洗发精;又例如Head &Shoulders挂名举办抽奖活动,并于页尾加上链结到公司主网页(Procter &Gamble)的链结按钮,如此只要将公司主网页链结按钮布置在所有的日用品专案中,自然可以大幅提升主网页的浏览率。
2.专门的友情链结页
第二节"关链字和链结"已经讲到了,尽管友情链结页并不会带来多少直接的访问量,但可以提高网站的搜索引擎排名。所以作为一个网站不可或缺的一个通用栏目,笔者还是建议你设立专门的友情链结页。
3.本地化服务和多语种版本
如果你有做过市场行销工作的经验,你就知道本地化服务有多重要了。市场营销理论,也有提及:客户对产品了解越多越会产生安全感,也就越有可能购买。因此,你应该明确地知道目标市场所在,然后尽可能地根据目标市场所在地的文化观念和消费习惯开发当地语言版本的网站,内容要生动活泼,符合一般群众需求。例如你有40%的客户来自日本,你完全有理由开发一个日本语文的网站。如进入一个自己既不熟悉又很难看懂的网站,大多数人会掉头就走,更不会有兴趣在这网站订购东西了
除了以上直接的原因,与间接网页策略一样,多语种版本可以为你带来额外的访问量。即使鄦的产品或服务只针对香港,内地市场,而且暂时还没有产品外销的计划,那是不是只制作中文网页就足够了呢?其实不是这样的,从提升网站浏览率的角度来看,起码要制作中,英文两个版本的网页。因为网络发源于英文国家-美国,目前英文仍是基本的网络语言,全球著名的搜索引擎商,使用最多的搜索引擎也是英文为主的,你可以将英文版的网页向英文搜索引擎商登记,香港、内地、外国用户会通过英文搜索引擎搜索到你的网页,然后看中文版内容。因此,笔者强烈建议所有的网页都最好至少制作中、英文两个版本。并且,你也许会吸引到国外客户,有意外的收获。
另外,考虑到新的搜索引擎Alexa的排位规则(以同一域名计算网站流量)和网站需要一致的网络标识,多语种版本最好采用与主站一样的域名,或是在域名下设立语种目录,或是使用子域名。例如:雅虎采用的是子域名设计。
主站:http://www.yahoo.com/
中文版(雅虎中国):http://cn.yahoo.com/、http://www.yahoo.com.cn
日文版:http://jp.yahoo.com
如果采用的是语种目录形式的话,式样可能会是这样的
主站:http://www.yahoo.com/
中文版:http://www.yahoo.com/cn/
日文版:http://www.yahoo.com/jp/
完成了网站的规划设计和建设发布,你大可以坐下来休息一下,一边喝着咖啡一边欣赏着自己的网站,但千万不要以为这样就大功告成,可以回家睡大觉,等着订单滚滚而来。其实,这只完成了全部工作的一半,后续工作除了网站内容的持续改进外,还有大量的网站宣传工作要做。例如:主动向搜索引擎商登记注册你的网站,增加链结和以网站访问日志报告作为持续改进网站的客观依据,刊登付费广告推广、网络排名关键字购买等等,
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229639
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
经过辛苦的建站工作,网站终于建成发布了。的确,你大可以坐下来休息一下,一边喝着咖啡一边欣赏自己的网站,但千万不要以为这样就可以坐着待订单会滚滚而来。坦率地说,倘若严格按照前奖期所介绍的建站方法做了,估计会有五、六成的收获把握,不过那可能需要等待较长的时间,因为你要等着搜索引擎在众多的网站中找到你,然后网站被搜索引擎收录、网页媒介标签META(所设置的关键字、网页描述等)被读取,令排位缓慢爬升,然后浏览逐渐地提......。
与上述被动式的"坐等生意"相比,笔者提倡在"精耕细作"基础之上,主动进行网站的推广和网络行销工作。事实上,网站推广和网络行销是一件事物的两个方位。网站推广是让更多的人知道你的网站、提高网站流量;网络行销是如何留住回头客、提升成交率,两者相辅相成,缺一不可。目前网站推广和网络行销的方法归纳有:搜索引擎排名、网络广告、合作专题(软广告)、电子杂志、电子邮件行销等。笔者认为搜索引擎行销是企业网站宣传推广最值得投入的(费用不是很高),而其余的网络行销方式则视情况而定。
一.搜索引擎行销
1.主动向搜索引擎和目录分类站点登记注册
很多企业网站内容丰富,颇有创意,却鲜有访问者,原因何在?在于没有进行网站的宣传推广工作,正如一位绝色女子,却"养在深闺无人识"。没有网站宣传和网络行销,网站如同虚设,你就不可能达到你建设网站的目的。搜索引擎行销的基本思想是让用户发现你,并点击进去进一步了解他所需要的资讯和服务。
还记得上期所做的工作吗?那些网页媒介标签META,那些从竞争对手的网页中找出的,根据自己的具体情况整理的,优于竞争对手的关键字(KEYWORDS),网页标题(TITLE)和网页描述(DESCRIPTION),现在是用武之地了。首先认真准备好网页的TITLE和META标签,以20个最重要的关键字为基本元素,找出与自己网页内容相关的专业性、地区性搜索引擎和目录站点,主动向它们登记注册。
由于95%的网上用户是通过Yahoo!、Google、Altavista、Excite、Infoseek、Netscape、Hotbot、Looksmart、Lycos、MSN、All the Web、Webcrawler、AOL、Netfind、Fast、Ask Jeeves、Dmoz、About、Euroseek和Northern Light等搜索引擎来寻找他们所需要资讯,因此它们是网站登记注册中最重要的部分,在很大程度上决定了网站宣传推广的成败。
目前,市面上专门的搜索引擎登记注册软体很多,号称能自动发送到上千的搜索引擎和目录分类网站,对此应谨慎用之。笔者强烈建议对上述全球TOP 20搜索引擎和目录分类网站,以手工登记为上策(原因很奥妙)。在此以Altavista为例,重点介绍主要搜索引擎登记网页的步骤和技巧。
1)用Meta Medic检查你的Metatag是否符合各大搜索引擎的标准;只有在通过Meta Medic的检测后,才能进行网页登记。(http://www.northernwebs.com/set/setsimjr.html)
2)首先向AltaVista登记你的网站的首页。在所有的搜索引擎中,Altavista收录网页的速度最快,在一至两天内就会收录你所申请登记的网页。隔两天后,在Infoseek中键入你的域名或网页的标题,看Altavista是否收录了你的网站。如果Altavista已经收录了你的网站,键入关键字来检查你的网页在搜索结果的排名情况,如果排名不理想,你需要重复设置首页中的网页媒介标签META。仔细阅读Altavista中Add your page上的提示,向Altavista report your dead link,请求Altavista删除已被收录的网页,然后重新登记你修改过的网页。你需要不断重复以上步骤,直至在Altavista的搜索结果中取得你理想的排名为止。
3)在一个星期后,如果你的网页在Altavista的搜索结果中的理想排名没有大的变化,那么说明你不但通过了Altavista这一关,而且你的Metatag也不会被其他搜索引擎认为是Spamming(胡乱塞入垃圾电子邮件行为)。
4)向其他搜索引擎登记你的网页,要注意三点:
严格遵守每个搜索引擎的规定。如Yahoo!规定网站描述不得超过20个字(包括标点符号),能在Yahoo!的搜索结果中排前10名,将会给你带来很大效益;
只向搜索引擎登记首页和最重要的两至三页,搜索程式会根据你首页的链结读出其他页面并收录。建议第一次只登记首页。
这些搜索引擎收录网页的时间从几天至几周不等。笔者建议等待一个月后,键入你的域名查询。如果网站没有被收录,再次登记直至被收录为止。要注意在一个月内,千万不要重复登记你的网页,这也许会导致网页永远不会被收录。
12家著名中文搜索引擎推介序号网站名称网址
01 雅虎中文 www.yahoo.com.cn
02 Google www.google.com
03 新浪 www.sina.com.cn
04 网易 www.163.com
05 搜狐 www.sohu.com
06 3721 www.3721.com
07 百度 www.baidu.com
08 tom.com www.tom.com
09 21cn www.21cn.com
10 263在线 www.263.net
11 中国搜索联盟 www.chinasearch.com.cn
12 中文Lycos www.lycos.com.cn
2.Google的工作原理
Google自1998年成立至今,在短短5年间已成为全球最受欢迎的搜索引擎(Search Engine),大大超越了老牌入门级的搜索引擎网站Yahoo!,成为大多数网民的首选。以Google为代表的新一代搜索引擎不仅仅只依靠META标签和网页内容的相关度来排名,而是被其他网站录接的数量作为一项重要的排名指标,Google排名规则不仅关注网站设计本身,而且还受其他因素的限制。Google的演算方法一直是个秘密,并且时刻在改变着,据说影响Google排名的因素有三百多种。事实上,Google搜索引擎采用了全新的搜索方式,通过一种复杂的数学分析,估计出一次搜索查询后反馈的网页的质量或重要性及相关主题。要知道一个网页的质量,Google可以通过有多少网页与它连接来判断,这是因为人们不会与糟糕的网页做链接。传统的搜索引擎如Hotbot和Lycos等当前使用的是元素搜索技术,即使用网页中的的关键字进行搜索,而Google则使用一种包含对整个网络的连接结构进行分析和大规模资料挖掘的技术,Google不仅扫描搜索关键字,还阅读页面全文,考虑到图像和所有链结,然后把该页面与类似页面划分开来。
因此,Google排名靠的是经验、资源、细节方面的技巧。在网络行销界,有句很有名的话,那就是"网络行销,细节制胜"。Google排名同样是这样的道理。
如果你的网站想在Google排名搜索结果排到前面,首先,你要把自己的网站建设做好,然后按情况进行改革。如果你没有时间和精力去做这些工作,可以找相关的服务公司或者个人工作室来做。不过,不要因为自己不了解而花掉冤枉钱。比如网络行销公司常常让客户购买一些并不常用的关键字或所谓的热门关键字,或者要求客户支付过高的价格等等。
3.搜索引擎行销的目标层次和网站优化设计
搜索引擎行销的基本思想是让用户发现资讯,并通过点击进到网站/网页进一步了解他所需要的资讯。在介绍搜索引擎策略时,一般认为,搜索引擎优化设计主要目标有2个层次:被搜索引擎收录,在搜索结果中排名靠前。这已经是常识问题,多数网络行销人员和专业服务商对搜索引擎的目标设定也基本处于这个水平。但从实际情况来看,仅仅做到被搜索引擎收录并且在搜索结果中排名靠前还不够,因为取得这样的效果实际上并不一定能增加用户的点击率,更不能保证将访问者转化为顾客或者潜在顾客,因此只能说是搜索引擎行销策略中两个最基本的目标。
利用搜索引擎工具可以实现4个层次的行销目标:
1)被搜索引擎收录;
2)在搜索结果中排名靠前;
3)增加用户的点击(点进)率;
4)将浏览者转化为顾客。
在这四个层次中,前三个可以理解为搜索引擎行销的过程,而只有将浏览者转化为顾客才是最终目的。在一般的搜索引擎优化中,通过设计网页标题,META标签中的内容等,通常可以实现前两个初级目标(如果付费登录,就直接可以实现这个目标了,甚至不需要考虑网站优化问题)。实现高层次的目标,还需要进一步对搜索引擎进行优化设计,或者说,从整体上设计对搜索引擎友好的网站。(参见本文"网站的持续改进"之"改进网站以尽量对搜索引擎友好"。)
二.网络广告
网络广告和与其他大型知名网站合作专题是许多大企业在网络行销上经常采用的手法,其优点在于影响面广,宣传效果好,同时有利于企业品牌的提升,缺点在于费用太高,需要专业的行销策划团队配合,以及设计人员的协助等。该手段适合大型知名企业采用,而对一般中小型企业来说,较可行的方法是选择本行业内较知名的网络媒体合作,这样一方面可节约宣传成本,另一方面目标群体更为明确有效。此外,不定期的更换企业网站上广告条(banner),有针对性对企业产品、品牌展开宣传,也是一种行之有效的手段,在企业网站上也开设专题区,定期策划宣传专题,有针对性地进行宣传,同样可起到引导用户,从而达到宣传效果。专题的选择可以是产品、活动、事件、互动调查等。
竞价排名是搜索引擎关键字广告的一种形式。其中以Google公司推出的关键字广告Adwords业务最为有效和常用。通过Google Adwords(http://www.google.com/intl/zh-CN/ads/)。
你可以自行制作广告,选择关键字,广告出现在所选择的"关键字"的相关搜索页面右侧。收费原则是点击付费(Cost Per Click),从而使得广告非常具有针对性,最低每次点击0.05美元的收费使得该业务尤其适合中小型企业开展网上宣传。
例如,在Google中键入"印刷"关键字,搜索所有中文网站,在其搜索结果右侧的"赞助商链结"中将出现已经购买了印刷关键字的印刷企业的广竹土口,目前共有8家,包括上海金粟印务有限公司、广州皇信彩印纸品有限公司、深圳极雅致印刷有限公司、深圳新联美术印刷厂等。
至于企业如何直接在Google上投放广告以节省费用,由于篇幅限制,在此不做详细介绍,读者可参见专题文章:《如何在GOOGLE上投放广告》(http://www.linkwan.com/gb/articles/97.htm)。
三.E-mail行销与垃圾邮件
目前,国内互联网用户使用最多的是电子邮件,这从另一方面也可以看出电子邮件行销的重要性及其作用。不过,现阶段电子邮件行销的重要性及其作用。不过,现阶段电子邮件行销还不是十分规范,存在着不少问题,因此,笔者认为,如果企业有实力,不妨采用企业电子杂志与电子邮件行销相结合的手段,效果将非常显著。
具体做法是,组织或成立专门的编辑部,负责企业各种资料的撰写、收集和整理,定期把宣传内容制作成电子杂志的形式挂在网站上,并设计订阅,退订视窗,如果用户喜欢你提供的内容,就会主动订阅。通过这种手段,企业可以收集到第一手客户资料,为日后有效的电子邮件行销打下良好基础。不过,笔者建议,初期开展电子杂志可借助外界电子邮件行销服务公司协助发送杂志,待形成规模后再主动传播。电子杂志传播方法如果得到有效实施,不但会给企业宣传带来极大提升,而且也有助企业网站访问量提高。
值得提出的是,以垃圾邮件方式行销。企业应该对规范的电子邮件行销方式有必要的了解。警惕有些打着网络营销旗号的"网络营销软体"、"分类邮件地址"名义垃圾邮件发送者以"定向发布资讯"、"搜集潜在客户"、"邮件群发是最好的网络营销手段"等口号混淆垃圾邮件与许可E-mail行销的概念,使得一些企业和个人在对正规的E-mail行销缺乏了解的情况下发送垃圾邮件,或者委托垃圾邮件发送者发送广告资讯。
四.其他网络行销方式
1.网络行销与传统行销的相互配合
广播、电视、报纸、杂志等传统媒体的行销广告是"广播"方式,即这些广告的观众不全都是你的目标客户。与此相比,Internet网络行销的最美妙之处在于由于网络搜寻资讯的特有方式,人们通过搜索引擎或其他网站的链结找到你的网站,获取产品或服务资讯,决定了网上行销的观众几乎全都是你的目标客户,及"窄播"效应。很显然,只有对某种产品或服务感兴趣的人才会键入与此产品、服务相关的关键字,从而找到此种产品或提供此种服务的商家。因此建议企业在形象设计(CI)中加入企业的网址,将企业网站作为企业形象(CI)的一个部分,在其他传统媒体(电视、广播、报刊、杂志等)的广告中有意识地加入网址,两者相互促进。
此外,企业在日常的营销工作中,也要有意识的加入网站宣传工作。比如,在企业会议室、会客室、业务洽谈室等地方醒目地打上自己的网址,并告诉客户可以通过企业网站了解企业业务和获得相关资料等。以及在企业的各种宣传册、广告、信纸、传真、名片、赠品上,印上企业网址和E-mail信箱。这样,既能体现企业的品位,又能让想了解企业的人可随时随地上网浏览网站。
2.网络会员制行销
网络会员制行销是电子商务中一种有效的行销模式。目前网络会员制行销已经在国内大型网络公司获得了广泛应用,不仅受到大型电子商务网站的重视,也扩展到其他网络服务领域,如搜索引擎的竞价排名、竞价广告等。尤其是在2003年上半年,以"短信联盟"为代表的网络会员制行销模式风风火火,几乎到了过热状态。
其他的网络行销方式还有:链结交换、间接网页策略(也叫迷你网站)、新闻组讨论、电子公告栏(BBS)、结合行销、CRM(客户关系管理)网络行销等。
五.网站的持续改进
1.网站诊断
通过网站访问日志报告,分析网站中的那几页的被调阅率最高,了解访问者对你的产品或服务中的那几项最感兴趣,并在这几页中增加更多内容和资讯,然后以此为主要内容向目标市场推介。
网上行销是一个实践-认识-再实践-再认识的过程。你需要根据访问流量和实际的销售业绩比较,看看影响成交率的是哪些因素,来制定出销售重点和销售策略,再根据实际的市场反应来修正你的销售策略和重点,以及确定哪些网上行销方法最有效,然后再主动出击,有的放矢地进行网上行销。
笔者要重申网站更新的重要性,其原因有三:
1)搜索引擎倾向于将经常更新的网站在搜索结果中排位靠前;
2)网上行销需要你经常更新网站的内容;
3)经常更新网站会增加公司的信任度。当看到很多网站的最近更新日期是几个月或一年前,笔者就会发出这样的疑问:灯总是亮着,但有人在家吗?
为此,建议至少每个月更新一次网站,哪怕只是做最细微的改动。
2.改进网站以尽量对搜索引擎友好
有些企业网站非常重视网页的视觉效果,尤其是首页,常常使用很复杂的图片,或者用Flash等Rich Media形式来展示企业形象,这些固然能从视觉上引起人们的注意,但从搜索引擎优化的角度来看,没有任何价值,甚至起到反作用,让搜索引擎无从检索,用户也就无法通过搜索引擎发现这个网站。
因此,应该在兼顾实用的前提下追求美观,而不是将美观放在首位,在两者之间必须权衡取舍时,宁可放弃外在的美观,因为对于对视觉效果并没有完全一致的评价标准,但搜索引擎却有共同的检索基础,对搜索引擎不够友好,失去的将是自己的潜在用户。强调网站的实用还有一个重要原因:用户通过搜索引擎来到一个网站,他们不是为了欣赏网页的视觉效果,而是为了获得与他在搜索引擎中所使用的关键字相关的资讯。可以想象,如果用户进入一个网站却没有发现自己需要的资讯,他唯一的选择就是尽快离开,这大概不是网站经营者所期望的结果吧!
网站设计对搜索引擎不友好,表现在多个方面,最糟糕的是使得搜索引擎无法检索资讯,或者得到的检索资讯让用户看起来没有吸引力。造成网站对搜索引擎不友好的主要原因是:
大量采用图片形式,没有可以检索的文本资讯;
网页没有标题,或者标题中潒有包含有效的关键字;
网页正文中有效关键字比较少;
网站导航系统让搜索引擎"看不懂";
部分资料库资讯对搜索引擎"保密";
没有与其他网站提供链接线索进行比较。
另外,除了考虑网站的设计、流量的增加、排名提升外,一个非常重要的问题是维持网站的稳定运行和拥有较高的访问速度。试想,一个排名非常靠前的网站,因为伺服器出现问题而造成无法访问,后果会如何?所以,如何降低伺服器故障及优化伺服器功能一直是业界所关心的话题。访问速度和稳定性乃优秀网站之重要指标,亦是提升网站浏览率的物质保障,在伺服器世界里,"稳定代表一切"。
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229638
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
访问速度和稳定性乃优秀网站之重要技术指标,亦是提升网站浏览率之重要环节。在伺服器世界里,稳定代表一切。按业界的一般标准,高档伺服器产品的稳定度达99.99%,也就是说伺服器运行一年内的当机(Hang)时间平均不超过53分钟,中档伺服器的稳定度为99%,平均当机时间是88小时,低档伺服器的稳定度仅为90%,平均当机时间高达876小时。
数据中心伺服器托管一般都是采用1U、2U机箱,尤其是访问量大的mail、web、ftp类的伺服器,对稳定度的要求很严格。如何降低伺服器故 障及优化其性能一直是业界所关心的话题。要达到百分之百的零当机是不可能的,我们要做的是深入分析影响伺服器稳定度的关键问题,采用针对性技术有效提高伺服器的稳定性,使当机时间尽可能地缩短。
就笔者的实际经验而言,影响伺服器稳定与安全之因素主要有伺服器的电源供应器、散热系统、伺服器主板选择、软件运用等。本文将就上述硬件的合理配置、如何评测、以及伺服器软件设置、优化等方面的问题进行探讨。
一、电源供应器
熟悉电脑的用户都知道,电源质量的优劣直接影响到系统的稳定和硬件的使用寿命,并不仅仅是将220V市电的交流电转变为电脑所需要的低电压强电流的直流电这么简单。
如果将CPU(处理器)比拟做一台伺服器的大脑,那么电源就可以说是伺服器的血液了。伺服器对电源的要求不仅是要求提供稳定的电流和较高的功率,还必须能应付各种苛刻的工作环境,同时还要求常年不间断地工作。随着CPU主频的提高,功耗将越来越大,硬盘(Harddis)容量和转速等也越来越大、越快,这对电源的要求就更高了。伺服器通常支持的CPU可以达到2个甚至更多。所使用SCSI硬盘约为2-4个,RAM容量2GB以上,以上配件在消耗能量方面都是惊人的。比如Intel P43.2G CPU 功耗达到82W(瓦特);Prescott 0.09微米制程P4-E 3.2G更达103W,所以目前Prescott CPU 己不适合应用在1U、2U机箱做伺服器。而SCSI硬盘的功率也在10W以上,所以伺服器系统所需要的功率远远高于一般PC,一般PC只要200W电源就够用了,而伺服器1U机箱应有300W,2U应有350W。
高品质电源是伺服器正常运行的重要保证,也是一般人最容易忽略的。实践经验告诉我们,电源导致伺服器经常自动重启(Reboot),致使硬盘出现坏道。功率不足使+5V、+3.3V和+12V在满负荷状态运行时(CPU使用率保持在100%,硬盘也在大量读写资料,功率消耗大)出现电压波动,或者散热不良造成过热,是经常性自动重启的主要原因,造成伺服器不能正常提供服务,同时也会缩短硬件的寿命。
二、散热
散热是伺服器要解决的首要问题之一。伺服器硬件一般放在1U、2U机箱内配合机架统一使用,机架伺服器的宽度为19英寸,高度以U为单位(1U=1.75英寸=44.45毫米),在狭小的空间内有大量的硬件高速运行状态下散发的热量非常大,且伺服器一般要求24小时不间断工作,如果机箱材料的选用或内部结构设计不良,导致整体散热性能差,则会经常导致伺服器出现当机、重启等状况。
首先,伺服器机箱的选料就马虎不得。首选全铝质的或者铝合金的,次选铁板。颜色应漆成黑色,以利于散热。采用全铜及直接整体铜切割出来的CPU散热器较好,其散热效果优于其它材料,是伺服器CPU散热的理想选择。但为达到最佳散热效果,须配合品质良好的散热膏并正确地使用。笔者采用Arctic Silver 5纯银散热膏,严格按照说明书操作,成功将CPU温度降低3-4℃。
再者,采用高风量(CFM)散热风扇对伺服器来说也是关键组件,散热风扇一般分滚珠轴承、油封轴承两种。滚珠轴承较为耐用,所以广泛应用,虽噪声略高,但实际上伺服器放在机房中,噪音干扰不成问题。判断风量的大小可以从风扇注明的A(电流量)或W(功率)来作选择,数字越大风量越强。可选择Delta、Sunon、Nidec、Sany、Y.S.Tech等名牌,以确保长期运转不出故障。为提高散热效果,也可选用小型鼓风机(BLOWER)。笔者使用的伺服器,选用小型鼓风机配合1U机箱,另加6个万转4CM电流0.24A强力风扇使机箱温度降低了8-10℃左右。有兴趣了解各类强力风扇的朋友可到超频专门店网址http://www.pcbulb.com/查询。近期Sany推出1.5万转4CM电流0.55A风量20.83CFM超强力风扇是1U伺服器散热较佳配搭。
另一方面要合理设计风道,在安装好硬件后把机箱内的cable、电线整齐地扎好,以保证机箱内气流循环无阻,能更有效地对CPU、RAM、硬盘、南北桥晶片等进行散热。Intel P4CPU温度75℃、AMD CPU温度86℃是工作温度极限,高温时CPU将会自动降低工作效率。所以在1U机箱伺服器P4平台full loading CPU温度能维持65℃左右及机箱温度50℃以内可算不错的散热效果。注:(Intel 的设计规范CPU温度不超过72℃)
三、主板
不可置疑,主板对于伺服器至关重要。主板犹如人的骨架,承载着CPU、RAM(记忆体)等重要部件的运行。如果你的伺服器电源质量可靠,功率充足;机箱及CPU散热良好,但仍偶尔会莫名其妙的当机,就该考虑问题可能出自主板了。有些主板在当机后,因有自我保护功能,必须关掉电源再开机;更有甚者,必须清除CMOS中的记忆,才可以重启,这对伺服器的远程维护与管理造成严重障碍。
INTEL主板是少数通过WHQL微软WINDOWS操作系统硬件质量认证的产品,稳定性和兼容性经受实际考验,INTEL生产的主板严格遵照规格制造。在性能方面INTEL原厂伺服器主板针对WINDOWS操作系统做了优化设计,加上INTEL对自己生产的处理器最为了解,更容易释放出自家处理器的性能,可以说INTEL的主板是高品质与高性能兼具的产品。但是INTEL也有为了稳定性而牺牲性能的传统,与同级的主板晶片组比较,INTEL的主板总是比其它大厂的主板要慢上一点,功能方面也没有太多的扩展性。但是在伺服器最注重稳定性的原则上,笔者强烈推荐采用INTEL主板。
四、评测
综上所述,电源、主板及散热是如此重要。直接影响到伺服器的稳定与安全,那么,你要如何判断其好坏呢?下面,我们将自己动手进行评测,去了解自己的伺服器是否处于一个良好的工作状态。
测试平台的搭建,主要考虑电源输出电压的稳定和主板、CPU等机箱内关键部分温度的测试。对于电源的测试相对比较简单,我们当然没有必要像专业电源制造厂商一样,用示波器、万用表甚至用ATE(自动测试仪)等专业工具来进行测试,仅通过软件来进行测试就足够了。虽然通过软件测试只能作为一个参考,所测值可能会与你的电源的真实值有所差距,但是通过这个测试,我们还是能大概看清自己伺服器中电源的"真实面目"。当然,探测主板及CPU的温度,用软件来测试也是很容易的事了。
Windows任务管理器可以监视电脑的CPU 和RAM使用情况、程式和进程的相关信息。建议搭配下述推荐评测软件共同使用。
*MBM5温度、电压监控软件
MBM5是一款用来探测主板CPU温度以及电压的软件。推荐使用Motherboard Monitor 5(以下简称MBM5)来测试。MBM5最新5.3.6.0英文版本、最新5.3.6.0多语言版本。其适合作业系统:Windows 9X/Me/2000/XP,可在世界网络:http://www.linkwan.com/gb/download/下载。
当温度超高过你的设定值时,MBM5便会启动警示音乐或是显示警示文字,还可以输出TXT或HTML格式的日志文件。
安装MBM5完成后,开始设置,这是关健的一步。因为不同主板的检测晶片是不同的,所以要先设定了MBM5。在程式集里面找出MBM5,然后运行MBM 5Config Wizard。
如下画面出现,点击NEXT。
如安装好的MBM5不能完全支持你最新的主板,请试试点击Update(升级),一般更新后软件会对更多新主板支持。升级完成后,进入下一步,出现如下画面,列出许多厂家和主板型号,根据你的主板,选择相应的主板厂商和主板名称。比如,笔者的主板为Intel S875WP1-E,选好后点击NEXT。
之后会出现一些选项,比如选择温度单位是摄氏度(Celsius)还是华氏度(Fahrenheit)。不同的主板也可能会出现不相同的设定,一般使用默认。
最后点击Finish。到了这一步许多朋友可能会想,这样就应该完成MBM5的安装了吧?其实不然。还有一个非常重要的设置,否则,MBM5测出来的值是不正确的。
运行MBM5,打开管理界面,在安装了语言包后,你可以选择繁体/简体中文。
然后在Voltages(电压)中,Voltages Configuration(电压适配器)要选择自己的主板的型号,如果在列表中没有你的主板型号,请先不要急,那是因为一般的主板都是采用标准的ITE8712F传感器,但你也可以对应你的主板进行相应的选择。
显示CPU温度、主频,风扇转速、机箱温度
点击Apply(应用)后,再看一下Dashboard看看是否都正常。该软件具体的使用,大家可按提示操作。
*OCCT电源测试软件
谈到电源质量的测试,就不得不提一下OCCT这个软件。其适合作业系统:Windows 9X/Me/2000/XP 可在http://www.linkwan.com/gb/download/下载。
OCCT需要和MBM5这个软件共同协作才能为用户提供一份完美的电源质量报告。在测试过程中,OCCT通过MBM5所测出的资料,自动模拟电脑满负载的状态,让电脑连续30分钟满负载运行,最后得出相应的电压波动图表,通过这些图表,用户就可以判断出电源是否令人满意了。
在安装好MBM5及OCCT后,点击桌面捷径方式就可以进入OCCT的主界面了。首先点击右下方的"Option"(选项)键进入设置界面,在这里用户可以对测试电压的负载进行设置,供用户选择的有"Lowest"(最低)或者"Highest"(最高)等5个等级,还可以设置使用内存(RAM)的大小、CPU温度以及输出图像的格式。设置完毕后,点击"Go Back"(返回)回到主界面,再点击左下方的"Test"(测试)键就可以对电源进行测试了。
测试将进行30分钟,这期间,OCCT占用系统资源很多,用户最好不要进行其它操作,否则可能会出现死机。测试完毕后,OCCT将把测试结果以分析图的方式呈现在用户眼前,这些分别是"系统(机箱)温度变化"、"CPU温度变化"、"+5V的电压波动"、"+3.3V的电压波动"、"+12V的电压波动"以及"CPU电压波动"。
如果用户的电源品质良好,那么图表上的各种电压波动幅度会非常小,即使有波动也是在正常范围之内;如果用户电源质量比较低劣,那么图表上各种电压的波动范围也会相应较大。
OCCT还可以单独对CPU进行测试,只要点击主界面下中间的"Torture"(CPU稳定检测)键就可以对CPU进行稳定性测试,并向用户报告错误。另外,由于OCCT可以实时监控CPU温度、系统(机箱)温度以及电源各个输出电压的情况,所以它也可以作为一款监控软件使用。
好了,我们终于可以开始我们的测试了。打开OCCT软件(它会自动关掉MBM5)点击test(测试)。你可以去休息了,约半个小时后再来看看成绩吧。
在OCCT进行测试的过程中,它会模拟你的伺服器在满负荷的状态下运行。在这期间,我们来了解一下伺服器的电源吧。为了保证电源的输出稳定,伺服器电源供应器都设计了一套自动补偿电路,也就是当电源的其中一组电压需要更大的功率的时候,它就会提高那组电压的输出电压,但由于不是每组电压都可以单独进行补偿,也就是说,我们的电源在提高一组电压的同时,其它的所有电压均会相应的提高。这样,就会形成一个特殊的现象,比如+5V因为负载太大而导致输出电压开始下降,电源会同时增加所有的输出电压,并不会单独对+5V进行控制,其结果必然导致其它电压组因为输出电压过渡补偿而超过额定的电压,当电源设计欠佳或输出功率不足时这种特有的现象就更加明显!这样,电脑内许多设备都会在较高的电压环境下工作。
那什么范围才算是合理波动呢?电源输出的正电压,合理的波动范围在-5%~+5%之内,而负电压的合理波动范围在-10%~+10%。
只要电源的输出在合理的范围内,对电脑的配件都不会造成负面影响的,所以也不用过分地关注波动的大小。但波动的相对大小,侧面反映了电源的负载能力,波动率相对越小的电源,其实际的最大输出功率可能越大。
下面我们来看看测试结果吧,笔者的测试是在以下平台完成的:
CPU :P4 2.8G (800FSB)
RAM :1G DDR400RAM
主板:Intel S875WP1-E
硬盘:WD360DG,36G 1万转SATA
电源:美基350CD(300W)
首先来看看CPU温度,从图中可以看出,从44℃升到64℃。看起来还是不错的。
+3.3V电压,大致波动范围是3.3195-3.336V,还不错,是在正常范围(3.14-3.46V)内,此电压主要应用在显卡、PCI、南北桥等设备。
再来看一下,系统要求最高的+5V电压,看这个图,波动曲线还不算大,在(5.123-5.16V)范围内供电包括CPU(旧式主版)、RAM、硬盘、光驱、I/O及主板的其它设备。
+12V,波动范围在11.85-11.975V,波动范围看似挺大的。主要应用在耗电量比较大的设备上,例如风扇,硬盘、光驱,新式主版用来转换为CPU所需的电压。
CPU电压,我在BIOS中设置的是1.45V,所以测试出来的结果也是在1.45V左右,看起来还是平稳。
测试结果看完了,该电源供应器总的来说非常不错,虽然所有电压均稍微偏离中心值,但均在安全的范围内。OCCT不对负电压进行测试,因为这几个电压的输出电流均小,而且相应的正电压的值也就可以大概看出负电压的波动。除了看波动范围,还需看波动大小。由下表可见笔者伺服器所用美基350CD电源的电压波动幅度非常小。
电压 |
合理波动范围 |
美基350CD (300W)实际波动范围 |
稳压精度 |
+5V |
4.75-5.25V |
5.123-5.16V |
3.04% |
+3.3V |
3.14-3.46V |
3.3195-3.336V |
1.1% |
+12V |
11.4-12.6V |
11.85-11.975V |
1.07% |
*Hot CPU Tester系统稳定度测试软件
为进一步考验伺服器的稳定性,笔者还给大家介绍一个不错的软件-Hot CPU Tester。其作用是考验CPU的稳定性以及散热系统的优劣(需要温度监控软件配合使用),不过在烤机(烧机)的时候还有一个附加功能,那就是可以发现CPU是否被超频。其最新版本:4.0,其适合作业系统:Windows 9X/Me/2000/XP,可在http://www.linkwan.com/gb/download/下载。
安装好Hot CPU Tester,桌面会显示一个icon ,双击icon进入Hot CPU Tester的主界面。下面主图左边是菜单,在这里我们可以看到7个选项,分别是"Diagnotisc"(检测运算测试)、"Burn-in"(CPU、RAM测试)、"Benchmark"(基准测试)、"System Info"(系统信息)、"Option"(选项)、"LiveSupport"(在线支持)以及"About"(关于)。可以看出,Hot CPU Tester是一个非常全面的测试软件,在这里,我们着重介绍几个Hot CPU Tester的主要功能。
*稳定性测试
稳定性测试主要是依靠"Diagnotisc"(检测运算测试)和"Burn-in"(CPU、RAM测试)两个功能。只要在"Diagnotisc"(检测运算测试)的界面中单击"Run Test"(开始测试)键就可以开始对系统进行测试。这个测试是让伺服器连续运算各种项目,使CPU在一段时间内保持使用率为100%,以此来测试CPU的稳定性。
中间的界面是测试的项目,包括硬盘、内存(RAM)以及MMX等,下方有CPU资源占用的情况,通常不到几分钟,CPU使用率就会达到100%。如果在这种状态下能让Hot CPU Tester运行达1小时以上,那么CPU的稳定性就算达到标准了。另外,由于CPU长期在100%状态下工作,会产生极大的热量,这个时候通过MBM5温度测试软件就可以看到CPU及系统的温度,并以此判断散热系统的优劣了。
在右下方,Hot CPU Tester会显示测试进行的时间,以及开始测试和结束测试的时间。另外,在Option(选项)中还可以对测试进行一些设置,比如测试的时间以及测试时硬件的状态,有一些功能需要用户注册后才能使用。
如果你只想测试CPU和内存,那么可以进入"Burn-in(CPU、内存测试)"的界面,在这个界面中可以设定测试的次数以及测试内存的大小,然后直接点击"Run CPU Burn-in(开始测试CPU)"键或者"Run Memory Burn-in(开始测试内存)"键进行测试。
小提示:在进行测试的时候,由于伺服器CPU的资源占用率达到了100%,所以这个时候操作其它程式都是危险的,极可能引起系统崩溃,所以在进行Hot CPU Tester测试的时候,应该关闭其它程式。
*性能测试
在Hot CPU Tester中也有类似PCMark2003的系统性能测试。进入Benchmark(性能测试)菜单中,点击右上角的"Run Benchmark"(开始性能测试)就可以对系统整体性能进行测试,测试项目在中间窗口中显示,测试结果会出现在"Total Score"(总分)的空格中。
五、伺服器软件优化
提到系统优化,我们有必要区别碎片整理和系统优化的概念。前者指系统向磁盘存储的文件体积大于磁盘提供的连续存储空间时,因此不得不将文件拆开分别存于几块不连续的物理磁盘区域,从而产生了所谓的磁盘碎片,而通过软件的调整将其转化成连续区域的过程称为碎片整理。系统磁盘优化则全然不同,它有两个方面:首先,根据文件调用的频繁程度来调整它们在磁盘中的位置,把使用频繁的文件放在磁盘开头以达到最短的调用时间;另外一个过程恰好与碎片整理相反,就是整理未被占用的磁盘空间,让它们连成一片,使以后磁盘碎片产生的可能性降至最低。
对访问量大的伺服器,定期的磁盘整理对于提高硬盘访问效率、保持系统稳定性非常有用。一般用户都是习惯使用WINDOWS自带的磁盘整理工具,它的优点在于工作时只占用CPU 10-30%适合伺服器在线时整理,不影响服务但其速度和效能往往不能令人满意。
现介绍二个优秀磁盘优化软件:
1)Norton Utilities
Norton Utilities是诺顿工具包Norton SystemWorks 2003中的一个组件,该软件是一个功能强大的磁盘修复、磁盘优化、系统维护和系统优化工具。在你的伺服器上运行该软件后,你将会发现Norton Utilities所具有的那些性能强大的功能是不可缺少。系统优化(Optimize Performance)选项中的Speed Disk工具,可用于优化系统磁盘,将最常用的档案放在硬碟最前端,使存取时间更短,以提高伺服器性能。优化磁盘的步骤非常简单,大家按下Optimization Map,在右边选择一个需要进行优化的磁盘分区,再按Start Optimizing即可开始优化磁盘。
在优化过程时,我们可以发现,Speed Disk的整理速度要比Windows自带的碎片整理程序快许多。但由于工作时占CPU使用率就会达到50%左右,如伺服器在线时流量大,可能会影响服务。笔者在一台使用Intel P42.8GHz处理器、1G内存、安装WINDOWS 2000SERVER的伺服器上对Norton Utilities进行了测试。为了测试该软件,我们在开启许多应用程式的情况下反复的重启伺服器、向注册表中添加许多错误条目、将程式的捷径指向错误的可执行档案,并且在电脑中反复安装和解除安装软件以便能够在硬盘中产生大量磁盘碎片。在我们所做的测试中,Norton Utilities成功地报告各项错误,而且很好地完成了修复工作。查找及修复系统问题上Norton System Doctor(系统医生),监测的内容要丰富得多。还有Norton Disk Doctor(磁盘医生)和Norton System Check(系统检查)等,功能都很强大。
2.Voptxp V7.12
除了Norton Utilities外,Voptxp v7.12也是优秀磁盘软件,可以把磁盘一些详细资料显示出来包括:磁盘使用和剩余空间图例结构图,当前磁盘碎片个数情况,当前磁盘文件和文件夹个数,分区大小,不连续文件个数,交换文件的情况等,和传统的磁盘碎片整理程序比较,Voptxp v7.12有着更大的优势:多任务窗口、速度快、功能强大等特点,更在"优化"选项中有:互联网优化和系统优化两个不错的功能,是一个完美的测试工具,帮你节省更多时间。
除系统及硬盘的维护问题外,操作系统的安装与配置、系统的及时更新与升级、杀毒软件的使用及日常的管理和维护等都是非常重要的。笔者就自己日常管理网站伺服器的经验,整理出来供大家分享。
a、定期查看系统/网站日志,查看是否有异常报错,以便找出网站存在的问题。系统有那些缺陷,可通过系统日志反映出来,通过网站日志,可以找到那些页面有错误、那些页面需优化、那些图片及文件应删除或减肥使网站访问的效率提升。查看网站日志最好是能安装相关的网站日志分析工具,使日志更直观。
b、必要时重启伺服器也是提高访问速度的方法之一,WIN系统定期重启是必要的,以释放一些使用完而没有被释放的资源。
c、当使用ACCESS数据库时,数据库最好是分多个文件来处理,这样读取和存贮速度都会快很多。数据库很大时最好是用MS SQL,不论是处理资料还是 数据容错性都会有一个质的提升,使用MS SQL要定期对SQL数据库日志进行清理,清理SQL的日志有利于降低系统资源的使用,特别是内存的占用率。
d、经常留意伺服器的资源使用量,查看是那些程式占用的系统资源比较高,是那些程式或那些内容引起的,是否属于正常。留意系统最新的(Service Pack)补丁程式和病毒,及时更新相关软件,打补丁程式要先在其它机上测试后再在伺服器上安装,以免引起兼容性的问题。查看伺服器的流量,随时分析伺服器状态,通过流量可知伺服器是否正常,如有骇客或入侵都会产生比较大的流量。
e、WIN2000在默认情况下会安装一些常用的组件,但是这个默认安装是极度危险的。你应该明确地知道你需要那些服务,而且仅仅安装你确实需要的服务。根据安全原则,最少的服务+最小的权限=最大的安全。典型的WEB伺服器需要的最小组件选择是:只安装IIS的Com Files,IIS Snap-In,WWW Server组件。如果你确实需要安装其它组件,特别是:Indexing Service,FrontPage 2000Server Extensions,Internet Service Manager (HTML)这几个危险服务,请慎重处理。其它的不在此详述。
经过评测,您是否拥有了一台性能稳定、处于良好工作状态的伺服器,为迎接随后接踵而来的访客做好准备了呢?是的,经过了前期细致的建站准备工作,又经过了紧锣密鼓的网站规划建设和网络营销工作,相信您网站的浏览率和知名度将会节节攀升,名列前茅。下期笔者将就优秀中文印刷网站的排名情况和本系列文章做最后的总结。希望不久的将来您能榜上有名
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229636
发表时间: 2008年06月19日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
目前国内用的最多的无非就是 美国-韩国-香港-台湾-加拿大 日本 英国 德国 比较少吧!日本可能SEX的比较多!
今天做的比较,是自己有初步接触,部分机房有用的,拿出来比较下:
1、比-速度
美国:(机房名地理位置-加洲、华盛顿、纽约、路易斯安娜、亚拉巴马、北卡罗来那、德洲、乔治亚)
美国整体速度其实不错,主要是看地理位置和机房!有些朋友都认为中国访问美国的,不行,慢!其实未必,选择一个好的机房,国内整体来说速度还是不错的。 现在由于做SEX和六合的多,很多国内同行 都把客户放到美国,一台服务器上放了很多六合和SEX的用户,没有很好的控制,会造成访问很慢,整体来说 美国的速度还是满优秀的!
香港:(机房名地理位置-HKNET、新世界电讯、、ENET、城市电讯、和记、太平洋电讯)
香港原本连接国内速度其实很快的,真的可以说和国内一样的快。可是大家都知道香港做六合的多,特别到了开奖的时候特别卡,有些客户经常会骂 “你们香港服务器怎么那么卡啊?” 中国这么多人去访问香港 能不卡吗???
HKNET ENET盈科 新世界都是比较常用的机房,这几个机房每个礼拜那几天总是比较慢的!
新世界我用了1年多了,个人感觉还算满意,但是最近比较不理想很糟糕!特别福建泉洲-广东一带的客户访问很不理想! 城市电讯 国内电信客户访问比较理想,可是和厦门电信一样 快成为“稀有品种”了。 和机、太平洋都比较贵,适合大企业客户!
韩国:(机房名地理位置-釜山、汉城、安山、大田、仁川、光洲、大邱、庆洲)
速度很明显可以感觉的到!真的很不错,可是由于价格的原因,能用的上的朋友,也不是很多。 记得落伍以前那个MR.L提供的韩国 虚拟主机,速度大家都可以看的到的吧。
台湾:(机房名地理位置-高雄 台北 新竹 嘉义 苗栗 台东 花莲)
速度不错,起码我是在厦门,访问的时候 感觉很不错!但是好象很少人用,而且价格方面,也是有点不敢恭维,等会下面比价格的时候再详细比。
台湾在 虚拟主机上控制的也不错,他们SEX也特别的多,和美国一样流量限制很严格,很少有商家做不限制流量的,做不限制流量的价格也非常的可怕!下面再提!
加拿大:(机房名地理位置-无)
加拿大,个人租用过一次,速度实在不敢恭维,不知道其他朋友用的怎么样。
2、比-价格
美国-c42.4 512 80g MD机房算不错 速度还满理想的,价格约为 600-700元RMB 国际代购价算在内 国内市场价650-900元!
香港-c42.4 512 80g 新世界不错,价格合理,速度现在不是很理想,市场价约为700-900,国内市场价900-1500元!
台湾-c42.4 512 80g 台中的还成,其他的没用过,市场价在1000左右,国内做的价大概在1500以上,利润满高的!
韩国-c42.4 512 80g 市场价1000-1200左右 国内市场价1500-1900左右!
加拿大-不熟,不太了解!
3、部分商家推荐
http://www.smartinfo.com.hk/ 香港
http://www.asiahost.com.hk/ 香港的 性价比不错
http://host.cigi.com.tw 台湾
Ipowerweb.com
Globat
Startlogic
MidPhase
Powweb 美国的 性价比 不错!
总结:
对于国内的朋友来说,美国-香港都是不错的选择!
美国100M asp+ac+asp.net(50IIS-100IIS) /php+MYSQL+5-10G月流量 市场价300-600 再贵 利润实在太高了!
香港价格和美国差不错!韩国台湾的价格会比较贵点!
站点经营内容选择:
企业用户/个人用户
此类用户建议采用香港,台湾的服务器或是虚拟主机。为什么不推荐使用美国? 因为美国毕竟有时差,如果是服务器在美国,日常的维护会比较麻烦,而且还有就是沟通上还是有差别,当然英语好的,那就不一样了。
特殊用户:
如XX,LHC,ZQ之类的客户,此类客户是非常的多,最常用的是 香港,但是香港IP少,而且封的也快。美国也是很不错的选择,美国有的机房速度也很快,但是好的机房价格又要比普通机房的价格贵1-1。5倍。但是美国优势在于IP多,(下面会再举例选购的误区! ) 台湾,台湾其实也满快的,但是价格和流量 是一个很大的屏障!
推荐 香港新世界/城市电信 (注意选择IP段) 美国!
选购误区:
1、现在市场上美国服务器都标 10个IP,注意,大家购买的时候要问清楚,是如何分配法。
美国机房现在开始抓IP,经常看到的IP分配为1+9 4+6 等。
注意,并不是网站上标明10个IP,就是一次性给你10条,而是第1次 可能给你1条,之后9条需要申请,但是申请了未必就是给你9条,有可能2条,3条这样。 目前比较明显的就是 美国的MD机房。
2、香港独享带宽
香港目前有2家以上提供每台服务器独享2M带宽。 这里的2M是每秒2M,并且,根据不同商家,限制是不同的。
有的商家是限制2M,超过了就不行,有的说是2M,但是实际用起来有的超过4M。(我有个客户就是做代理服务器的,之前和我合作的是一家香港公司,他们之前柜子机子少,所以当时客户能跑到4M左右,没做限制。)基本上2M独享 大多商家还是有限制的!!! 但是,不要拿国内的10M和香港的2M对比, 可以说,香港城市的2M独享 效果要比国内10M效果来的好,国内10M保证那些都是文字游戏,BS。 而且香港城市电信提供的带宽,国内无论电信,网通,铁通 访问都特别的快。(这里拿出个自用服务器给大家测试203.186.128.225 ,)注意,同个机房不同的路由,不同的带宽接入 还是有差别!!!
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229634
发表时间: 2008年06月23日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
其于window系统的同步实战
1. 远程数据同步工具Rsync介绍
1.1 软件简介
Rsync是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。Rsync本来是用以取代rcp的一个工具,它当前由 rsync.samba.org维护。Rsync使用所谓的“Rsync演算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。运行Rsync server的机器也叫backup server,一个Rsync server可同时备份多个client的数据;也可以多个Rsync server备份一个client的数据。
Rsync可以搭配rsh或ssh甚至使用daemon模式。Rsync server会打开一个873的服务通道(port),等待对方Rsync连接。连接时,Rsync server会检查口令是否相符,若通过口令查核,则可以开始进行文件传输。第一次连通完成时,会把整份文件传输一次,下一次就只传送二个文件之间不同的部份。
Rsync支持大多数的类Unix系统,无论是Linux、Solaris还是BSD上都经过了良好的测试。此外,它在windows平台下也有相应的版本,比较知名的有cwRsync和Sync2NAS。
Rsync的基本特点如下:
1.可以镜像保存整个目录树和文件系统;
2.可以很容易做到保持原来文件的权限、时间、软硬链接等;
3.无须特殊权限即可安装;
4.优化的流程,文件传输效率高;
5.可以使用rcp、ssh等方式来传输文件,当然也可以通过直接的socket连接;
6.支持匿名传输。
1.2 核心算法
假定在名为α和β的两台计算机之间同步相似的文件A与B,其中α对文件A拥有访问权,β对文件B拥有访问权。并且假定主机α与β之间的网络带宽很小。那么rsync算法将通过下面的五个步骤来完成:
1.β将文件B分割成一组不重叠的固定大小为S字节的数据块。最后一块可能会比S 小。
2.β对每一个分割好的数据块执行两种校验:一种是32位的滚动弱校验,另一种是128位的MD4强校验。
3.β将这些校验结果发给α。
4.α通过搜索文件A的所有大小为S的数据块(偏移量可以任选,不一定非要是S的倍数),来寻找与文件B的某一块有着相同的弱校验码和强校验码的数据块。这项工作可以借助滚动校验的特性很快完成。
5.α发给β一串指令来生成文件A在β上的备份。这里的每一条指令要么是对文件B经拥有某一个数据块而不须重传的证明,要么是一个数据块,这个数据块肯定是没有与文件B的任何一个数据块匹配上的。
1.3 命令语法
rsync的命令格式可以为以下六种:
rsync [OPTION]... SRC DEST
rsync [OPTION]... SRC [USER@]HOST:DEST
rsync [OPTION]... [USER@]HOST:SRC DEST
rsync [OPTION]... [USER@]HOST::SRC DEST
rsync [OPTION]... SRC [USER@]HOST::DEST
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
对应于以上六种命令格式,rsync有六种不同的工作模式:
1)拷贝本地文件。当SRC和DES路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。
2)使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DST路径地址包含单个冒号":"分隔符时启动该模式。
3)使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号":"分隔符时启动该模式。
4)从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式。
5)从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含"::"分隔符时启动该模式。
6)列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。
主服务器
IP 192.168.0.100
F:/data/www
备份服务器
IP 192.168.0.101
F:/data/www
实战:
1、http://rsync.samba.org/ 下载cwRsync客户端(cwRsync)和服务器端(cwRsyncServer)。
2、服务器端安装:采用默认选项安装。
安装后,服务默认为手动启动模式,到“管理工具/服务管理”里,启动“RsyncServer”服务,并修改“RsyncServer”为自动启动模式。
1、http://rsync.samba.org/ 下载cwRsync客户端(cwRsync)和服务器端(cwRsyncServer)。
安装的过程很简单,也很顺利,从 cwRsync 网站上下载的 server and client ,都安装了一下,不过后来发现,其实是不需要安装 client 的,只要 server 就可以了,server 包括了 client 的功能。安装完 server 后,会在 service 中增加 Rsync 和 ssh 服务。
服务器端安装:采用默认选项安装。
安装后,服务默认为手动启动模式,到“管理工具/服务管理”里,启动“RsyncServer”服务,并修改“RsyncServer”为自动启动模式
2、配置主服务器
配置了一下 rsyncd.conf
use chroot = false
strict modes = false
hosts allow = *
log file = rsyncd.log
pid file = rsyncd.pid
# Module definitions
# Remember cygwin naming conventions : c:\work becomes /cygwin/c/work
#
[test]
path = /cygdrive/c/work
read only = false
transfer logging = yes
只是将 [test] 中的 path 改成了我本机的备份目录
[www]
path = /cygdrive/F/data/www
read only = false
transfer logging = yes
3、备分服务器数据同步
因为只是最简单的数据同步,所以就不使用 ssh 了,直接启动 rsync 服务就可以了。然后按照 usage 上面教的。
rsync -av /cygdrive/F/data/www 192.168.0.100::www
完成了数据的同步工作,一切顺利。顺便说一下,/cygdrive/d 是安装完 cwRsync ,会自动将系统上所有的盘 mount 成 /cygdrive/x ,x 表示盘符,小写的,并把安装目录 mount 成 / 了。
这样我们实现了从主服务器到备分服务器的数据同步
下一步我们结合windows的任务调度来实现这个批处理文件,取名为XXX.cmd
rsync -avr --ignore-errors --force 192.168.0.100::www /cygdrive/F/data/wwwroot
test.bat
---------------------------------------------------------------------------------------------
@echo off
set path=%path%;C:\Program Files\cwRsyncServer\bin;
date /t >> F:\syn.txt
time /t >> F:\syn.txt
rsync -avr --ignore-errors --force --exclude="/tmp/" --delete 192.168.0.103::test /cygdrive/F/temp >> F:\syn.txt
date /t >> F:\syn.txt
time /t >> F:\syn.txt
echo .
echo .
echo . remote synchronous over
echo .
echo .
rem pause
---------------------------------------------------------------------------------------------
linux中安全性说明
一:服务端rsyncd.conf文件配置
uid = nobody
gid = nobody
use chroot = no # 不使用chroot
max connections = 4 # 最大连接数为4
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log # 日志记录文件
[inburst] # 这里是认证的模块名,在client端需要指定
path = /home/inburst/python/ # 需要做镜像的目录
comment = BACKUP CLIENT IS SOLARIS 8 E250
ignore errors # 可以忽略一些无关的IO错误
read only = yes # 只读
list = no # 不允许列文件
hosts allow=172.25.43.57 #允许连接IP
auth users = inburst # 认证的用户名,如果没有这行,则表明是匿名
secrets file = /etc/inburst.pas # 认证文件名
注:
为安全考虑,在设置服务端rsyncd.conf模块时,最好加上auth users = inburst,secrets file = /etc/inburst.pas,密码写到一个文件中inburst.pas。
执行命令时:rsync -avrp /test/ [email=inburst@172.25.43.158::test]inburst@172.25.43.158::test[/email] --password-file=inburst.pas。
二:客户端脚本
rsync -avrp /test/ [email=administrator@172.25.43.58::test]administrator@172.25.43.58::test[/email] --password-file=1234567
(表示将客户端test目录下文件备份到服务器test模块下。如果将/test/放后面,表示将服务器test模块下目录备份带客户端/test/下。)
选项说明:
-v, --verbose 详细模式输出
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-r, --recursive 对子目录以递归模式处理
-R, --relative 使用相对路径信息
其他参数可以查看rsync相关手册。
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229632
发表时间: 2008年07月04日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
dwr动态载入小结
笔记在实际开发中用到dwr框架,一直以来,常为加载中提示用户等待这问题困扰,经笔者研究,摸索出一个切实可行的方案,供大家参考。
实例如下:
<a style="cursor:hand" onclick="changeStatus(this);Test.invoke('${parameters}','${pageId}',callBack);"><img src='/icon.gif'></a>
函数说明:
changeStatus我们将用来改变提示状态值
Test类的invoke函数将触发从台数据库取出值
然后通过回调函数callBack负责在页面显示出来
页面配置
<script type='text/javascript' src='/dwr/interface/Test.js'></script>
<script type='text/javascript' src='/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/util.js'></script>
<script type='text/javascript' src="/js/prototype-1.4.0.js"></script>
dwr.xml
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create creator="new" javascript="Test">
<param name="class" value="pakage.Test"/>
</create>
<convert converter="bean" match="pakage.Test"/>
</allow>
</dwr>
回调函数
var callBack=function(data){
var pageId=data.pageId;
var list=data.listEntityBean;
if ($(pageId).style.display == "none") {
$(pageId).style.display="block";
var htmlStr = "";
for (var i = 0; i < list.length; i++) {
htmlStr +=...//这里是将list中的值取出来给一个字符串
}
$(pageId).innerHTML = htmlStr;
return;
}
$(pageId).style.display="none";
}
pakage.Test类
public class Test {
private String pageId;
private List list;
public String getPageId() {
return pageId;
}
public void setPageId(String pageId) {
this.pageId = pageId;
}
public String getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
static Log log= LogFactory.getLog(Test.class);
public void invoke(String parameter,String pageId){
this.setPageId(pageId);
this.list=...//这里根据参数从数据库里取出值来
return this;
}
至些我们完成的dwr的编写。
function changeStatus(obj){
var htmlStr = "";
var oPopup = window.createPopup();
DWREngine.setPreHook(function() { //这是正在加载的代码
htmlStr = "<img src=\"/loading.gif\">";
obj.innerHTML = htmlStr;//这里是改变传入对象的值,是dwr正在加载时的提示,如loading,我这里是用的是图片
var oPopupBody = oPopup.document.body;
oPopupBody.innerHTML = "<img src='/admin/images/spinner.gif'>";
oPopup.show((Math.abs(Math.round((document.body.clientWidth-50) / 2))), Math.abs(Math.round((document.body.clientHeight-50)/ 2)), 100, 100, document.body);
});
DWREngine.setPostHook(function() { //这是加载完成的代码
htmlStr = "<img src=\"/loadok.gif\">";//这里是改变传入对象的值,是dwr加载时完成的提示,如load ok,我这里是用的是图片
obj.innerHTML = htmlStr;
oPopup.hide();
});
}
以上代码,是我在项目中抽取出来的一部份。
小说明一下:
var oPopup = window.createPopup();这个函数用于创建浮动页面的loading载入提示,加载完成后将对象进行oPopup隐藏处理oPopup.hide();
如果不须要,changeStatus这个函数完全可以这样写
function changeStatus(obj){
DWREngine.setPreHook(function() { //这是正在加载的代码
obj.innerHTML = "<img src=\"/loading.gif\">";//这里是改变传入对象的值,是dwr正在加载时的提示,如loading,我这里是用的是图片
});
DWREngine.setPostHook(function() { //这是加载完成的代码
obj.innerHTML = "<img src=\"/loadok.gif\">";//这里是改变传入对象的值,是dwr加载时完成的提示,如load ok,我这里是用的是图片
});
}
至此我们完美的完成了dwr加载时的提示问题,这样也使用户体更强,更具人性化.
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229631
发表时间: 2008年07月17日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
linux 与adsl 共享上网 真实机系统为windows xp,使用adsl拨号上网,虚拟机安装linux,有一块网卡,使用桥接模式。
实现环境:
1、在windows下,启用ICS。
选择adsl上网拨号后的连接,属性->高级->Internet连接共享->勾选“允许其他网络用户通过此计算机的internet连接共享”,家庭网络连接选“本地连接”。
2、在linux下,配置静态IP。
点主菜单->系统设置->网络,弹出“网络配置”,双击eth0,勾选“静态设置的ip地址”,
地址:192.168.0.2 (除192.168.0.1和255外,随便填)
子网掩码: 255.255.255.0
网关:192.168.0.1
确定
DNS项,主DNS填:192.168.0.1
都填完,记得保存。
3、重起服务
service network restart 或者重启linux。
4、现在ping 一下 google.cn 看看,如果通就ok了
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229629
发表时间: 2008年07月21日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
最近由于公司要求开发一个小小的插件,用来改变文件名字 简单的说,就是读取一个csv文件,里面只有两列 如:test.csv "OldName","NewName" "test1.eps","1.eps" "test2.eps","2.eps" "test3.tif","3.eps" 然后用户通过界面选择csv文件,选择源文件目录,选择目的文件目录,选好再按一个键对原来文件按新的文件名输出。
我开始拿到蒙了,因为自己没有搞过呀,经过查资料,自己研究,搞定。 下面开始我们的实战吧。
工欲善其事,必须利其器
首选搭建好开发环境。
1.安装MyEclipse 6.0 2.安装打包工具 net.sf.fjep.fatjar_0.0.27.zip 我是解压到 MyEclipse 6.0\fjep\eclipse\plugins 在MyEclipse 6.0\eclipse\links 建fjep.link 里,添加 path=C:\\Program Files\\MyEclipse 6.0\\fjep 3.重启myeclipse 我们的开发环境就搞定啦 重启后Window->Preferences可以看到 Fat Jar Preferences 说明你安装成功 下面开始我们的项目 1.新建Plug-in Project名字自己取Demo 建好后可以看到结构Demo --src --bin 2.新建log4j.properties log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%c{1} - %m%n log4j.logger.java.sql.PreparedStatement=DEBUG 3.新建cvs.properties csv.field.key=OldName, NewName 4.编辑NewRenamer.java
import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement;
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; public class Renamer { private static final String CVS_PROPERTIES = "cvs.properties"; Log log = LogFactory.getLog(Renamer.class); private Shell sShell = null; private Button btnSourceDir = null; private CLabel labSourceDir = null; private Button btnDestinationDir = null; private CLabel labDestinationDir = null; private Button btnCSVFile = null; private CLabel labCSVFile = null; String openDirPathFlag = "openDirPath"; // @jve:decl-index=0: private Table tabPreview = null; private Button processIt = null; //private Button restoreIt = null; //private Button flashRestore = null; int runTime = 1000 * 10; private void createSShell() { GridData gridData = new GridData(); gridData.horizontalSpan = 7; gridData.verticalAlignment = GridData.FILL; gridData.verticalSpan = 3; gridData.grabExcessVerticalSpace = true; gridData.horizontalAlignment = GridData.FILL; GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 8; sShell = new Shell(); sShell.setText("Shell"); sShell.setLayout(gridLayout); sShell.setSize(new Point(800, 500)); btnCSVFile = new Button(sShell, SWT.NONE); btnCSVFile.setText("CSV"); btnCSVFile.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { //清掉以前的显示结果 tabPreview.removeAll(); //path part String openDirPath = (String)btnCSVFile.getData(openDirPathFlag); FileDialog dd = new FileDialog(sShell, SWT.NONE);//用来显示一个目录对话 dd.setFilterPath(openDirPath); dd.setText("CVS file"); String cvsPath = dd.open(); cvsPath = cvsPath == null ? "" : cvsPath; btnCSVFile.setData(openDirPathFlag,cvsPath); labCSVFile.setText(cvsPath); if(StringUtils.isEmpty(cvsPath)) return; //得到csv文件 String csvDir=StringUtils.substringBeforeLast(cvsPath, "\\"); String csvFileName=StringUtils.substringAfterLast(cvsPath, "\\"); String csvFileNameNotSuffix=StringUtils.replace(csvFileName, ".csv", ""); log.debug(csvDir); log.debug(csvFileNameNotSuffix); try { Configuration config = new PropertiesConfiguration(CVS_PROPERTIES); String[] aryFields = config.getStringArray("csv.field.key"); // 加载驱动 Class.forName("org.relique.jdbc.csv.CsvDriver");
// 定位文件夹位置
Connection conn = DriverManager .getConnection("jdbc:relique:csv:"+csvDir);
Statement stmt = conn.createStatement();
// 注意 csvFileNameNotSuffix 就是cvs文件 ResultSet results = stmt .executeQuery("SELECT * FROM "+csvFileNameNotSuffix);
while (results.next()) { String showname = results.getString(aryFields[0]); String destName = results.getString(aryFields[1]); TableItem item = new TableItem(tabPreview, SWT.NONE); item.setText(0,showname); TabItemData itemData = new TabItemData(cvsPath,"",showname,"",destName); item.setData("itemData",itemData); item.setText(1,destName); } results.close(); stmt.close(); conn.close();
} catch (Exception e1) {
log.debug(e1); }
} }); labCSVFile = new CLabel(sShell, SWT.NONE); labCSVFile.setText("please choose CSV"); btnSourceDir = new Button(sShell, SWT.NONE); btnSourceDir.setText("source"); btnSourceDir .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { String csvFile = (String)btnCSVFile.getData(openDirPathFlag); if(StringUtils.isEmpty(csvFile)) return;//必须先有csv文件
//path part String openDirPath = (String)btnSourceDir.getData(openDirPathFlag); DirectoryDialog dd = new DirectoryDialog(sShell, SWT.NONE);//用来显示一个目录对话 dd.setFilterPath(openDirPath); dd.setText("Souce Dir"); String sourcePath = dd.open(); sourcePath = sourcePath == null ? "" : sourcePath; btnSourceDir.setData(openDirPathFlag,sourcePath); labSourceDir.setText(sourcePath); int tabLength = tabPreview.getItems().length; for(int i=0;i<tabLength;i++){ TableItem item = tabPreview.getItem(i); TabItemData itemData = (TabItemData)item.getData("itemData"); itemData.setSourceDir(sourcePath+"\\");//把源目录加进去 item.setData("itemData",itemData);
System.out.println(i+":" +tabPreview.getItems().length + "\n" + itemData); if(new File(itemData.getSourceFilePath()).exists()){ item.setBackground(new Color( sShell.getDisplay(), 0, 255, 128 )); } } } }); labSourceDir = new CLabel(sShell, SWT.NONE); labSourceDir.setText("please choose directory"); btnDestinationDir = new Button(sShell, SWT.NONE); btnDestinationDir.setText("destination"); btnDestinationDir.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { String openDirPath = (String)btnDestinationDir.getData(openDirPathFlag); DirectoryDialog dd = new DirectoryDialog(sShell, SWT.NONE); dd.setFilterPath(openDirPath); dd.setText("destination dir"); String path = dd.open(); btnDestinationDir.setData(openDirPathFlag,path); labDestinationDir.setText(path); } }); labDestinationDir = new CLabel(sShell, SWT.NONE); labDestinationDir.setText("please choose directory"); processIt = new Button(sShell, SWT.NONE); processIt.setText(" process it "); processIt.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { //得到目的路径 String descPath = (String)btnDestinationDir.getData(openDirPathFlag); if(StringUtils.isEmpty(descPath)) return; int tabLength = tabPreview.getItems().length; descPath += "\\"; for(int i=0;i<tabLength;i++){ TableItem item = tabPreview.getItem(i); TabItemData itemData = (TabItemData)item.getData("itemData"); itemData.setDestinationDir(descPath); System.out.println(i+":" +tabPreview.getItems().length + "\n" + itemData); if(new File(itemData.getSourceFilePath()).exists()){ try { FileUtils.copyFile(new File(itemData.getSourceFilePath()),new File(itemData.getDestinationFilePath())); item.setBackground(new Color( sShell.getDisplay(), 184, 109, 109 )); } catch (IOException e1) { System.out.println("e1:" + e1); } } } } });
tabPreview = new Table(sShell, SWT.NONE); tabPreview.setHeaderVisible(true); tabPreview.setLayoutData(gridData); tabPreview.setLinesVisible(true); TableColumn colSource = new TableColumn(tabPreview, SWT.NONE); colSource.setWidth(350); colSource.setText("source"); TableColumn colDestination = new TableColumn(tabPreview, SWT.NONE); colDestination.setWidth(350); colDestination.setText("destination"); } public static void main(String[] args) { Display display = Display.getDefault(); Renamer thisClass = new Renamer(); thisClass.createSShell(); thisClass.sShell.open();
while (!thisClass.sShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
5.编辑BaseObject.java
import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import java.io.Serializable;
public class BaseObject implements Serializable {
public static final Log log = LogFactory.getLog(BaseObject.class);
public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); }
public boolean equals(Object o) { return EqualsBuilder.reflectionEquals(this, o); }
public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); }
} 6.编辑TabItemData.java
public class TabItemData extends BaseObject{ String sourceDir = ""; String csvFile = ""; String fileInSourceDir = ""; String destinationDir = ""; String fileInDestinationDir = ""; public TabItemData(String csvFile,String sourceDir, String fileInSourceDir, String destinationDir, String fileInDestinationDir){ this.csvFile = csvFile; this.sourceDir = sourceDir; this.fileInSourceDir = fileInSourceDir; this.destinationDir = destinationDir; this.fileInDestinationDir = fileInDestinationDir; } public String getCsvFile() { return csvFile; }
public void setCsvFile(String csvFile) { this.csvFile = csvFile; }
public String getSourceFilePath(){ return this.getSourceDir() + this.getFileInSourceDir(); } public String getDestinationFilePath(){ return this.getDestinationDir() + this.getFileInDestinationDir(); } public String getDestinationDir() { return destinationDir; } public void setDestinationDir(String destinationDir) { this.destinationDir = destinationDir; } public String getFileInDestinationDir() { return fileInDestinationDir; } public void setFileInDestinationDir(String fileInDestinationDir) { this.fileInDestinationDir = fileInDestinationDir; } public String getFileInSourceDir() { return fileInSourceDir; } public void setFileInSourceDir(String fileInSourceDir) { this.fileInSourceDir = fileInSourceDir; } public String getSourceDir() { return sourceDir; } public void setSourceDir(String sourceDir) { this.sourceDir = sourceDir; }
}
7.上面我们把一切都编好了 然后选择项目->右健->Fat jar->选择main class [NewRenamer] ->finish就生成夹包了 8.编辑批处理文件 run.bat 里面加 start javaw -jar Demo_fat.jar
即可运行啦
说明: jdk 1.42 这是本项目必须的jar包 commons-collections-3.0.jar commons-configuration-1.5.jar commons-io-1.2.jar commons-lang-2.4.jar commons-logging.jar csvjdbc.jar log4j-1.2.9.jar
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229627
发表时间: 2008年07月23日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class DogShowRegistrationWindow {
/*
* 参考文章
* http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html
* http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui1/index.html
* http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui2/index.html
* http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui3/index.html
* http://www-128.ibm.com/developerworks/cn/opensource/os-swingswt/
* http://www.blogjava.net/fortune/archive/2006/03/09/34463.html
*/
Image dogImage;
Text dogNameText;
Combo dogBreedCombo;
Canvas dogPhoto;
List categories;
Text nameText;
Text phoneText;
public static void main(String[] args) {
Display display = new Display();
Shell shell = new DogShowRegistrationWindow().createShell(display);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public Shell createShell(final Display display) {
final Shell shell = new Shell(display);//通用窗口
FormLayout layout = new FormLayout();//布局管理器
layout.marginWidth = 5;
layout.marginHeight = 5;
shell.setLayout(layout);
shell.setText("Dog Show Entry");
//****************************定义布局所要用的资源开始****************************
//定义dog name标签
Label dogName = new Label(shell, SWT.NONE);//显示静态文本
dogName.setText("Dog's Name:");
//定义dog name的文本输入框
dogNameText = new Text(shell, SWT.SINGLE | SWT.BORDER);//文本输入
//定义dog greed标签
Label dogBreed = new Label(shell, SWT.NONE);
dogBreed.setText("Breed:");
//定义一个dog greed多选框
dogBreedCombo = new Combo(shell, SWT.NONE);
dogBreedCombo.setItems(new String[] { "Collie", "Pitbull", "Poodle","Scottie", "Black Lab" });//从一个下拉列表中选择
//定义photo标签
Label photo = new Label(shell, SWT.NONE);
photo.setText("Photo:");
//定义photo显示域
dogPhoto = new Canvas(shell, SWT.BORDER);//绘图区域;可能用于定制控件
//定义Photo Browse按钮
Button browse = new Button(shell, SWT.PUSH);
browse.setText("Browse...");
//定义Photo Delete按钮
Button delete = new Button(shell, SWT.PUSH);//简单按下具有文本的按钮
delete.setText("Delete");
//定义分类标签
Label cats = new Label(shell, SWT.NONE);
cats.setText("Categories");
//定义分类List
categories = new List(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);//从条目列表中进行选择
categories.setItems(new String[] { "Best of Breed", "Prettiest Female",
"Handsomest Male", "Best Dressed", "Fluffiest Ears",
"Most Colors", "Best Performer", "Loudest Bark",
"Best Behaved", "Prettiest Eyes", "Most Hair", "Longest Tail",
"Cutest Trick" });
//定义一个组
Group ownerInfo = new Group(shell, SWT.NONE);//其他控件的有边界和标题的通用容器
ownerInfo.setText("Owner Info");
FormLayout ownerLayout = new FormLayout();//布局管理器
ownerLayout.marginWidth = 5;
ownerLayout.marginHeight = 5;
ownerInfo.setLayout(ownerLayout);
//定义Enter按钮
Button enter = new Button(shell, SWT.PUSH);
enter.setText("Enter");
//****************************定义布局所要用的资源结束****************************
FormData data = new FormData();
data.top = new FormAttachment(dogNameText, 0, SWT.CENTER);
dogName.setLayoutData(data);//定义dogName与dogNameText的中心位置对齐
data = new FormData();
data.left = new FormAttachment(dogName, 5);
data.right = new FormAttachment(100, 0);
dogNameText.setLayoutData(data);//定义dogNameText左边距dogName5个点数的偏移 右边100%填充
data = new FormData();
data.top = new FormAttachment(dogBreedCombo, 0, SWT.CENTER);
dogBreed.setLayoutData(data);
//定义dogBreed项部距dogBreedCombo 0个点数的偏移 与dogBreedCombo标签的中心位置对齐
data = new FormData();
data.top = new FormAttachment(dogNameText, 5);
data.left = new FormAttachment(dogNameText, 0, SWT.LEFT);
data.right = new FormAttachment(categories, -5);
dogBreedCombo.setLayoutData(data);
//定义dogBreedCombo项部距dogNameText 5个点数的偏移
//定义dogBreedCombo左边与 dogNameText的左边对齐
//定义dogBreedCombo右边距 categories左边5个点数的偏移
data = new FormData(80, 80);
data.top = new FormAttachment(dogBreedCombo, 5);
data.left = new FormAttachment(dogNameText, 0, SWT.LEFT);
data.right = new FormAttachment(categories, -5);
data.bottom = new FormAttachment(ownerInfo, -5);
dogPhoto.setLayoutData(data);
//定义dogPhoto大小为80X80
//定义dogPhoto顶边与dogBreedCombo底边点数的偏移
//定义dogPhoto左边与dogNameText左边对齐
//定义dogPhoto右边距categories 5个点数的偏移
//定义dogPhoto底边距ownerInfo 5个点数的偏移
dogPhoto.addPaintListener(new PaintListener() {
public void paintControl(final PaintEvent event) {
if (dogImage != null) {
event.gc.drawImage(dogImage, 0, 0);
}
}
});
data = new FormData();
data.top = new FormAttachment(dogPhoto,0, SWT.TOP);
photo.setLayoutData(data);
//定义photo顶边与 dogPhoto的顶边对齐
data = new FormData();
data.top = new FormAttachment(photo, 5);
data.right = new FormAttachment(dogPhoto, -5);
browse.setLayoutData(data);
//定义photo顶边距 photo 5个点数的偏移
//定义photo右边距 dogPhoto 5个点数的偏移
browse.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
String fileName = new FileDialog(shell).open();//用来显示一个文件对话
if (fileName != null) {
dogImage = new Image(display, fileName);
}
}
});
data = new FormData();
data.top = new FormAttachment(browse, 5);
data.left = new FormAttachment(browse, 0, SWT.LEFT);
data.right = new FormAttachment(dogPhoto, -5);
delete.setLayoutData(data);
//定义delete顶边距 browse 5个点数的偏移
//定义delete左边与 browse 左边对齐
//定义delete右边距 dogPhoto 5个点数的偏移
delete.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
if (dogImage != null) {
dogImage.dispose();
dogImage = null;
dogPhoto.redraw();
}
}
});
data = new FormData(90, 140);
data.top = new FormAttachment(dogPhoto, 0, SWT.TOP);
data.right = new FormAttachment(100, 0);
data.bottom = new FormAttachment(enter, -5);
categories.setLayoutData(data);
//定义categories顶边与 dogPhoto的顶边对齐
//定义categories右边100% 填充
//定义categories底边距底边父组件 5个点数的偏移
data = new FormData();
data.bottom = new FormAttachment(categories, -5);
data.left = new FormAttachment(categories, 0, SWT.CENTER);
cats.setLayoutData(data);
//定义cats底边与 categories的底边 5个点数的偏移
//定义cats左边与 categories 的中心对齐
data = new FormData();
data.right = new FormAttachment(100, 0);
data.bottom = new FormAttachment(100, 0);
enter.setLayoutData(data);
enter.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
System.out.println("\nDog Name: " + dogNameText.getText());
System.out.println("Dog Breed: " + dogBreedCombo.getText());
System.out.println("Owner Name: " + nameText.getText());
System.out.println("Owner Phone: " + phoneText.getText());
System.out.println("Categories:");
String cats[] = categories.getSelection();
for (int i = 0; i < cats.length; i++) {
System.out.println("\t" + cats[i]);
}
}
});
data = new FormData();
data.bottom = new FormAttachment(enter, -5);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(categories, -5);
ownerInfo.setLayoutData(data);
Label name = new Label(ownerInfo, SWT.NULL);
name.setText("Name:");
Label phone = new Label(ownerInfo, SWT.PUSH);
phone.setText("Phone:");
nameText = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
phoneText = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
data = new FormData();
data.top = new FormAttachment(nameText, 0, SWT.CENTER);
name.setLayoutData(data);
data = new FormData();
data.top = new FormAttachment(phoneText, 0, SWT.CENTER);
phone.setLayoutData(data);
data = new FormData();
data.left = new FormAttachment(phone, 5);
data.right = new FormAttachment(100, 0);
nameText.setLayoutData(data);
data = new FormData();
data.left = new FormAttachment(nameText, 0, SWT.LEFT);
data.right = new FormAttachment(100, 0);
data.top = new FormAttachment(55, 0);
phoneText.setLayoutData(data);
shell.pack();
return shell;
}
}
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229625
发表时间: 2008年08月04日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
swt学习小结 Widget —— 基本的 SWT GUI 组件 Control —— 拥有操作系统的对等物的窗口小部件 Composite —— 包含其他控件的控件 Item —— 其他控件包含的窗口小部件(该控件可能不是复合控件),比如列表和表
标准的SWT布局类 FillLayout:在容器中以相同的大小单行或单列的排列组件 RowLayout:以单行或多行的方式使用几个选项(fill,wrap,spacing,justify,type)定制组件的排列方式 GridLayout:类似于swing的GridLayout的方式以格子的方式排列组件 FormLayout(SWT 2.0的新特性):通过定义组件四个边的“粘贴”位置来排列组件,被引用的相对的组件可以父组件,也可以是同一容器中的其它组件。
/* * 参考文章 * http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html * http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui1/index.html * http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui2/index.html * http://www.ibm.com/developerworks/cn/linux/opensource/os-ecgui3/index.html * http://www-128.ibm.com/developerworks/cn/opensource/os-swingswt/ * http://www.blogjava.net/fortune/archive/2006/03/09/34463.html */ 布局实施 1.首先定义窗口和它的空白边 Display.getDefault().dispose(); //移去平台核心启动画面 display = new Display(); shell = new Shell(display, SWT.TITLE); FormLayout layout = new FormLayout(); layout.marginHeight = 10; layout.marginWidth = 20; shell.setLayout(layout); shell.setText("用户登录");
2.创建窗口上的元素,其中下面的两个button由一个使用RowLayout的组件来包容。 name = new Label(shell, SWT.NONE); name.setText("用户名"); nameText = new Text(shell, SWT.SINGLE | SWT.BORDER); pass = new Label(shell, SWT.NONE); pass.setText("密码"); passText = new Text(shell, SWT.SINGLE | SWT.BORDER); passText.setEchoChar('*'); passText.setTabs(2); bottom = new Composite(shell, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.justify = true; //justify定义组件在容器中分散开,效果类似于swing的FlowLayout bottom.setLayout(rowLayout);
3.定义name标签的位置。它的顶边离父组件(窗口shell)的空白边距离是父组件clientArea(除空白边以外的空间)高度(height)的15%,偏移的点数(points)为0。 FormData data = new FormData(); data.top = new FormAttachment(15, 0); name.setLayoutData(data);
4.定义name文本输入的位置。它的顶边在name标签的中心位置(这不是正确的表达,但程序是这样解释,事实上它的中心位置与name标签在同一条水平线上),左边距name标签的右边有10个点。 data = new FormData(); data.top = new FormAttachment(name, 0, SWT.CENTER); data.left = new FormAttachment(name, 10, SWT.RIGHT); nameText.setLayoutData(data);
5.定义pass标签的位置。它的顶边距name标签的底边有10个点数的偏移。 data = new FormData(); data.top = new FormAttachment(name, 10, SWT.BOTTOM); pass.setLayoutData(data);
6.定义pass文本输入的位置。它的顶边在name标签的中心位置(同上),左边与name文本框的左边对齐。 data = new FormData(); data.top = new FormAttachment(pass, 0, SWT.CENTER); data.left = new FormAttachment(nameText, 0, SWT.LEFT); passText.setLayoutData(data);
7.定义bottom组件的位置。它的顶边距pass标签的底边15个点数,左边与pass标签的左边对齐,右边与pass文本输入的右边对齐。 data = new FormData(); data.top = new FormAttachment(pass, 15, SWT.BOTTOM); data.left = new FormAttachment(pass, 0, SWT.LEFT); data.right = new FormAttachment(passText, 0, SWT.RIGHT); bottom.setLayoutData(data);
完整的源码 import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text;
import cn.com.efly.clientframe.core.Hook;
/** * @author efly * @version 1.0.0,11/22/02 */ public final class LoginUI { private Display display; private Shell shell; private Composite bottom; private Label name; private Label pass; private Text nameText; private Text passText; private Button ok; private Button exit; private Rectangle clientArea; private RootHook rootHook;
public LoginUI(Hook hook) { rootHook = (RootHook) hook; }
/** * 显示登陆界面 */ public void show() { Display.getDefault().dispose(); display = new Display(); clientArea = display.getClientArea(); shell = new Shell(display, SWT.TITLE); FormLayout layout = new FormLayout(); layout.marginHeight = 10; layout.marginWidth = 20; shell.setLayout(layout); shell.setText("用户登录");
name = new Label(shell, SWT.NONE); name.setText("用户名"); nameText = new Text(shell, SWT.SINGLE | SWT.BORDER); pass = new Label(shell, SWT.NONE); pass.setText("密码"); passText = new Text(shell, SWT.SINGLE | SWT.BORDER); passText.setEchoChar('*'); passText.setTabs(2); bottom = new Composite(shell, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.justify = true; bottom.setLayout(rowLayout); ok = new Button(bottom, SWT.PUSH); ok.setText("确定"); ok.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { ok(); } }); exit = new Button(bottom, SWT.PUSH); exit.setText("取消"); exit.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { cancel(); } });
FormData data = new FormData(); data.top = new FormAttachment(15, 0); name.setLayoutData(data);
data = new FormData(); data.top = new FormAttachment(name, 0, SWT.CENTER); data.left = new FormAttachment(name, 10, SWT.RIGHT); nameText.setLayoutData(data);
data = new FormData(); data.top = new FormAttachment(name, 10, SWT.BOTTOM); pass.setLayoutData(data);
data = new FormData(); data.top = new FormAttachment(pass, 0, SWT.CENTER); data.left = new FormAttachment(nameText, 0, SWT.LEFT); passText.setLayoutData(data);
data = new FormData(); data.top = new FormAttachment(pass, 15, SWT.BOTTOM); data.left = new FormAttachment(pass, 0, SWT.LEFT); data.right = new FormAttachment(passText, 0, SWT.RIGHT); bottom.setLayoutData(data);
shell.pack(); Rectangle shellBounds = shell.getBounds(); shell.setLocation( (clientArea.width - shellBounds.width) / 2, (clientArea.height - shellBounds.height) / 2);
shell.open();
while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } }
private void dispose() { display.dispose();
}
private void cancel() { dispose(); }
private void ok() { verify(); }
private void verify() { rootHook.runPlatform(); }
public static void main(String[]){ new LoginUI(null).show(); } }
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229622
发表时间: 2008年08月08日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
webwork处理编码webwork.properties 设置你的缺省 locale和编码方案 webwork.locale=en_US webwork.i18n.encoding=UTF-8 如果使用freemarker 还要设置freemarker.properties locale=en_US default_encoding=UTF-8 网页上设置编码 1、JSP文件用支持UTF-8的文字编辑器编辑,如EditPlus、UltraEdit,并把原来ascii转换成utf-8(菜单里有)。 2、JSP文件头改成: <%@ page contentType="text/html; charset=UTF-8" language="java" import="java.sql.*"%> 3、html文件 <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 数据库 1、mysql配置文件:修改mysql在windows\my.ini里default-character-set=utf-8 2、mysql里数据库和表也都设为utf8_unicode_ci 3、数据库连结:jdbc:mysql://localhost/mydb?useUnicode=true&characterEncoding=utf-8 属性文件 native2ascii -encoding UTF8 ApplicationResources_xx.properties ApplicationResources_zh.properties 过滤器 EncodingFilter.java public class EncodingFilter implements Filter { public void init(FilterConfig cong) { // do nothing }
public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain) { try{ //编码 srequest.setCharacterEncoding("UTF-8"); //继续请求 chain.doFilter(srequest, sresponse); }catch(Exception e){ e.printStackTrace(); } }
public void destroy() { //do nothing } } web.xml <filter> <filter-name>encodingfilter</filter-name> <filter-class>fr.simatai.util.application.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encodingfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 数据库字符编码转化(己存在的表) ALTER TABLE test CONVERT TO CHARACTER SET UTF8
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229619
发表时间: 2008年08月08日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
dwr开发总结 dwr+spring 参考资料 http://wiki.javascud.org/display/dwrcn/Spring+Integration http://wiki.javascud.org/display/dwrcn/Getting+Started 测试http://{your app}//dwr/ 第一步 web.xml <!--***********************dwr setting***********************--> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet>
<servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <!--*********************** spring setting ***********************--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/applicationContext.xml </param-value> </context-param> 第二步 dwr.xml <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr> <allow> <create creator="new" javascript="JDate"> <param name="class" value="java.util.Date"/> </create> <create creator="new" javascript="TestBean"> <param name="class" value="com.photo.test.TestBean"/> </create> <create creator="spring" javascript="userAction"> 这里交给spring进行创建 <param name="beanName" value="userAction"/> </create> <convert converter="bean" match="com.photo.dao.domain.User"/>返回类型需要反换的bean </allow> </dwr> 第三步 applicationContext.xml <beans> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close" singleton="true"> .... </bean> <bean id="userService" class="com.photo.service.UserService"> ... </bean> <bean id="userAction" class="com.photo.action.UserAction"> 这里是spring创建bean的定义 <property name="userService" ref="userService"/> 将业务层注入 </bean>
第四步 类、网页 User.java 返回的实体 public class User { Integer id; String username; String password;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; } } UserAction.java dwr框架调用 public class UserAction { private UserService userService; //spring依赖注入,实现与持久层通信 public void setUserService(UserService userService) { this.userService = userService; } public Map getUserList(String id){ Map map=new HashMap(); map.put("userList",userService.queryUser(new User())) ;//查询实体bean User map.put("id",id);//用于显示的div id return map ; } } 测试页面testajax.html <html> <head> <META http-equiv=Content-Type content="text/html; charset=UTF-8"> <title>First Example</title> <script type='text/javascript' src='/dwr/interface/userAction.js'></script> <script type='text/javascript' src='/dwr/engine.js'></script> <script type='text/javascript' src='/dwr/util.js'></script> <script type="text/javascript"> var showUser = function(data) { var id = data["id"];//取出页面显示的id var userList = data["userList"];//取出页面显示的Userlist if ($(id).style.display == "none") { $(id).style.display = "block"; var htmlStr = ""; //alert(id); for (var property in userList) { var user = userList[property]; htmlStr += user.id + " " + user.username + " " + user.password + "<br>"; } $(id).innerHTML = htmlStr; return; } $(id).style.display = "none"; } </script> </head> <body> 这是触发函数 <a style="cursor:hand" id="" onclick="userAction.getUserList('div_show',showUser);">show Users</a> <br> 这块区域用于显示 <div id="div_show" style="display:none"></div> </body> </html>
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
作者: beauty9235
链接: http://beauty9235.javaeye.com/blog/229617
发表时间: 2008年08月08日
声明:本文系JavaEye网站发布的原创博客文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
spring 任务调度总结 参考资料 http://www.ibm.com/developerworks/cn/java/j-quartz/ http://www.opensymphony.com/quartz/download.action
Java的Timer类和OpenSymphony的Quartz调度器是两个流行的调度API。Spring为这两个调度器提供了一个抽象层,可以更容易的使用他们
spring+timer
1 .使用java Timer调度任务 第一步 web.xml <!--*********************** spring setting ***********************--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/applicationContextTimeTask.xml </param-value> </context-param> 第二步 配置applicationContextTimeTask.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- ****************使用java Timer调度任务********************* 使用java Timer调度第一步是从java.util.TimerTask派生一个任务 声明本身只是将EmailReportTask放到应用上下文, 并在testBean属性装配TestBean 在调度之前不会做任何事。 --> <bean id="testBean" class="com.photo.test.TestBean"/> <bean id="reportTimerTask" class="com.photo.task.EmailReportTask"> <property name="testBean"> <ref bean="testBean"/> </property> </bean> <!-- Spring的ScheduledTimerTimerTask定义了一个定时器任务的运行周期。应该如下装配一个ScheduledTimerTask timerTask告诉ScheduledTimerTask运行哪个TimerTask, 这里该装配属性指向reportTimerTask的一个引用。 属性period告诉ScheduledTimerTask以怎样的频率调用TimerTask的run()方法。 这个属性以毫秒作为单位, 86400000指定该任务每24小时运行一次 10X1000 属性scheduledTimerTasks 要求一个需要启动的定时器任务列表。 ScheduledTimerTask有一个delay属性, 允许你指定当任务第一次运行之前应该等多久。 如,EmailReportTask的第一次运行延迟5毫秒 -->
<bean id="scheduledReportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <property name="timerTask"> <ref bean="reportTimerTask"/> </property> <property name="period"> <value>10000</value> </property> <property name="delay"> <value>5000</value> </property> </bean> <!--Spring 的TimerFactoryBean负责启动定时任务。按以下方式在Spring配置文件里声明它--> <bean class="org.springframework.scheduling.timer.TimerFactoryBean"> <property name="scheduledTimerTasks"> <list> <ref bean="scheduledReportTask"/> </list> </property> </bean> </beans> 第三步 相关类的编写 EmailReportTask.java public class EmailReportTask extends TimerTask {//必需继承TimerTask Log log= LogFactory.getLog(EmailReportTask.class); public EmailReportTask() { }
public void run() {//这个函数是调度任务执行的入口 log.debug("task begin :"+testBean.greeting); }
private TestBean testBean;//这里实现spring的依赖注入
public void setTestBean(TestBean testBean) { this.testBean = testBean; } } testBean.java public class TestBean { public String greeting="hello,world"; } spring+Quartz Quartz 作业调度框架所提供的 API 在两方面都表现极佳:既全面强大,又易于使用。Quartz 可以用于简单的作业触发,也可以用于复杂的 JDBC 持久的作业存储和执行。 第一步 同上 第二步 配置applicationContextTimeTask.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="reportJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>com.photo.task.EmailReportTask2</value> </property> <property name="jobDataAsMap"> <map> <entry key="testBean"> <ref bean="testBean"/> </entry> </map> </property> </bean> <!--用它来指定一个工作应以怎样的频率运行,及第一次运行工作前应等多久--> <bean id="simpleReportTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail"> <ref bean="reportJob"/> </property> <property name="startDelay"> <value>3600000</value> </property> <property name="repeatInterval"> <value>86400000</value> </property> </bean> <!-- CronTriggerBean允许更精确的控制任务的运行时间。如果要在每天的6:00运行任务可以按照以下方式声明一个CronTriggerBean 0 0 6 * * ? jobDetail属性告诉触发器调度哪一个工作,属性cronExpression告诉触发器何时触发。一个cron表达式至少有6个由空格分隔的时间元素(最多7个)从左到右元素定义如下 1。秒(0-59) 2。分(0-59) 3。小时(0-23) 4。月份中的日期(1-31) 5。月份(1-12 或 JAN-DEC) 6。星期(1-7 或 SUN-SAT) 7。年份(1970-2099) 每一个元素都可以显示规定的一个值,一个区间(9-14),一个列表(9,12,14)或一个通配符(*)月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号(?)来表明不想设置那个字段 对于cronReportTrigger我们设置的cronExpression为 0 0 6 * * ?可以读作任意月份任何日期的6时0分0秒执行触发器 --> <bean id="cronReportTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="reportJob"/> </property> <property name="cronExpression"> <value>0/5 * * * * ?</value> </property> </bean> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronReportTrigger"/> </list> </property> </bean> </beans> 第三步 相关类的编写 EmailReportTask2.java public class EmailReportTask2 extends QuartzJobBean { Log log = LogFactory.getLog(EmailReportTask.class);
public EmailReportTask2() { } //这个函数是调度任务执行的入口 protected void executeInternal(JobExecutionContext jobExecutionContext) throws org.quartz.JobExecutionException {
log.debug("task 2 begin :" + testBean.greeting); }
private TestBean testBean;//这里实现spring的依赖注入
public void setTestBean(TestBean testBean) { this.testBean = testBean; } } TestBean.java 同上
本文的讨论也很精彩,浏览讨论>>
JavaEye推荐
引用地址:http://blog.csdn.net/joohnnie/archive/2004/09/15/105911.aspx
最近看了一本关于Hibernate开发的书.自己尝试了一下.
1.首先准备环境,以下Hibernate及其插件的下载地址
http://prdownloads.sourceforge.net/hibernate/?sort_by=date&sort=desc
2.Hibernate基础代码包括
-
POJO
POJO在Hibernate里应该理解成数据库表所对应的Domain Object.POJO就是“Plain Ordinary Java Object“ 无格式的普通Java对象.可以理解为不包含逻辑代码的值对象(Value Object)
public class TUser implements Serializable { private String name;
public User(String name) { this.name = name; }
/** default constructor */ public User() { }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; } }
|
-
Hibernate映射文件
Hibernate 从本质上来讲是一种“对象-关系型数据映射”(Object Relational Mapping 简称ORM)。前面的POJO在这里体现的就是ORM中Object层的语义, 而映射(Mapping)文件则是将对象(Object)与关系型数据(Relational)相关联的纽带,在Hibernate中,映射文件通常以“.hbm.xml”作为后缀。
3.由数据库来产生基础代码 Hibernate官方提供的MiddleGen for Hibernate 和Hibernate_Extension工具包,我 以很方便的根据现有数据库,导出数据库表结构,生成ORM和POJO。下面就来做个示例.
4.接压缩MiddleGen-Hibernate到 C:workMiddleGen.
5.接压缩Hibernate 到 C:workHibernate.
6.接压缩Extentions到 c:workExtentions
7.进入MiddleGen目录的configdatabase子目录.我们这里用的是Sqlserver2000,所以选择mssql.xml
打开 mssql.xml
<property name="database.script.file" value=""/> <property name="database.driver.file" value="${lib.dir}/Sprinta2000.jar"/> <property name="database.driver" value="com.inet.tds.TdsDriver"/> <property name="database.url" value="jdbc:inetdae7:localhost?database=airline"/> <property name="database.userid" value="sa"/> <property name="database.password" value="sa"/> <property name="database.schema" value=""/> <property name="database.catalog" value=""/>
<property name="jboss.datasource.mapping" value="MS SQLSERVER"/>
这里修改一下
我们把下载好的jdbc for sqlserver2000安装了后,把安装目录的lib目录下面的3个jar文件放到Middlegen的lib目录里面.
<property name="database.driver.file" value="${lib.dir}/mssqlserver.jar"/> //驱动jar文件 <property name="database.driver" value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/>//用winrar打开上面的jar文件就可以看到SQLServerDriver.class在jar文件中的路径了 <property name="database.url" value="jdbc:microsoft:sqlserver://localhost:1433;database=Northwind"/>//数据库的路径.前面的“jdbc.microsoft.sqlserver“ <property name="database.userid" value="sa"/>//用户名 <property name="database.password" value=""/>//密码 <property name="database.schema" value="dbo"/>//一定要写,很重要 <property name="database.catalog" value="Northwind"/>//一定要写很重要
8.配置build.xml文件(下面只是个人做一些测试,可以根据自己的需要来进行修改)
-
查找关键字 ”!ENTITY”,得到:
<!DOCTYPE project [ <!ENTITY database SYSTEM "file:./config/database/hsqldb.xml"> ]>
因为默认MiddleGen是采用hsql.xml,所以修改成我们的mssql.xml
<!DOCTYPE project [ <!ENTITY database SYSTEM "file:./config/database/hsqldb.xml"> ]>
<property name="name" value="airline"/>
修改成
<property name="name" value="sample"/>
-
修改输出目录
查找“name="build.gen-src.dir"“ <property name="build.gen-src.dir" value="${build.dir}/gen-src"/>
修改成 <property name="build.gen-src.dir" value="c:sample"/>
-
修改Package 名称
查找“<hibernate“
<hibernate destination="${build.gen-src.dir}" package="${name}.hibernate" genXDocletTags="false" genIntergratedCompositeKeys="false" javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper" />
把pachage属性修改为
<hibernate destination="${build.gen-src.dir}" package="org.hibernate.sample" genXDocletTags="true" genIntergratedCompositeKeys="false" javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper" />
这里的genXDocletTags是设置在生成代码的时候是否生成XDoclettags,这个很重要,我们设置成true.
9.配置ant的路径,解压缩下载的ant后,比如c:ant
我们右击我的电脑->熟悉->高级->编辑path的熟悉
在后面加入c:antin
10.点击开始-->运行-->cmd
cd到我们的MiddleGen目录 ,运行ant
如果提示连接数据库失败的话那就是mssql.xml没有配置好
如果显示连接数据库成功,没有找到table的话就是schemas和catalogs没有配置对了.
11.如果没有出错的话会启动一个界面,然后点击最上面的generae就可以生成POJO文件了.
|