javax.servlet.UnavailableException

今天,我改了几个类文件上传到虚拟空间,应用自动重启不能成功。在log中报告:


2006-12-07 21:25:37,578 - Initializing application data source dataSource

org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (User xyz has already more than 'max_user_connections' active connections)

at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:855)

at org.apache.commons.dbcp.BasicDataSource.setLogWriter(BasicDataSource.java:598)

at org.apache.struts.action.ActionServlet.initModuleDataSources(ActionServlet.java:808)

at org.apache.struts.action.ActionServlet.init(ActionServlet.java:335)

at javax.servlet.GenericServlet.init(GenericServlet.java:82)

at com.caucho.server.http.Application.createServlet(Application.java:3114)

at com.caucho.server.http.Application.loadServlet(Application.java:3065)

at com.caucho.server.http.Application.initServlets(Application.java:1923)

at com.caucho.server.http.Application.init(Application.java:1849)

at com.caucho.server.http.VirtualHost.startApplication(VirtualHost.java:1207)

at com.caucho.server.http.VirtualHost.getInvocation(VirtualHost.java:1007)

at com.caucho.server.http.ServletServer.getInvocation(ServletServer.java:1249)

at com.caucho.server.http.RunnerRequest.handleRequest(RunnerRequest.java:343)

at com.caucho.server.http.RunnerRequest.handleConnection(RunnerRequest.java:274)

at com.caucho.server.TcpConnection.run(TcpConnection.java:139)

at java.lang.Thread.run(Thread.java:595)

Caused by: java.sql.SQLException: User xyz has already more than 'max_user_connections' active connections

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:771)

at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1229)

at com.mysql.jdbc.Connection.createNewIO(Connection.java:2558)

at com.mysql.jdbc.Connection.<init>(Connection.java:1485)

at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)

at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:37)

at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)

at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:877)

at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:851)

... 15 more

2006-12-07 21:25:37,593 - connect fail in CallHtml.callOnePage()!

2006-12-07 21:25:37,593 - excute manager.deleteExpiredRecords() 1 times.

于是,我连接mysql查看当前活动连接数(show porcesslist;)确实达到了空间的最大活动连接数。

然后,只要一进入*.do形式的链接均在页面上报告上面相似的错误。也不知道是我上传的类文件是否触犯了Struts框架哪根神经?

上网用出现错误的关键字查了一下,其中有一篇http://mail-archives.apache.org/mod_mbox/struts-dev/200312.mbox/%3C20031204011632.14053.qmail@nagoya.betaversion.org%3E 上面的话:“Struts missing commons-dbcp and commons-pooling jar files.”启发了我。于是,我把lib中的那个:commons-pool-1.3.jar移走了。然后,我再输入*.do的链接,错误信息变了,为:


2006-12-07 22:11:07,765 - Unable to initialize Struts ActionServlet due to an unexpected exception or error thrown, so marking the servlet as unavailable.  Most likely, this is due to an incorrect or missing library dependency.

java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool

at java.lang.Class.getDeclaredConstructors0(Native Method)

at java.lang.Class.privateGetDeclaredConstructors(Class.java:2328)

at java.lang.Class.getConstructor0(Class.java:2640)

at java.lang.Class.newInstance0(Class.java:321)

at java.lang.Class.newInstance(Class.java:303)

at org.apache.struts.util.RequestUtils.applicationInstance(RequestUtils.java:143)

at org.apache.struts.action.ActionServlet.initModuleDataSources(ActionServlet.java:805)

at org.apache.struts.action.ActionServlet.init(ActionServlet.java:335)

at javax.servlet.GenericServlet.init(GenericServlet.java:82)

at com.caucho.server.http.Application.createServlet(Application.java:3114)

at com.caucho.server.http.Application.loadServlet(Application.java:3065)

at com.caucho.server.http.Application.initServlets(Application.java:1923)

at com.caucho.server.http.Application.init(Application.java:1849)

at com.caucho.server.http.VirtualHost.startApplication(VirtualHost.java:1207)

at com.caucho.server.http.VirtualHost.cron(VirtualHost.java:1359)

at com.caucho.server.http.ServletServer.cron(ServletServer.java:1940)

at com.caucho.server.http.ServletServer.handleCron(ServletServer.java:1774)

at com.caucho.util.Cron$CronThread.evaluateCron(Cron.java:199)

at com.caucho.util.Cron$CronThread.run(Cron.java:163)

2006-12-07 22:11:07,812 - connect fail in CallHtml.callOnePage()!

2006-12-07 22:11:07,812 - excute manager.deleteExpiredRecords() 1 times.

看来,应用已经有反应了(先前是没有任何反应,改变类文件也没反应,log信息一点不变。我又不能手动重启位于虚拟主机上应用,因为他们还暂时不提供这个功能),于是,我再把那个commons-pool-1.3.jar加进去。然后,系统成功自动重启,log信息如下:


2006-12-07 22:12:16,187 - Enter updateCache!

2006-12-07 22:12:21,609 - connect success in CallHtml.callOnePage()!

2006-12-07 22:12:21,609 - excute manager.deleteExpiredRecords() 1 times.

我也不知道是什么原因,就这样糊里糊涂的出问题,又糊里糊涂的解决了问题:)

也许,我中了seo的毒了?

从理论上讲,www.javaeye.com的静态文件列表对搜索引擎来说有内容复制之嫌疑。

如:这篇帖子:confluence不支持群集,是因为hibernate吗?

在静态文件列表中是:http://www.javaeye.com/t/20169.html

而在动态文件列表中是:http://www.javaeye.com/topic/20169

也就是说,相同的内容在他们页面有两个版本,一个动态的,一个静态的。

我不知道这对它们在搜索引擎中的收录有什么影响?

也许,我现在考虑搜索引擎考虑得太多了。

像这两天又想在虚拟主机提供商端实现彻底的301重定向,但是到现在为止也还没有成功。

做网站,或者更坦白的说,学习知识的我不应该在为迁就搜索引擎而折磨自己了。

还有,我发现一个著名的linux个人站linux.vbird.org,他有两个域名:http://linux.vbird.orghttp://www.vbird.org,进入都是同样的返回200 ok状态码;还有他的文章如: DNS 伺服器設定 两个域名都返回的是200码

