对于Hibernate的几点质疑
2007/04/19 22:32 | by edwardproAdmin ]
今天本来是一个好机会问Gavin不过自己的英语不行,估计一些复杂的表述很难描述清楚,不过我想还是在blog里聊聊吧。
1 关于轻量级的开发
什么叫轻量级?几个类几个表不需要太多扩展性能,这种平台显然不合适Hibernate,因为为了简单的dao操作需要付出很大的配置代价,而gavin对于ROR的简便是很suck的,因此Hibernate依然是一个中型以上使用的系统。这是Hibernate我认为的弱项。
2 多表问题
大家都知道在Hibernate里的实体其实就是表的java表现,而这种模式在多表查询中变得不再灵活,这个问题在robbin的讲座中也得到验证,而我个人更倾向于使用一种更特性的单独bean加入到系统中,但gavin显然不会同意,我也很难说服自己。
3 Connection陷阱
如果你试图把Hibernate当作连接池那么你就是在自杀,这个我曾经用过,如果sql执行没有Exception还好一旦有了,犹豫Hibernate自身的管理是通过SessionFactory的因此连接一旦取出来Session和Connection都会失去管理,这个很容易造成性能问题,我也在实践中出现过类似问题
4 Xml配置问题
Gavin是狂热的xml者,而我开始倾向部分使用jason了,这种更清楚的表达对于数据传输应该更有效率。
Seam的感悟
2007/04/19 22:22 | by edwardproAdmin ]
老实说对于Seam如果不是今天听到还真不了解,因为我们身边不缺庞大的开发框架尤其是MVC框架,webwork tapestray structs等等,太多了。今天听了曹老师的介绍,对于seam有了一点了解,下面谈谈自己的想法:
1 IOC的畅想,在spring中大家都知道,它的IOC是inject,但在Seam中这种观念得到了突破,它提出了一种叫做Backject的概念字面理解就是注回这是一个突破的概念。用过Spring的同学都应该知道在某些时候非要使用GetBean从上下文中得到Bean的,而有了回注的功能,就可以达到配置对bean的反向注入这样就再也不用使用getBean这种依赖spring的方法了。而且Seam的IOC允许在很多时候进行Bean的初始化这点比起Spring也灵活得多。
2 MVC的扩展:在Seam中提出了一种叫做对话的概念,什么是对话呢?对话是把一组相关的动作(Process)组合起来达到一个统一的功能比如多步注册等,这在spring中也有类似的(曹老师说目前还没有这个不是太同意),但spring的实现方法过于麻烦,而在Seam中他的实现方法比较容易 使用一个HashMap的集合来存放个步骤的所有上下文信息(Request Response Session)代码容易又容易使用这种简单的创意令我眼睛一亮
Hibernate性能篇——Robbin讲座总结
2007/04/19 22:12 | by edwardproAdmin ]
Hibernate的性能问题一直是大家关注的,很多人都觉得Hibernate性能不行,其实我觉得没有,Hibernate性能其实非常不错,觉得不行主要就是没有用好,下面总结下Robbin说的内容:
1 多表查询: cache 正确的反转控制,这两条是解决多表的性能问题的关键
2 分页技术: 使用3.0的createFilter方法得到分页,Hibernate拥有非常好的分页实现
3 分表: 采用更多的1to1把数据表拆小,然后记得配置隐式多态,这样就不会把整个数据集都读出来了
Robbin本人大概说了10条我把它们整合成了这样3条,希望对大家有用
用JSON代替XML
2007/03/18 21:48 | by edwardproAdmin ]
一般来说AJAX的最后一个技术就是XML,那么一般来看都会用XML传输数据,但在实际应用中实际上XML解析更繁琐消耗也大,在不需要XML特性的情况下完全可以使用JSON代替,而且JSON拥有类似HASHMAP的数据结构对于实际应用会非常方便,在很多时候我都会用JSON代替Array因为我需要使用Hash结构,如果自己实现有需要写一个类对数组作遍历,很不合算,用JSON更方便。
在AJAX应用中JSON更是方便,以下给大家一个简单的例子:(需要prototype配合)
function getinfoBean(beaninfo){
var message=eval('(' + beaninfo+')'); //特别注意这边需要填写括号,否则编译器报错。
return message;
}
通过上述函数可以把 response.responseText 送入得到一个JSON对象:
var msgAll = {
"m0": "<font color=\"green\">没有问题了</font>",
"m1": "<font color=\"red\">密码长度错误,应该至少6位</font>",
"m2": "<font color=\"red\">密码输入不一致</font>",
"m3": "<font color=\"red\">mail格式错误</font>",
"m4": "<font color=\"red\">该字段不能为空</font>",
"m5": "<font color=\"red\">您提交的信息有误</font>",
"m6": "<font color=\"green\">正在提交信息</font>"
};
这样调用的时候就可以用:
msgAll.m3 来得到他的值了。这样的解析相对于严格的XML更方便
设计模式:状态机
2007/03/08 09:23 | by edwardproAdmin ]
设计模式看过1.5遍了,但感觉自己学得还是不好,名字说不上来,应用也就局限在某些品种上,看过spring的代码感觉到自己学习的太多了,设计模式的典范教材就是spring的代码,今天讲讲自己的设计模式,这种模式我不知道应该叫什么,我叫它状态机:
应用:诸如如下的
if(exp1){
return aaa;
}else if(exp2){
return bbb;
}
....
分析:这种模型在很多地方都会用到,一般来说我们的处理方法就是写上述的循环然后return,但这种方法的坏处就是维护问题。在实际应用中这样的代码逻辑是很难看的。在前一次的应用中曾经尝试在短信程序中最后返回n多个结果,当然我采用了上述的模式,结果是非常恐怖的大约有11种状态,另代码支离破碎,而且后期维护基本上只能增加,修改代码害怕所有的逻辑出问题,这时候就进入了这种两难的境地。我们希望是一个统一的处理表达式开关加上对应的处理函数(也许只是return)。
因此上述的模式应该变成如下的控制器模型:
doProcess(expFunction,expBean)
return doReturn(expBean);
其中使用两个借口分别在doprocess和doreturn上,几点使用的说明,首先代码必须保持好颗粒度,如果颗粒度不合适同样影响到接口的修改。
上述模型在spring下实现更容易可以方便的采用配置系统得到需要的“处理-返回”系统。
AJAX 和 SEO
2007/02/02 09:26 | by edwardproAdmin ]
原文连接:http://blog.tn38.net/archives/2005/12/ajax_and_seo.html
原文翻译:
ajax对于那些此前没有听过的人来说,是一种网页应用程序的新时代。虽然它只是把一些已有技术整合起来,但却达到了一种web应用的新时代。我经常看到很多优秀的例子:gg map 和gg suggest(gg suggest已经正式上线了)等
实际上,他只是通过不刷新页面而把远程数据加载到当前页面来。
但对于seo来说这是一个挑战,因为搜索引擎对于那些唯一url,但内容不同的页面不那么敏感。
怎样让搜索引擎看到ajax?
我会说两个主要途径来改变ajax技术对于搜索引擎的表现
Rule #1
The initial load of the AJAX application must contain the optimised elements such as TITLE and headers and also must be reachable from a fixed address.
规则1
初始化ajax的应用必须包含那些可以看到的元素包括标题 html头 以及其他可达的固定url地址。
Rule #1 is all about using the following two techniques.
Server side script
.htaccess mod_rewrite
如果你不是apache可能没有mod_rewrite,但肯定有类似功能你可以使用类似的rewrite模块
下面有一个rewrite的例子:
http://labs.tn38.net/ajax_seo/company/1/
http://labs.tn38.net/ajax_seo/company/2/
http://labs.tn38.net/ajax_seo/company/3/
->
http://labs.tn38.net/ajax_seo/index.php?company=1
http://labs.tn38.net/ajax_seo/index.php?company=2
http://labs.tn38.net/ajax_seo/index.php?company=3
我们看下apache的配置:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ajax_seo/(.*)/(.*)/$
/ajax_seo/index.php?$1=$2
虽然访问的是一个动态页面,但我们可以通过rewrite模块看到他只不过是一个静态目录的url。
Rule #2
As with all websites, we need inbound links which are keyphrase descriptive that point to a particular resource, not just the home page.
规则二,我们必须所有的页面上都有关键字表述这个字段来描述页面的内容,而不仅仅是在首页
下面有一个例子:
http://labs.tn38.net/ajax_seo/
我们看到他的目录下有如此的一个url:
http://labs.tn38.net/ajax_seo/directory.html
规则3:
我们经常在ajax的连接上使用return false,但是ggbot是不会理会这些javascript的,因此他依然会跟踪这些连接。
彻底解决webwork2.2.4和spring的集成问题
2007/01/18 18:28 | by edwardproAdmin ]
JDK6脚本性能不成熟测试
2006/12/17 12:54 | by edwardproAdmin ]
利用js的循环和java循环比较速度:
function test(){
for(var i=0;i<=3256500;i++){
Math.round(11.2345);
}
}
javascript结果:
0 [main] INFO com.edward.test.script.TestScript - start:1166329667718
30766 [main] INFO com.edward.test.script.TestScript - start:1166329698484
30766 [main] INFO com.edward.test.script.TestScript - result:30s
java结果:
0 [main] INFO com.edward.test.script.TestScript - start:1166329775421
359 [main] INFO com.edward.test.script.TestScript - start:1166329775796
359 [main] INFO com.edward.test.script.TestScript - result:0s (<1s)
虽然不是很科学,但是足以说明问题,脚本的性能还是比较令人失望的,不会愿意有人忍受达到30倍的性能落差吧。
开始期待性能提高了。。。