http://www.vbird.org/linux_server/0350dns.php

http://linux.vbird.org/linux_server/0350dns.php

也就是说,也有内容复制之嫌。

但是以“DNS 伺服器設定”为关键字检索site:linux.vbird.org有结果,而site:www.vbird.org却没有这篇文章的影子,只有这篇文章的老版本:http://www.vbird.org/linux_server/0350dns/0350dns.php存在,而且,这篇老文章被标记成了补充材料。

另外,另一篇文章(Enterprise Linux 实战讲座前言DNS 反解( Reverse Lookup )原理)的pdf文件:

http://linux.vbird.org/somepaper/20050630-dns-1.pdf分在了linux.vbird.org,

而同样文章的第二部分却分在了:www.vbird.org/somepaper/20050630-dns-2.pdf

但是他还不是照样很红火?

我想,是google根据判断把本来是一个站的内容分在了两个域名下。

说明这还是有问题的,我上vbird.org问一下站长vbird的想法如何?

也许,正如:SEO每日一帖的zac说的那样,我中了SEO的毒了?

如何分离个人信息,缓存动态页面(转帖)

下面是一个用于php中的静态缓存加入动态个人信息的方案,我觉得他的思路是可以借鉴的,就转帖在这里了。

正文

****************************************************************************

转自:(http://nio.infor96.com/archives/283

如何分离个人信息,缓存动态页面

肖理达 (KrazyNio AT hotmail.com), 2005.06.07, 转载请注明出处

一直想写一篇关于动态页面 cache 的文章,但每次?提笔?却又放弃,因为总是觉得准备得

还不够充分。今天埋头写下,只是希望对自己的工作做一些笔录。

1、问题起源

我们经常会在一个动态页面中加入很多个人信息,以 CMS 首页为例,用户登录之前显示登

录框,登录之后显示其用户名,并根据权限显示其可用模块的链接。由于每个用户登录之

后,显示出来的动态信息都是不一样的,所以这部分无法进行 cache,我们将这部分信息

定义为?个人信息?,它的特性是根据登录用户进行动态改变。

现在问题来了,就是一个 CMS 的首页,访问者的登录概率并不是百分百的,应该说有一大

部分人访问首页是没有登录的,这个时候的首页是一个公共的页面,没有任何个人信息,

或者说这时候首页的任何动态信息都是可以转换成静态的,也就是说这部分是可 cache 的

2、使用 JavaScript 分离个人信息

解决这个问题的方法有很多种,一种是将个人信息和其他信息进行分离,如在 CMS 首页中

加入一个外部的 JavaScript 文件,而这个文件的内容实际上是由 PHP 动态生成的。CMS

首页 index.php 代码片段:

<script language="JavaScript" src="/js/personal.php"></script>

?.

<script language=?JavaScript?>

document.write(sUser);

document.write(sLinks);

</script>

personal.php 代码片段:

<?php

session_start();

header(?Cache-Control: no-store, no-cache, must-revalidate?);

?>

sUser = ?<?php echo $_SESSION['USER']; ?>?;

sLinks = ?<?php echo addslashes($_SESSION['LINKS']); ?>?;

这种方法比较适合个人信息较少,易于集中显示的情况。通过 JavaScript 外挂代码实现

个人信息分离之后,personal.php 是永不 cache 的,这样也就可以放心地对 CMS 首页进

行 cache 了,具体的 cache 方法可采用 304 HTTP 头与 Cache_Lite 相结合的方式,这

在后边有详细代码示例。

3、选择性分离个人信息

一旦个人信息较多,很难对其进行分离的时候,上述方法实现起来就会比较麻烦了。接下

来介绍一种比较放宽的 cache 方式,就是只对用户未登录的 CMS 首页进行 cache,一旦

发现用户处于登录状态,则跳过 cache 部分,直接运行相关代码,我把这种方法称为?

选择性 cache
?。这种方法中,我们牺牲了一部分可 cache 的情况,但很大程度上提

高了个人信息的可扩充性,也就是说个人信息的多少、显示的位置等等都不再受到限制,

这是值得的,毕竟修改服务端代码要比修改大量的 JavaScript 代码要来得方便,而且

JavaScript 的调试也会比较麻烦。

分析一下这种 cache 方式,概要流程图如下:

image

代码片段如下:

<?php

session_cache_limiter(?must-revalidate?);

session_start();

if (empty($_SESSION['USER'])) { //未登录时才使用 cache

    ?.    //输出 cache

} else {

    //  直接输出页面内容,此条件下与未使用 cache 时一样

    $data =& get_data();

    echo $data;

}   //end if

?>

这里需要说明的一点是,由于 PHP 在使用 SESSION 时,php.ini 中默认设置的

session.cache_limiter 为 nocache,所以需要修改 cache_limiter,设置成

must-revalidate,使得客户端再次浏览当前页时必须发送相关 HTTP 头信息到服务器进行

验证,然后才决定是否加载客户端本地 cache。不要把客户端本地 cache 与服务器端

cache 搞混,之后的代码片段中会充分利用客户端 cache 和服务器端 cache 机制达到缓

存的目的。关于 must-revalidate,请参考 HTTP 规格说明书 RFC 2612 的 14.9.4 章节

上边的代码并不完整,接下来是更加深入的探讨客户端 cache 机制了,利用客户端 cache

,可以有效地减轻服务器端负载。首先了解一下 HTTP 头:Last-Modified 与

If-Modified-Since。简单的说,Last-Modified 与If-Modified-Since 都是用于记录页面

最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头

,而 If-Modified-Since 则是由客户端往服务器发送的头,其工作原理图如下:

image

可以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将

先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进

行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的

内容,如果是最新的,则返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户

端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了

服务器的负担。想要详细查看 HTTP 头信息,可以在 Firefox 中安装 LiveHTTPHeaders

插件,安装完成之后按 Alt+L 就可以在 Sidebar 中看到了。

现在再来完善之前的 index.php 代码:

<?php

session_cache_limiter(?must-revalidate?);

session_start();

function &get_data()

{

    //此函数用于获取本页面的输出内容

    //?.

}   //end function

if (empty($_SESSION['USER'])) { //未登录时才使用 cache

    //====================================================

    //  1. 检查 HTTP 头是否符合 304 的条件

    //====================================================

    //get_last_modified() 函数需要另外单独实现,此函数用于获取服务器端 cache 文件的最后修改时间,可将时间戳保存在数据库中。

    $last_modified = get_last_modified();

    $headers = getallheaders();

    if (strtotime($headers['If-Modified-Since']) == $last_modified) {

        //  返回 304 并结束程序运行

        header('HTTP/1.1 304 Not Modified');

        exit;

    }   //end if

    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT');

    //====================================================

    //  2. 检查 cache 文件是否存在

    //====================================================

    require_once 'Cache/Lite.php';

    //  参数设置

    $options = array(

        'cacheDir' => './cache/',

        'lifeTime' => 86400, //最大 cache 一天时间

        'fileNameProtection'   => false //使用 CMS 自身提供的 id 作为名字

    );

    $cache = new Cache_Lite($options);  //创建 Cache_Lite 对象

    $id = md5($_SERVER['REQUEST_URI']); //生成对应于 cache 文件的 ID

    if ($data = $cache->get($id)) {   //存在 cache 文件,获取内容,直接输出

        echo $data;

    } else {

        $data =& get_data();

        echo $data;

        flush();

        $cache->save($data);    //保存 cache

    }   //end if

} else {

    $data =& get_data();

    echo $data;

}   //end if

?>

测试时可以使用 LivHTTPHeaders 插件,你将会看到第一次访问时是返回 200,第二次到

第N次访问时则返回了 304,而登录之后,则一直都返回 200,因为我们选择性 cache 之

后,对登录之后一律运行程序输出,而不使用 cache,如果之后需要对输出的个人信息进

行修改,只需要改函数 get_data() 即可,也避免了 JavaScript 的调试。

总结

除此之外,还有其它方法可以实现分离个人信息,缓存动态页面的目的。而且为了提高服

务器运行效率,还可以使用数据库 cache、Squid 反向代理等,如 ADOdb 的 cache。目前

用的比较多的 Drupal 应用的就是本文中提到的第二种方法。

参考资料

HTTP Caching & Cache-Busting for Content Publishers

Hypertext Transfer Protocol ? HTTP/1.1

PHP Anthology, Volume 2: Applications. Chapter 5: Caching

Caching Tutorial for Web Authors and Webmasters

Drupal 源代码

Comments RSS | Trackback URL

4 Comments on ?关于 Cache(4)?

By zeal. June 13th, 2005 at 3:25 pm

我们目前采用的是oracle cache server以及squid。对于不能cache的内容采取分目录存放

。在代码设计的时候就考虑可cache性。对于大量需要用户交互的内容,似乎cache的作用

不大。

By Nio. June 13th, 2005 at 5:02 pm

嗯,如果内容本身全都是个人信息的话或者必须登录才能浏览的页面,就用不到这种cache

方法了,需要看登录与不登录的概率比而定 🙂

By nc. July 17th, 2006 at 12:43 pm

感谢你文章的提示,非常不错.

By ahu. October 8th, 2006 at 5:10 pm

zeal的公司貌似有些money~

**************************************************************************

                                                           转载完毕

另一段静态页面计数代码:


<script language="javascript" src="/data/include/count.php?id=$id"></

script>

转摘自:(http://www.mephp.com/view.php?tid=1&id=44

301永久性重定向和302临时性重定向的研究(转帖)

转自:301永久性重定向和302临时性重定向的研究

301永久性重定向 和 302临时性重定向 的研究

作者:快速胡萝卜 日期:2006-08-09

字体大小: 小 中 大

先简要说一下

重定向就是网页自动转向

301永久性重定向

302临时性重定向

实施301后,新网址完全继承旧网址,旧网址的排名等完全清零。

实施302后,对旧网址没有影响,但新网址不会有排名。

详情见下文。

301 Redirect 永久重定向的实现

  在我们的网站建设中,时常会遇到需要网页重定向的情况:象网站调整,如改变网页目录结构,网页被移到一个新地址,再或者,网页扩展名改变,如因应用需要把.php改成.Html或.shtml,在这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户还会得到一个404页面错误信息,访问流量白白丧失;再如某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点,等等。

  常用的重定向方式有: 301 redirect, 302 redirect 与 meta fresh:

  301 redirect: 301代表永久性转移(Permanently Moved),301重定向是网页更改地址后对搜索引擎友好的最好方法,只要不是暂时搬移的情况,都建议使用301来做转址。

  302 redirect: 302代表暂时性转移(Temporarily Moved ),在前些年,不少Black Hat SEO曾广泛应用这项技术作弊,目前,各大主要搜索引擎均加强了打击力度,象Google前些年对Business.com以及近来对BMW德国网站的惩罚。即使网站客观上不是spam,也很容易被搜寻引擎容易误判为spam而遭到惩罚。

  meta fresh: 这在2000年前比较流行,不过现在已很少见。其具体是通过网页中的meta指令,在特定时间后重定向到新的网页,如果延迟的时间太短(约5秒之內),会被判断为spam。

    页面永久性移走(301重定向)是一种非常重要的“自动转向”技术。

  301重定向可促进搜索引擎优化效果

  从搜索引擎优化角度出发,301重定向是网址重定向最为可行的一种办法。当网站的域名发生变更后,搜索引擎只对新网址进行索引,同时又会把旧地址下原有的外部链接如数转移到新地址下,从而不会让网站的排名因为网址变更而收到丝毫影响。同样,在使用301永久性重定向命令让多个域名指向网站主域时,亦不会对网站的排名产生任何负面影响。

  302重定向可影响搜索引擎优化效果

  迄今为止,能够对302重定向具备优异处理能力的只有Google。也就是说,在网站使用302重定向命令将其它域名指向主域时,只有Google会把其它域名的链接成绩计入主域,而其它搜索引擎只会把链接成绩向多个域名分摊,从而削弱主站的链接总量。既然作为网站排名关键因素之一的外链数量受到了影响,网站排名降低也是很自然的事情了。

  综上所述,在众多重定向技术中,301永久性重定向是最为安全的一种途径,也是极为理想的一款解决方案。

  对于正确实施301重定向,本人整理了以下方法可供大家参考:

  1. Apache服务器实现301重定向

  a. 相比较来说,Apache实现起来要比IIS简单多了。在Apache中,有个很重要的文件.htaccess,通过对它的设置,可以实现很多强大的功能,301重定向只是其中之一。

  Redirect permanent / http://www.yourdomain.com ;将目录下内容重定向到http://www.yourdomain.com/

  redirect permanent /old.html http://www.yourdomain.com/new-url/ ;将网页old.html内容重定向到http://www.yourdomain.com/new-url/

  通过合理地配置重定向参数中的正则表达式,可以实现更复杂的匹配。有兴趣的朋友可参考Apache手册。

  b. 采用“mod_rewrite”技术。

  通过该技术进行的改变将在.htaccess文件中体现出来,形如:

  Options +FollowSymLinks

  RewriteEngine on

  RewriteCond %{HTTP_HOST} ^yourdomain\.com

  RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [R=301,L]

  2. 适用于使用Unix网络服务器的用户

  通过此指令通知搜索引擎的spider你的站点文件不在此地址下。这是较为常用的办法。

  形如:Redirect 301 / http://www.yourdomain.com/

  3.在服务器软件IIS服务器实现301重定向

  * 打开internet信息服务管理器,在欲重定向的网页或目录上按右键

  * 选中“重定向到URL”

  * 在对话框中输入目标页面的地址

  * 切记,记得选中“资源的永久重定向”

  * 当然,最后要点击“应用”

  适用于使用Window网络服务器的用户

  4.绑定/本地DNS

  如果具有对本地DNS记录进行编辑修改的权限,则只要添加一个记录就可以解决此问题。若无此权限,则可要求网站托管服务商对DNS服务器进行相应设置。

  DNS服务器的设置

  若要将aaa.domain.com指向www.domain.com,则只需在DNS服务中应增加一个别名记录,可写成:aaa IN CNAME www.domain.com。

  如需配置大量的虚拟域名,则可写成::* IN CNAME www.domain.com.

  这样就可将所有未设置的以domain.com结尾的记录全部重定向到www.domain.com上。

  5. 用ASP/PHP/.net实现301重定向:

  ASP:

  Response.Status="301 Moved Permanently"

  Response.AddHeader "Location","http://www.vc01.com/"

  Response.End

  PHP:

  header("HTTP/1.1 301 Moved Permanently");

  header("Location:http://www.vc01.com");

  exit();

  ASP .NET:

  <script runat=”server”>

  private void Page_Load(object sender, System.EventArgs e)

  {

    Response.Status = “301 Moved Permanently”;

    Response.AddHeader(”Location”,”http://www.vc01.com”);

  }

  </script>

  配置完成后,要认真检查一下是否正确。Internet有很多Server Header检查工具

以下为非关键参考:

*************************************************

网站重定向成祸端(从Business.com遭封看302重定向编译:Karen)

  Business.com是网上最大的商业搜索引擎和分类目录,以专业提供商业信息而享负盛名,包括近19万网页。若以“business”为关键词在 Google中进行搜索,该网站名列第一。不过在9月5日,Business.com遇到一件蹊跷之事:它的首页由PR8变成了PR0, 而且 Google搜索结果中找不到首页。好在被“蒸发”的只是首页,不过庆幸的是第二天首页又回到了Google的搜索结果,但PR仍旧为0。

  Business.com的问题出在它的重定向命令上。该网站让business.com跳转到www.business.com,这种重定向本该是永久性的。我们知道,301属于永久性重定向,而302则属于临时性重定向,只有当一个网站或网页在24到48小时之内临时移到其它位置的情况下才能使用该命令。但Business.com却错误地使用了“HTTP/1.1302 Object Moved”状态码。

  其实网站重定向极为普遍,譬如不满意原来的域名而申请了一个新域名;买下容易被人错拼的域名,防止客户因为拼错URL而找不到网站,等等。可是,很多人却会由于使用了错误的重定向状态码而遭“灭站之灾”,就象Business.com。尽管他们的重定向理由充分合理,然而若使用不当,则可能被Google误认为是利用多个域名指向同一网站,那么你的网站就会被封掉,罪名是“利用重复的内容来干扰Google搜索结果的网站排名”。Business.com就是最好的前车之鉴。只不过大多数使用错误重定向参数的网站没Business.com这么幸运,一个小小的重定向就可能使网站前功尽弃,只能从头来过:重新申请新域名,重新发布新网站,等等。记住:Google绝不会同情任何人即使无心犯下的错误。

*************************************************

网站服务器响应网页浏览请求的运作流程

  让我们先来了解一下用户/搜索引擎和网站一开始的交互流程。当用户或搜索引擎向一个网站服务器发出网页浏览请求时,该服务器将:

  1.通过域名服务器(DNS)将域名转换为网站的IP地址,然后返回给客户

  2.打开一个该IP套接口连接

  3.记下通过该套接口的一个HTTP数据流

  4.从WEB服务器接收一个响应请求的HTTP数据流。该数据流包含状态码,状态码的值由HTTP协议所决定。  这里所说的“HTTP数据流”信息也叫“头信息(Header)”。头信息中包括了日期,服务器类型,通常还会有一条“200 OK”信息。如果一切良好,那么网络服务器就会将 “200 OK”信息以及请求页面发送出去。如果网站在这时候已经建立了重定向,那么服务器就会在头信息中包含一个 “302 Moved Temporarily”或“301 Moved Permanent”之类的响应信息。搜索引擎会根据服务器头信息中的内容作出决定。

*************************************************

网站重定向的注意事项

  1.若准备将服务器上的文件移到其它地方时,须就以下信息正确地通知搜索引擎的爬行程序:

- 目标地址:这些文件被移向何方

- 移动属性:暂时移走还是永久性移走

  2.对拥有多个域名的网站,专家建议应把那些不想在搜索引擎上推广的域名用301跳转命令来永久性重定向。

*************************************************

资深SEO专家Dan Thies的看法和建议

  对于Business.com所遭遇的问题Dan Thies深有体会,因为他也有过类似的遭遇。他的网站上有一个会员跟踪脚本,其中一个会员的站点通过302命令映射到这个跟踪脚本,而这个跟踪脚本又是通过302映射到他的主页。当在Google中用“keyword research”进行搜索,他的主页排名在前十位,然而地址显示的却是那个会员的网址。结果使他哭笑不得:访问者通过Google搜索结果进入他的网站,而他却不得不为这些访问量给那个会员支付报酬! 后来他用robots.txt文件禁止Spiders跟踪访问他的会员跟踪脚本才算解决了问题。

  对于Business.com,Dan Thies认为:“目前Google在302重定向"的处理上还存在一定的问题,但并不表示Google不允许302重定向。Business.com并未遭封或遭到惩罚,它们只是返回了错误的响应。”

  Dan Thies建议:如果使用了跟踪URL/脚本,又必须让访问者重定向到某一着陆页,那么一定要在robots.txt文件中禁止Spiders 去访问第二个重定向。如果没有对跟踪URL/脚本进行重定向,而只是把另外一个URL上的内容给复制过来,那么应在robots.txt文件中禁止 Spiders去访问跟踪URL,以防因内容重复而遭搜索引擎惩罚。引自:21cnbj:从Business.com遭封看302重定向

*************************************************

302转向与网址劫持

  302转向或者302重定向(302 redirect)指的是当浏览器要求一个网页的时候,主机所返回的状态码。302状态码的意义是暂时转向到另外一个网址。

  另一个更常见的状态码是404错误(404 error),404错误或404状态码指的是网页不存在。

  另一个和302状态码相关的是301重定向(301 redirect),301重定向指的是本网页永久性的转移到另外一个位置。301和302的区别就在于301是永久性重定向,302是暂时重定向。

  302重定向和网址劫持(URL hijacking)有什么关系呢?这要从搜索引擎如何处理302转向说起。从定义来说,从网址A做一个302重定向到网址B时,主机服务器的隐含意思是网址A随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。

  实际上如果搜索引擎在遇到302转向时,百分之百的都抓取目标网址B的话,就不用担心网址URL劫持了。

  问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。为什么呢?比如说,有的时候A网址很短,但是它做了一个302重定向到B 网址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不用户友好。这时Google很有可能会仍然显示网址A。

  由于搜索引擎排名算法只是程序而不是人,在遇到302重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址URL劫持的可能性。也就是说,一个不道德的人在他自己的网址A做一个302重定向到你的网址B,出于某种原因,  Google搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B上的内容,这种情况就叫做网址URL劫持。你辛辛苦苦所写的内容就这样被别人偷走了。

  302重定向所造成的网址URL劫持现象,已经存在一段时间了。不过到目前为止,似乎也没有什么更好的解决方法。在正在进行的大爸爸数据中心转换中,302重定向问题也是要被解决的目标之一。从一些搜索结果来看,网址劫持现象有所改善,但是并没有完全解决。

  如果你遇到你自己的网站网址被劫持的时候,在你自己这一方面并没有什么办法,你只能向Google汇报。 作者: Zac原载: 搜索引擎优化每天一贴。

*************************************

以上文章为本人整理十多篇文章的成果,多处具体细节本人能力之内无法尝试,各部分原出处也已无法标明,见谅。有问题给我留言,大家一起研究研究。

JAVA学习日记页面静态化方案

JAVA学习日记页面静态化方案(借鉴了:http://www.agilejava.org/space/?233的 生成静态页面技术解决方案系列,见我的转帖:一个实现将JSP动态页面转为静态的方案(转帖)

1、首页和帖子页面静态化,帖子列表不静态化;

2、列表上的帖子用静态化链接;

3、隐私帖子页面不静态化;用户登录后用动态化链接,所以可以看到隐私帖子;

4、静态化时机:

  1)、发公开帖子;

  发公开目标:静态化目标和首页;

  公开日记:静态化日记、目标和首页;

  公开评论:评论日记:静态化日记、目标、首页;评论目标:静态化目标、首页;

  发私人日记:不作任何静态化;

  2)、修改公开帖子;

  修改目标(目标不能修改隐私属性):

  修改公开目标:目标、首页;

  修改私有目标:不作任何静态化;

  修改日记(日记可以修改隐私属性):

  修改公开日记,并且修改后仍是公开帖子:静态化日记、目标、首页;

  修改公开日记,但是修改后的日记是私有帖子:删除已经静态化日记,重新静态化目标、首页;

  修改私有日记,并且修改后仍是私有帖子:不作任何静态化;

  修改私有日记,但是修改后成了公开日记:静态化日记、目标、首页; 

  修改评论(评论的隐私属性与被它评论的目标或日记一致)

  修改公开目标的评论:静态化目标、首页;

  修改公开日记的评论:静态化日记、目标、首页;

  修改私有目标的评论:不作任何静态化;

  修改私有日记的评论:不作任何静态化;

  3)、删除帖子(私有帖子是不能被删除的);

  删除公开目标:删除目标会删除此目标下的评论和日记和日记的评论,所以要:删除已静态化的目标、删除已静态化的目标的日记、重新静态化首页;

  删除公开日记:删除日记会删除此日记下的评论,所以要:删除已经静态化的日记、重新静态化首页;

  删除公开评论:删除目标的公开评论:重新静态化目标、首页;删除日记的公开评论:重新静态化日记、日记的目标、首页;

 

  4)、静态化种类:

  手动静态化:由管理员执行手动全面静态化及维护工作:包括:对数据库和静态化文件储存目标扫描,重新静态化应该静态化的帖子;如果某个不应该静态化的私有目标或日记被静态化了则删除已静态化的文件,并且作下记录,分析原因;

  定时静态化:同手动静态化一样的功能,只不过由系统定时进行,比如每晚12:00点;

  帖子变动时的静态化:如上面的列表;