测试硬件:
迅驰II 赛扬 1.4GHz
1G 内存
JDK6新特性SCRIPT最简单尝试
2006/12/17 12:42 | by edwardproAdmin ]
测试成功的代码:
test.js:
function test(){
return Math.round(11.2);
}
主要代码:
public static void main(String[] args){
org.apache.log4j.BasicConfigurator.configure();
ScriptEngineManager mgr = new ScriptEngineManager(); //启动脚本管理器
ScriptEngine engine=mgr.getEngineByName("ECMAScript");//配置脚本类型为javascript
try {
engine.eval(new FileReader("c:\\test.js"));//读取脚本
Invocable invocableEngine=(Invocable)engine;//转成invocable
Object ret=invocableEngine.invokeFunction("test", null);//调用test函数并接受返回值
logger.info("ret:"+(Double)ret);//已经可以探测出类型了
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
运行结果:
0 [main] INFO com.edward.test.script.TestScript - ret:11.0
使用中有这个几个问题:
alert这类界面 js函数是不支持的会报错:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "alert" is not defined. (
at com.sun.script.javascript.RhinoScriptEngine.invoke(RhinoScriptEngine.java:184)
at com.sun.script.javascript.RhinoScriptEngine.invokeFunction(RhinoScriptEngine.java:142)
看到他的js解析器是属于mozilla的
另外在eclipse中使用需要手工建立jdk1.6的jar lib,否则虽然你可以选择jdk6作为编译器,但是运行时还是jdk5因为eclipse还是会默认带上1.5的jar,手工建立一个,然后加入并删除系统自动带上的jdk1.5的包就可以了。
从支持上来说至少对于js的支持是不令人满意的,不会有很多人写了很多js脚本来用java运行吧,这毫无意义,这些工作java都可以完成。但如果是php或者ruby paython就会完全不同,他们的构架上有很大不同,可以支持大量不同的特性来扩展java自身的功能,这项新功能可以说是非常有价值的,现在唯一的疑问就是性能。
apache httpclient 对iis服务器的乱码问题
2006/12/15 12:50 | by edwardproAdmin ]
URLEncoder.encode(sResponse);
就这么简单,由于预先编码后,httpclient不会再编码,因此整个代码得以保持原来的编码方式,实验成功!
spring代码的一个小心得
2006/12/09 02:34 | by edwardproAdmin ]
class A{
private A(){}
public static void a1(){}
}
好处是什么?显然是无法new这个对象了,当你new这个对象的时候会报这个类无法实例,也就是告诉了大家这是一个工具类里边的方法都是static的。
今天非常偶然看了下spring代码:
public abstract class SessionFactoryUtils {
public static DataSource getDataSource(SessionFactory sessionFactory) {
if (sessionFactory instanceof SessionFactoryImplementor) {
ConnectionProvider cp = ((SessionFactoryImplementor) sessionFactory).getConnectionProvider();
if (cp instanceof LocalDataSourceConnectionProvider) {
return ((LocalDataSourceConnectionProvider) cp).getDataSource();
}
}
return null;
}
}
说实话这是一个迷惑性很强的类,我以为是一个虚类,但看下去却发现里边全部都是static的方法,显然就是工具类,而它同样可以达到我在前面说的效果就是无法new这个对象,这是一种工具类的思路,只是以前并没有想到,对啊,阻止你实例用虚类就好了,相比之下代码量也减少了(private方法还要增加函数),而这种方法更简单。
结论有时候看别人的代码也是一种学习,其实hibernate和spring都是实现的非常好的虚工厂的范例。
spring+sqlserver使用hibernate template的问题
2006/11/22 23:29 | by edwardproAdmin ]
1 采用了super类,实际上这是我的一个失误,忘记了spring的对象实际上是持久化,这样存在了大数据负荷时候的隐患。
2 这个问题非常致命,同样的配置在mysql下可以正常save但是用sqlserver就不行了,无论如何都插入不了了,配置如下:
bean id="ds_jnj"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
property name="configLocation"
valueclasspath:hibernate.cfg.xml /value
/property
/bean
bean id="appinit2" class="com.cms21.wap.wap3.beans.AppSetupBean"
property name="hibernateCfg"
map
<entry key="default"
<ref bean="ds_jnj" /
</entry
<entry key="jnj"
<ref bean="ds_jnj" /
</entry
</map
</property
<property name="log4jCfg"
<value>classpath:log4j.properties</value
</property
</bean>
后来发现似乎没有事务处理,会不会因为没有事务而没有提交呢?于是配置了事务:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="ds_jnj" />
</property>
</bean>
可惜结果依然令我失望,照样无法写入,难道这就是spring2.0和1.2一样的宿命么?注定要自己写轻量级dao框架么?还不死心,开始实验各种方法,手动提交等,但是由于template被封装了似乎非常麻烦也没有效果,正当一筹莫展的时候,突然启动的日志让我兴奋了:
FO [main] (C3P0ConnectionProvider.java:54) - autocommit mode: false
难道是他的问题,于是在hibernate中加入了:
<property name="c3p0.autoCommitOnClose">true</property>
哈哈,终于写入了我可爱的数据!yeah!原来不是bug只是我没有配置,被可恶的c3p0设置成了false,不过问题出现了,首先为什么同样的内容在mysql上ok呢?第二我已经配置了事务,按照spring的说法,如果没有出错就会自动提交一次,但事实是采用了c3p0的时候变成了它的天下,我也没有注意过这个问题,结果酿成了如此的结果。
看来之前测试还是不够仔细结果造成了很多问题,现在详细多了,心情不错总算解决了一个愚蠢的问题:)
防洪水攻击之攻击类型
2006/11/20 10:21 | by edwardproAdmin ]
拒绝服务攻击是最常见的一类网络攻击类型。在这一攻击原理下,它又派生了许多种不同的攻击方式。正确了解这些不同的拒绝攻击方式,就可以为正确、系统地为自己所在企业部署完善的安全防护系统。
入侵检测的最基本手段是采用模式匹配的方法来发现入侵攻击行为。要有效的进行反攻击,首先必须了解入侵的原理和工作机理,只有这样才能做到知己知彼,从而有效的防止入侵攻击行为的发生。下面我们针对几种典型的拒绝服务攻击原理进行简要分析,并提出相应的对策。
l 死亡之Ping(Ping of death)攻击
由于在早期的阶段,路由器对包的最大大小是有限制的,许多操作系统TCP/IP栈规定ICMP包的大小限制在64KB以内。在对ICMP数据包的标题头进行读取之后,是根据该标题头里包含的信息来为有效载荷生成缓冲区。当大小超过64KB的ICMP包,就会出现内存分配错误,导致TCP/IP堆栈崩溃,从而使接受方计算机宕机。这就是这种“死亡之Ping”攻击的原理所在。根据这一攻击原理,黑客们只需不断地通过Ping命令向攻击目标发送超过64KB的数据包,就可使目标计算机的TCP/IP堆栈崩溃,致使接受方宕机。
防御方法:现在所有的标准TCP/IP协议都已具有对付超过64KB大小数据包的处理能力,并且大多数防火墙能够通过对数据包中的信息和时间间隔分析,自动过滤这些攻击。Windows 98、Windows NT 4.0(SP3之后 )、Windows 2000/XP/Server 2003、Linux、Solaris和Mac OS等系统都已具有抵抗一般“Ping of death”拒绝服务攻击的能力。此外,对防火墙进行配置,阻断ICMP以及任何未知协议数据包,都可以防止此类攻击发生。
l 泪滴(teardrop)攻击
对于一些大的IP数据包,往往需要对其进行拆分传送,这是为了迎合链路层的MTU(最大传输单元)的要求。比如,一个6000字节的IP包,在MTU为2000的链路上传输的时候,就需要分成三个IP包。在IP报头中有一个偏移字段和一个拆分标志(MF)。如果MF标志设置为1,则表面这个IP包是一个大IP包的片断,其中偏移字段指出了这个片断在整个IP包中的位置。例如,对一个6000字节的IP包进行拆分(MTU为2000),则三个片断中偏移字段的值依次为:0,2000,4000。这样接收端在全部接收完IP数据包后,就可以根据这些信息重新组装这几个分次接收的拆分IP包。在这里就又一个安全漏洞可以利用了,就是如果黑客们在截取IP数据包后,把偏移字段设置成不正确的值,这样接收端在收后这些分拆的数据包后就不能按数据包中的偏移字段值正确重合这些拆分的数据包,但接收端会不断偿试,这样就可能致使目标计算朵操作系统因资源耗尽而崩溃。
泪滴攻击利用修改在TCP/IP堆栈实现中信任IP碎片中的包的标题头所包含的信息来实现自己的攻击。IP分段含有指示该分段所包含的是原包的哪一段的信息,某些操作系统(如SP4以前的Windows NT 4.0)的TCP/IP在收到含有重叠偏移的伪造分段时将崩溃,不过新的操作系统已基本上能自己抵御这种攻击了。
防御方法:尽可能采用最新的操作系统,或者在防火墙上设置分段重组功能,由防火墙先接收到同一原包中的所有拆分数据包,然后完成重组工作,而不是直接转发。因为防火墙上可以设置当出现重叠字段时所采取的规则。
l TCP SYN洪水(TCP SYN Flood)攻击
TCP/IP栈只能等待有限数量ACK(应答)消息,因为每台计算机用于创建TCP/IP连接的内存缓冲区都是非常有限的。如果这一缓冲区充满了等待响应的初始信息,则该计算机就会对接下来的连接停止响应,直到缓冲区里的连接超时。
TCP SYN洪水攻击正是利用了这一系统漏洞来实施攻击的。攻击者利用伪造的IP地址向目标发出多个连接(SYN)请求。目标系统在接收到请求后发送确认信息,并等待回答。由于黑客们发送请示的IP地址是伪造的,所以确认信息也不会到达任何计算机,当然也就不会有任何计算机为此确认信息作出应答了。而在没有接收到应答之前,目标计算机系统是不会主动放弃的,继续会在缓冲区中保持相应连接信息,一直等待。当达到一定数量的等待连接后,缓区部内存资源耗尽,从而开始拒绝接收任何其他连接请求,当然也包括本来属于正常应用的请求,这就是黑客们的最终目的。
防御方法:在防火墙上过滤来自同一主机的后续连接。不过“SYN洪水攻击”还是非常令人担忧的,由于此类攻击并不寻求响应,所以无法从一个简单高容量的传输中鉴别出来。防火墙的具体抵御TCP SYN洪水攻击的方法将在本书的第三章最后有详细介绍。
l Land攻击
这类攻击中的数据包源地址和目标地址是相同的,当操作系统接收到这类数据包时,不知道该如何处理,或者循环发送和接收该数据包,以此来消耗大量的系统资源,从而有可能造成系统崩溃或死机等现象。
防御方法:这类攻击的检测方法相对来说比较容易,因为它可以直接从判断网络数据包的源地址和目标地址是否相同得出是否属于攻击行为。反攻击的方法当然是适当地配置防火墙设备或包过滤路由器的包过滤规则。并对这种攻击进行审计,记录事件发生的时间,源主机和目标主机的MAC地址和IP地址,从而可以有效地分析并跟踪攻击者的来源。
l Smurf 攻击
这是一种由有趣的卡通人物而得名的拒绝服务攻击。Smurf攻击利用多数路由器中具有同时向许多计算机广播请求的功能。攻击者伪造一个合法的IP地址,然后由网络上所有的路由器广播要求向受攻击计算机地址做出回答的请求。由于这些数据包表面上看是来自已知地址的合法请求,因此网络中的所有系统向这个地址做出回答,最终结果可导致该网络的所有主机都对此ICMP应答请求作出答复,导致网络阻塞,这也就达到了黑客们追求的目的了。这种Smurf 攻击比起前面介绍的“Ping of Death”洪水的流量高出一至两个数量级,更容易攻击成功。还有些新型的Smurf攻击,将源地址改为第三方的受害者(不再采用伪装的IP地址),最终导致第三方雪崩。
防御方法:关闭外部路由器或防火墙的广播地址特性,并在防火墙上设置规则,丢弃掉ICMP协议类型数据包。
l Fraggle攻击
Fraggle攻击只是对Smurf攻击作了简单的修改,使用的是UDP协议应答消息,而不再是ICMP协议了(因为黑客们清楚UDP协议更加不易被用户全部禁止)。同时Fraggle攻击使用了特定的端口(通常为7号端口,但也有许多使用其他端口实施Fraggle攻击的),攻击与Smurf攻击基本类似,不再赘述。
防御方法:关闭外部路由器或防火墙的广播地址特性。在防火墙上过滤掉UDP报文,或者屏蔽掉一些常被黑客们用来进行Fraggle攻击的端口。
l 电子邮件炸弹
电子邮件炸弹是最古老的匿名攻击之一,通过设置一台计算机不断地向同一地址发送大量电子邮件来达到攻击目的,此类攻击能够耗尽邮件接受者网络的带宽资源。
防御方法:对邮件地址进行过滤规则配置,自动删除来自同一主机的过量或重复的消息。
tomcat下防止引用的方法
2006/11/13 23:00 | by edwardproAdmin ]
url pattern
remote ip
white list
然后利用tomcat的过滤器实现一个接口方法就可以使得资源不被引用或者其他事情。
当然在apache下其实也是一个过滤器类的重定向装置,本质区别不大。
网站防引用心得
2006/11/12 23:22 | by edwardproAdmin ]
禁止引用可以在网站根目录上建立.htaccess文件里边存放,如下内容:
SetEnvIfNoCase Referer "^http://blog.edwardro.com/" local_ref=1
SetEnvIfNoCase Referer "^http://edwardro.com/" local_ref=1
Order Allow,Deny
Allow from env=local_ref
Allow from 127.0.0.1
不过我使用后发现无效,经过探查,原来我已经配置了
AllowOverride None
这样配置会使得.htaccess文件失效,这样当然是提高了效率,因为这种方法的查找是递归的,这样消耗非常大。于是我把它配置在
下面看看现在的访问日志:
65.77.121.65 - - [12/Nov/2006:23:18:53 +0800] "GET /attachment/200610/1161479678_4.gif?gowy=14379 HTTP/1.1" 403 333 "http://dzh1.mop.com/topic/readSub_7139134_0_0.html" "Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7"
222.139.203.143 - - [12/Nov/2006:23:18:53 +0800] "GET /attachment/200610/1161479678_4.gif?rmydn=25761 HTTP/1.1" 403 333 "http://dzh1.mop.com/topic/readSub_7137428_0_0.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; MyIE2)"
已经全部变成了403错误,虽然这样服务器还是有消耗,当然还可以用rewrite方法来处理:
同样把代码加在
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://blog.edwardro.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.edwardro.com/.*$ [NC]
RewriteRule .*\.(jpg|jpeg|gif|png|bmp|rar|zip|exe)$ http://www.mop.com/index.gif [R,NC]
这样只要遇到引用就会重定向到指定的url,嘿嘿,我不厚道了,定义了一个mop的地址:)
看来再多的理论没有用,只有遇到问题的时候才能让人进步,apache的配置还是蛮有研究头,今后继续研究,优化慢慢路。