5、其它注意事项:

  1)、为了统一静态化页面和简要设计和增加系统灵活性,现对登录用户和游客用户(包括搜索引擎)的静态化作一区别:

  登录用户:全部用动态化,也就是说与现在动态化的系统没有区别;从各论坛和网站的统计情况来看:登录用户占全部用户的比例一般在5%左右,所以不会系统有什么大的影响;

  未登录用户(包括搜索引擎):首页和帖子全部用静态化,游客提交评论后通过Action的301跳转进入已静态化的最新页面,但是提交评论的表单已经静态化了,所以不能记住用户,这可以放在以后解决,同屏蔽垃圾留言的设计一起进行,可能会用<frame>内嵌表单来做。

  2)、类的设计:

  1个执行实际静态化的类:ToHtml.java;1个模拟游客访问,调用静态化的工具类:CallHtml.java;再增加一个静态化文件管理类:HtmlsManager.java,用于封装各种静态化时机的操作,包括:

  1>,提交帖子:doPostArt(),传入提交的帖子作为参数,即为doPostArt(ArticleInfo postedArt);

  2>,修改帖子:doEditArt(),传入修改前的帖子和修改后的帖子作为参数,即为:doEditArt(ArticleInfo oldArt, ArticleInfo newArt);

  3>,删除帖子:doDelArt(),传入被删除的帖子作为参数,即为:doDelArt(ArticleInfo);

  4>,检测是否相应静态化文件的方法:isExist(String phyFullName),传入系统路径的包含路径的全文件名作为参数;

  5>,删除一个相应静态化文件的方法:delete(String phyFullName),传入系统路径的包含路径的全文件名作为参数;

解密.htm.html.shtm.shtml的区别与联系(转帖)

转自:(http://tech.sina.com.cn/s/2006-04-24/1654915865.shtml)

今天,在做JAVA学习日记的首页静态化过程中想到一个问题,静态文件的后缀名用.htm还是用.html呢?它们有什么区别吗?是不是像图像文件后缀名:.jpg和.jpeg一样呢?

下面是一篇转帖正文。

*************************************************************************

                                           

                          解密.htm.html.shtm.shtml的区别与联系

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                 http://www.sina.com.cn 2006年04月24日 16:54 天极yesky

      作者:猴年马月

      每一个网页或者说是web页都有其固定的后缀名,不同的后缀名对应着不同的文件格式

    和不同的规则、协议、用法,最常见的web页的后缀名是.html和.htm,但这只是web页最基

    本的两种文件格式,今天我们来介绍一下web页的其它一些文件格式。

   

    [adfshow]

    [xfrd_01]                                          ●

      首先介绍一下html与htm

      关于HTML,HTML(HyperTextMark-upLanguage)即超文本标记语言,是WWW的描述语言。

    设计HTML语言的目的是为了能把存放在一台电脑中的文本或图形与另一台电脑中的文本或

    图形方便地联系在一起,形成有机的整体,人们不用考虑具体信息是在当前电脑上还是在

    网络的其它电脑上。我们只需使用鼠标在某一文档中点取一个图标,Internet就会马上转

    到与此图标相关的内容上去,而这些信息可能存放在网络的另一台电脑中。 HTML文本是由

    HTML命令组成的描述性文本,HTML命令可以说明文字、图形、动画、声音、表格、链接等

    。HTML的结构包括头部(Head)、主体(Body)两大部分,其中头部描述浏览器所需的信息,

    而主体则包含所要说明的具体内容。

      关于HTM,实际上HTM与HTML没有本质意义的区别,只是为了满足DOS仅能识别8+3的文

    件名而已,因为一些老的系统(win32)不能识别四位文件名,所以某些网页服务器要求

    index.html最后一个l不能省略。MSIE能自动识别和打开这些文件,但编写网页地址的时候

    必须是完全对应的,也就是说index.htm和index.html是两个不同的文件,对应着不同的地

    址。值得一提的是UNIX系统中对大小写敏感,不吻合的话就可能报没有文件或者找不到文

    件。

      其次介绍一下shtml和shtm

      关于shtml,shtml是一种基于SSI技术的文件,也就是Server Side Include--SSI 服

    务器端包含指令,一些Web Server如果有SSI功能的话就会对shtml文件特殊招待,服务器

    会先扫一次shtml文件看没有特殊的SSI指令存在,如果有的话就按Web Server设定规则解

    释SSI指令,解释完后跟一般html一起调去客户端。

      关于shtm,shtm与shtml的关系和htm与html的关系大致相似,这里就不多说了。

      html或htm与shtml或shtm的关系是什么

      html或者htm是一种静态的页面格式,也就是说不需要服务器解析其中的脚本,或者说

    里面没有服务器端执行的脚本,而shtml或者shtm由于它基于SSI技术,当有服务器端可执

    行脚本时被当作一种动态编程语言来看待,就如asp、jsp或者php一样。当shtml或者shtm

    中不包含服务器端可执行脚本时其作用和html或者htm是一样的。

********************************************************************************

                                      转帖完毕

JSP中读文件和写文件的例子(转帖)

转自:(http://www.programfan.com/article/showarticle.asp?id=2495


 <%@ page import="java.io.*" %>

<html>

  <head>

    <title>Lion互动网络==》JSP中读文件和写文件的例子</title>

  </head>

  <body>

   <%

//写文件

String str = "WWW.LIONSKY.NET";

String filename = request.getRealPath("lionsky.txt");

java.io.File f = new java.io.File(filename);

if(!f.exists())//如果文件不存,则建立

{

  f.createNewFile();

}

try

{

  PrintWriter pw = new PrintWriter(new FileOutputStream(filename));

  pw.println(str);//写内容

  pw.close();

}

catch(IOException e)

{

  out.println(e.getMessage());

}

//读文件

java.io.FileReader fr = new java.io.FileReader(f);

char[] buffer = new char[10];

int length; //读出的字符数(一个中文为一个字符)

//读文件内容

out.write(filename+"<br>");

while((length=fr.read(buffer))!=-1)

{

  //输出

  out.write(buffer,0,length);

}

fr.close();

%>

  </body>

</html>

本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( ProgramFan.Com )

在Struts Action对象中得到类似jsp页面application的ServletContext

今天需要把数据存在网站程序全局范围,需要在struts Aciton对象中得到 ServletContext对象,与jsp页面的application一样。在google中搜索到如下帖子。转帖于此:

How to get 'application' in Struts Action class? (转自:http://forum.java.sun.com/thread.jspa?threadID=609998&messageID=3346689

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

How to get 'application' in Struts Action class?  

Mar 23, 2005 7:45 PM

Click to email this message

 

Hello,

I have a question on how to get 'application' in Struts Action class.

In the jsp file, i have set an application attribute:

<%

applicaiton.setAttribute("userId", "testUser");

%>

But how to get this application attribute in Struts Action class?

So far I only know how to get session in Struts Action class by using:

(HttpServletRequest)request.getSession();

 

[Dukes Earned 1425] evnafets

Posts:7,577

Registered: 29/04/03

Re: How to get 'application' in Struts Action class?  

Mar 23, 2005 8:08 PM (reply 1 of 2)

Click to email this message

 

The "application" in a JSP page is the ServletContext object.

In a standard servlet you can use

ServletContext application = getServletConfig().getServletContext();

In a Struts Action class, just have to get hold of the servlet first

ServletContext application = getServlet().getServletConfig().getServletContext();

Cheers,

evnafets

 

[Dukes Earned 0] nonameisname

Posts:24

Registered: 8/13/03

Re: How to get 'application' in Struts Action class?  

Mar 23, 2005 8:33 PM (reply 2 of 2)

Click to email this message

 

Hi evnafets,

Thanks a lot for your help. It works.

By the way, i found that it is possible to get ServletContext in Struts in two ways:

ServletContext application = getServlet().getServletConfig().getServletContext();

or

ServletContext application = getServlet().getServletContext();

Both work fine. Any concern about the 2nd way? It does not getServletConfig() but instead it straight away getServletContext().

*********************************************************************************************************

                       转帖完毕

一个实现将JSP动态页面转为静态的方案(转帖)

最近早上的时候发现首页很难完整打开(其它页正常),搞不懂为什么白天网络繁忙的时候才有可能出现问题在早上出现。我看了网络当前用户只有我一个人,但是数据库当前又只有两个连接(加上我查询连接数据的一个共3个)。不知道是不是这时是搜索引擎们勤奋工作的结果。但老是这样下去也不是办法。

解决的办法有两个:1、缓存数据;2、页面静态化;

暂时想只把首页的数据进行尽量简单的缓存,也许根本就不叫真正意义的缓存,把首页的数据存在程序全局变量中,只有帖子提交后才更新其中的数据。

这样,当首页要取数据时就不用读数据库了。如果这样还不行的话就试试先把首页静态化。再不行的话只有问问空间提供商了。

下面是转帖的一个JSP动态页面静态化的一个方案,贴在这里备用。

***********************************************************************************************************

一个实现将动态页面转为静态的方案(转自:http://java.ccidnet.com/art/3741/20061008/915263_1.html

 

正文

************************************************************************************************************

 

1.前言

为了能深入浅出的理解这个框架的由来,我们首先来了解一下JSP解析器将我们写的JSP代码转换成的JAVA文件的内容。

下面是一个JSP文件test.jsp

<%@ page language=java contentType=text/html;charset=GB2312 %>

<%

out.write();

%>

<%= 输出%>

经过TOMCAT转换出的JAVA文件test$jsp.java内容如下:

package org.apache.jsp;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

import org.apache.jasper.runtime.*;

 

public class test$jsp extends HttpJspBase {

 

    static {

    }

    public testOutRedir$jsp( ) {

    }

 

    private static boolean _jspx_inited = false;

 

    public final void _jspx_init() throws org.apache.jasper.runtime.JspException {

    }

 

    public void _jspService(HttpServletRequest request, HttpServletResponse  response)

        throws java.io.IOException, ServletException {

 

        JspFactory _jspxFactory = null;

        PageContext pageContext = null;

        HttpSession session = null;

        ServletContext application = null;

        ServletConfig config = null;

        JspWriter out = null;

        Object page = this;

        String  _value = null;

        try {

 

            if (_jspx_inited == false) {

                synchronized (this) {

                    if (_jspx_inited == false) {

                        _jspx_init();

                        _jspx_inited = true;

                    }

                }

            }

            _jspxFactory = JspFactory.getDefaultFactory();

            response.setContentType(text/html;charset=GB2312);

            pageContext = _jspxFactory.getPageContext(this, request, response,

                            , true, 8192, true);

 

            application = pageContext.getServletContext();

            config = pageContext.getServletConfig();

            session = pageContext.getSession();

            out = pageContext.getOut();

                //为了节省篇幅,我删除了解释器添加的注释

                out.write(\r\n);

//上一句是由于<%@ page language=java  contentType=text/html;charset=GB2312 %>后面的换行产生的

                out.write();

                out.write(\r\n\r\n\r\n\r\n);

                out.print( 输出 );

                out.write(\r\n\r\n\r\n\r\n);

        } catch (Throwable t) {

            if (out != null && out.getBufferSize() != 0)

                out.clearBuffer();

            if (pageContext != null) pageContext.handlePageException(t);

        } finally {

            if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);

        }

    }

}

从上面的代码中可以清晰的看到JSP内建的几个对象(out、request、response、session、pageContext、application、config、page)是怎么产生的,懂servlet的朋友一看就能明白。

下面重点理解一下out对象,它被声明为JspWriter类型,JspWriter是一个抽象类,在包javax.servlet.jsp中可以找到它的定义。

abstract public class javax.servlet.jsp.JspWriter extends java.io.Writer{

       final public static int NO_BUFFER = 0;

       final public static int DEFAULT_BUFFER = -1;

       final public static int UNBOUNDED_BUFFER = -2;

       protected int bufferSize;

       protected Boolean autoFlush;

       protected javax.servlet.jsp.JspWriter(int arg1, boolean arg2);

     

    abstract public void newLine() throws IOException ;

    abstract public void print(boolean arg0) throws IOException ;

    abstract public void print(char arg0) throws IOException ;

    abstract public void print(int arg0) throws IOException ;

    abstract public void print(long arg0) throws IOException ;

    abstract public void print(float arg0) throws IOException ;

    abstract public void print(double arg0) throws IOException ;

    abstract public void print(char[] arg0) throws IOException ;

    abstract public void print(String arg0) throws IOException ;

    abstract public void print(Object arg0) throws IOException ;

    abstract public void println() throws IOException ;

    abstract public void println(boolean arg0) throws IOException ;

    abstract public void println(char arg0) throws IOException ;

    abstract public void println(int arg0) throws IOException ;

    abstract public void println(long arg0) throws IOException ;

    abstract public void println(float arg0) throws IOException ;

    abstract public void println(double arg0) throws IOException ;

    abstract public void println(char[] arg0) throws IOException ;

    abstract public void println(String arg0) throws IOException ;

    abtract public void println(Object arg0) throws IOException ;

    abstract public void clear() throws IOException ;

    abstract public void clearBuffer() throws IOException ;

    abstract public void flush() throws IOException ;

    abstract public void close() throws IOException ;

    public int getBufferSize() ;

    abstract public int getRemaining() ;

    public boolean isAutoFlush() ;

}

我相信当我写到这里你可能已经知道我想怎么做了。是的,来个偷天换日,继承JspWriter类,然后实现其定义的虚函数,然后把out变量替换成你自己实现的类的实例就ok了。

2.实现替换

假设

<%@ page language=java  contentType=text/html;charset=GB2312 import=jwb.util.HtmlIntoFile,jwb.util.TempSinglet,java.io.File%><%

JspWriter out_bak = out;String arg1=argument1;String filePath = /cache/根据参数生成文件名_ + arg1 + .html;//首先判断文件是否已经存在,如果不存在则执行本页面,否则跳转到静态页面就OK了File f = new File(pageContext.getServletContext().getRealPath(filePath));if(f.exists()) { out_bak.clear(); pageContext.forward(filePath); System.out.println(直接转到静态页面); return;}out = new HtmlIntoFile(pageContext.getServletContext().getRealPath(filePath));out.write();

%><%= 看吧,这就是输出被重定向到文件的实现,很简单吧^_^%><%out.close();//关闭生成的静态文件out_bak.clear();pageContext.forward(filePath);

System.out.println(执行本页面后再转到静态页面);return;%>

3.更新问题

下面就讨论一下如何更新生成静态文件,其实从上面实现中你可以看到,很简单的就是将生成的静态文件删除即可,至于什么时候删除,要看你的需求了。我能想到的几种情况如下

    *

      当用来生成页面的数据更新时

    *

      如果不需要很提供时时的数据可以定时更新

    *

      永远不更新

*********************************************************************************************************

                                                        转帖完毕

跳来跳去的adsense广告和在文章中广告文字绕排

  网站需要运行,google广告是一个途径,我认为不应绝对的排斥广告

  前一段时间我发现广告的点击率由1~1.5%下降为0.5~0.8%,就想是不是一成不变的广告对朋友已经失去吸引力,于是用代码让广告随机的变位置和种类。结果经过3天的试验效果,点击率更是下降到了0.1%。

  看来,还是固定位置的广告要好点呀。聊胜于无吧。

  现在的广告形式是页面头尾是大横幅,文章开头绕排一个200×200的正方形广告。

  另外,我申请了google广告的自定义渠道报告分析,从今天的效果来看,还是菜单顶部的效果好于中部和底部。

  可见,网页广告成功的要素还是醒目为主,那种像我那样不断变种类和位置的跳来跳去的广告是不行的。

附:一、jsp页面的元素随机跳动代码

 下面附上我的jsp页面的元素随机跳动代码,使用的是Struts+JSTL+JSP。很简单:

  1、随机数发生器:


package com.learndiary.website.util;

import java.util.Random;

import com.learndiary.website.Constants;

/**

 * generate random int between 0 (inclusive) and the specified value: Constants.MAX_RANDOM (exclusive),

 */

public class Randomer {

  private int i;

  public int getI() {

    return new Random().nextInt(Constants.MAX_RANDOM);

  }

}

  2、在用户进入页面后在session中保留一个 Randomer的对象。

  3、在页面和JSTL调用事先在google帐户中复制下来的代码:


 <c:set var="j" value="2"/>

 <c:set var="k" value="5"/>

 

 

 <c:if test="false">

  <div align="left">

 </c:if>

 <c:if test="false">

  <div align="center">

 </c:if>

 <c:if test="false">

  <div align="right">

 </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/234.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/468.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/728.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/link_728.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/ref_firefox.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/ref_firefox_en.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/ref_pic.jsp" %>

  </c:if>

 

  <c:if test="false">

  <%@ include file="/guanggao/ref_pic_en.jsp" %>

  </c:if>

 

 </div>

  总觉得这样写可以让页面简洁一点,也许效率比直接写在jsp页面的要差一点?不知道。

 二、google adsense被文字绕排的效果 (相关代码来自google上的论坛,好像是:http://groups.google.com/group/adsense-help-zhs,具体位置忘了)

1、

 


     <table cellSpacing=0 cellPadding=10 align=left border=0>

      <tr>

       <td style="border-style: dotted; border-width: 0">

        <%@ include file="/guanggao/200_200.jsp" %>

       </td>

      </tr>

     </table>

     <p style="text-indent: 3">

     <bean:write name="aGoal" property="articleText" scope="request" filter="false"/><!--文章内容-->

 

但是我发现google广告在文章头部的加载时间太长严重影响了文章的显示,于是,根据原来学到的让del.icio.us不影响页面的加载(转帖),改进了代码如下:

内容部分:


     <font face="Ms Song"><font face="宋体">

     <table cellSpacing=0 cellPadding=10 align=left border=0>

      <tr>

       <td style="border-style: dotted; border-width: 0">

        <div id="daily_loading">loading...</div>

        <div id="daily_show" style="display:none;"></div>

       </td>

      </tr>

     </table>

     <p style="text-indent: 3">

     <bean:write name="aGoal" property="articleText" scope="request" filter="false"/><!--文章内容-->

     </font></font>

在</body>和</html>之间的部分:

<script type="text/javascript">

 

   function daily() {

 

       document.getElementById("daily_loading").style.display = 'none';

       document.getElementById("daily_loaded").style.display = 'none';

       document.getElementById("daily_show").innerHTML=document.getElementById("daily_loaded").innerHTML;

       document.getElementById("daily_show").style.display = 'block';    

   };

 

   window.onload = daily;

 

</script>

<div id="daily_loaded" style="display:none">

<%@ include file="/guanggao/200_200.jsp" %>

</div>

以上代码供对有同样需求的朋友参考,热切的希望您的任何意见和建议,谢谢。