一种更高效率的ISAPI整合IIS与Tomcat_JSP的方式(非jk)
[ 大恐龙 发表于 2008年9月 9日 17:34 ]
今天发现一种极好的整合IIS和JSP的方法,毫无疑问java在windows下运行比在linux运行效率要高(大约4%),同比IIS比Apache的IO能力强,在不考虑了lisence的问题下,笔者一直在考虑在windows下部署java的生产环境,尽管笔者的很大程度的工作是管理的维护linux服务器,但是发现很多时候windows还是最好的选择,当然是在得到一样优秀的维护和管理的前提下,一直以来很头疼的就是Tomcat和IIS的整合,在windows下肯定不会考虑使用apache,apache在windows下的表现太差了。笔者使用了2个月时间仔细研读和修改apache 2.29版的windows版源代码(哈哈,不专业了apache的源代码是可移植C++不分版本)试图优化apache的IO。 最终不得不放弃,Apache的构架上不如IIS,在windows上表现始终不如意,所以还是考虑用IIS整合tomcat.
IIS整合Tomcat的传统方式是JK,通过8009端口做代理,这样做缺点很多,当然优点也很多,优点我就不说了。这样的缺点是实际上要socket一次,笔者认为除非在一台IIS+多个Tomcat,或者IIS和tomcat不在一台服务器上时才有必要使用。在大多数情况,也就是IIS和Tomcat在同一台服务器上时,完全可以用一种高效的办法.
答案其实就是asp.net里的ihttphandle, 使用asp.net的ISAPI handle劫持要转发的页面(图方便,有达人直接写一个C++的ISAPI也行,.net基于jit效率也没得说),直接把他rewrite到8080端口上,也就是实际上IIS和Tomcat没有任何通信。图片、js、html全部IIS处理,这个小程序只处理URL。也就是我写的这个JSP ihttphandle直接取tomcat 的response 作为IIS的response。
下载 JSP_iHttpHandle.dll (.net 3.5) 拷贝到站点的bin目录。
修改web.config添加:
<!-- JSP ihttpHandle 配置 -->
<add path="*.jsp" verb="GET,POST" type="com.w3cool.web.jsp.TomcatRequestHandler" />
<add path="*.xhtml" verb="GET,POST" type="com.w3cool.web.jsp.TomcatRequestHandler" />
<add path="/servlet/*" verb="GET,POST" type="com.w3cool.web.jsp.TomcatRequestHandler" />
<!-- JSP ihttpHandle 配置 -->
然后在 站点属性 -> "home directory" ->Configuration ->
把.jsp .xhtml你要tomcat处理的内容加在aspnet_isapi.dll上,当然也可以图方便设定一个WildCard
好了。现在就可以看看效果
java反编译源代码处理技巧(4)-boolean $assertionsDisabled
[ 大恐龙 发表于 2007年11月20日 21:23 ]
static final boolean $assertionsDisabled; /* synthetic field */
if(!$assertionsDisabled && ((WeakReference)oIterActive).get() != iter)
throw new AssertionError();
static {
$assertionsDisabled = !(SafeHashMap.class).desiredAssertionStatus();
}
|
assert ((WeakReference)oIterActive).get() != iter; |
java反编译源代码处理技巧(3)-do while
[ 大恐龙 发表于 2007年11月20日 21:13 ]
| do { if(!e.hasMoreElements()) break label0; key = (String)e.nextElement(); } while(!m_tblCache.containsKey(key)); throw new IllegalStringException(key); |
for(Enumeration e = tblTest.keys(); e.hasMoreElements();) { String key = (String)e.nextElement(); if(m_tblCache.containsKey(key)) throw new IllegalStringException(key); } |
java反编译源代码处理技巧(2)-break
[ 大恐龙 发表于 2007年11月20日 16:01 ]
| if(fReentrant) { aoKey = SimpleEnumerator.toArray(iterator(), ao != null ? ao : OverflowMap.EMPTY_ARRAY); break MISSING_BLOCK_LABEL_238; } gate.close(-1L); int cKeys = mapOverflow.size(); if(ao == null) { aoKey = new Object[cKeys]; } else { int cElements = ao.length; if(cKeys > cElements) { aoKey = (Object[])Array.newInstance(((Object) (ao)).getClass().getComponentType(), cKeys); } else { aoKey = ao; if(cKeys < cElements) aoKey[cKeys] = null; } } int iKey = 0; Iterator iter = mapOverflow.getStatusMap().entrySet().iterator(); do { if(!iter.hasNext()) break; java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); Status status = (Status)entry.getValue(); if(status.isEntryExistent()) aoKey[iKey++] = entry.getKey(); } while(true); if(!$assertionsDisabled && iKey != cKeys) throw new AssertionError(); gate.open(); break MISSING_BLOCK_LABEL_238; |
if(fReentrant) { aoKey = SimpleEnumerator.toArray(iterator(), ao != null ? ao : OverflowMap.EMPTY_ARRAY); }else{ gate.close(-1L); int cKeys = mapOverflow.size(); if(ao == null) { aoKey = new Object[cKeys]; } else { int cElements = ao.length; if(cKeys > cElements) { aoKey = (Object[])Array.newInstance(((Object) (ao)).getClass().getComponentType(), cKeys); } else { aoKey = ao; if(cKeys < cElements) aoKey[cKeys] = null; } } int iKey = 0; Iterator iter = mapOverflow.getStatusMap().entrySet().iterator(); do { if(!iter.hasNext()) break; java.util.Map.Entry entry = (java.util.Map.Entry)iter.next(); Status status = (Status)entry.getValue(); if(status.isEntryExistent()) aoKey[iKey++] = entry.getKey(); } while(true); if(!$assertionsDisabled && iKey != cKeys) throw new AssertionError(); gate.open(); } |
java反编译源代码处理技巧
[ 大恐龙 发表于 2007年11月20日 15:48 ]
| public static final class Type extends Enum { public static final Type SELECT; public static final Type UPDATE; public static final Type INSERT; public static final Type DELETE; private static final Type $VALUES[]; public static final Type[] values() { return (Type[])$VALUES.clone(); } public static Type valueOf(String name) { return (Type)Enum.valueOf(com/***/***/***/***$Type, name); } static { SELECT = new Type("SELECT", 0); UPDATE = new Type("UPDATE", 1); INSERT = new Type("INSERT", 2); DELETE = new Type("DELETE", 3); $VALUES = (new Type[] { SELECT, UPDATE, INSERT, DELETE }); } private Type(String s, int i) { super(s, i); } } |
public enum Type { SELECT, UPDATE, INSERT, DELETE }; |
enum的处理
| Script script; int iLine; int ofInLine; script = m_script; iLine = script.getLine(); ofInLine = script.getOffset(); if(script.nextChar() != '<') goto _L2; else goto _L1 _L1: script.nextChar(); JVM INSTR lookupswitch 3: default 330 // 33: 124 // 47: 72 // 63: 98; goto _L3 _L4 _L5 _L6 _L5: m_nCtx = 5; return new XmlToken(XmlToken.TOK_ENDTAG_START, iLine, ofInLine, script.getOffset() - ofInLine); _L6: m_nCtx = 4; return new XmlToken(XmlToken.TOK_PI_START, iLine, ofInLine, script.getOffset() - ofInLine); _L4: script.nextChar(); JVM INSTR lookupswitch 3: default 313 // 45: 164 // 68: 275 // 91: 196; goto _L7 _L8 _L9 _L10 _L8: match('-'); m_nCtx = 3; return new XmlToken(XmlToken.TOK_COMMENT_START, iLine, ofInLine, script.getOffset() - ofInLine); _L10: String sData; match("CDATA["); ParsePosition pos = script.savePosition(); scan("]]>"); sData = script.subScript(pos).toString(); script.nextChar(); script.nextChar(); script.nextChar(); return new XmlToken(2, 4, 4, sData, sData, iLine, ofInLine, script.getOffset() - ofInLine); _L9: script.putBackChar(); match("DOCTYPE"); m_nCtx = 2; return new XmlToken(XmlToken.TOK_DOCTYPE_START, iLine, ofInLine, script.getOffset() - ofInLine); _L7: script.putBackChar(); match('-'); throw internalError(); _L3: script.putBackChar(); m_nCtx = 5; return new XmlToken(XmlToken.TOK_ELEMENT_START, iLine, ofInLine, script.getOffset() - ofInLine); _L2: script.putBackChar(); ParsePosition pos = script.savePosition(); while(script.nextChar() != '<') ; script.putBackChar(); sData = script.subScript(pos).toString(); return new XmlToken(2, 4, 3, sData, sData, iLine, ofInLine, script.getOffset() - ofInLine); EOFException e; e; logError(3, "XT-002", null, script.getLine(), script.getOffset(), 0); throw new CompilerException(); e; logError(3, "XT-003", new String[] { e.toString() }, script.getLine(), script.getOffset(), 0); throw new CompilerException(); |
Script script = m_script; int iLine = script.getLine(); int ofInLine = script.getOffset(); try { ParsePosition pos; String sData; if(script.nextChar() == '<') { switch(script.nextChar()) { case 47: // '/' m_nCtx = 5; return new XmlToken(XmlToken.TOK_ENDTAG_START, iLine, ofInLine, script.getOffset() - ofInLine); case 63: // '?' m_nCtx = 4; return new XmlToken(XmlToken.TOK_PI_START, iLine, ofInLine, script.getOffset() - ofInLine); case 33: // '!' switch(script.nextChar()) { case 45: // '-' match('-'); m_nCtx = 3; return new XmlToken(XmlToken.TOK_COMMENT_START, iLine, ofInLine, script.getOffset() - ofInLine); case 91: // '[' match("CDATA["); pos = script.savePosition(); scan("]]>"); sData = script.subScript(pos).toString(); script.nextChar(); script.nextChar(); script.nextChar(); return new XmlToken(2, 4, 4, sData, sData, iLine, ofInLine, script.getOffset() - ofInLine); case 68: // 'D' script.putBackChar(); match("DOCTYPE"); m_nCtx = 2; return new XmlToken(XmlToken.TOK_DOCTYPE_START, iLine, ofInLine, script.getOffset() - ofInLine); } script.putBackChar(); match('-'); throw internalError(); } script.putBackChar(); m_nCtx = 5; return new XmlToken(XmlToken.TOK_ELEMENT_START, iLine, ofInLine, script.getOffset() - ofInLine); } script.putBackChar(); pos = script.savePosition(); while(script.nextChar() != '<') ; script.putBackChar(); sData = script.subScript(pos).toString(); return new XmlToken(2, 4, 3, sData, sData, iLine, ofInLine, script.getOffset() - ofInLine); } catch(EOFException e) { logError(3, "XT-002", null, script.getLine(), script.getOffset(), 0); throw new CompilerException(); } catch(IOException e) { logError(3, "XT-003", new String[] { e.toString() }, script.getLine(), script.getOffset(), 0); } throw new CompilerException(); |
JavaCC学习笔记 -- by greatdino
[ 大恐龙 发表于 2007年5月 3日 18:34 ]
JavaCC是一个java语言分析器,就是按照“模版”,“装配”不同的语言分析程序的源代码。复杂语言的语法通常都是使用 BNF(巴科斯-诺尔范式,Backus-Naur Form)表示法或者其“近亲”― EBNF(扩展的 BNF)描述的。自动化工具可以使用那些描述(我将使用通用的术语 BNF来指代这两种变体)或与它们近似的描述来为你生成解析代码。
这个例子可以在javacc-4.0/doc/examples/SimpleExamples/Simple1.jj看到
......
PARSER_BEGIN(Simple1)
public class Simple1 {
public static void main(String args[]) throws ParseException {
Simple1 parser = new Simple1(System.in);
parser.Input();
}
}
PARSER_END(Simple1) void Input() : {} {
MatchedBraces() ("\n"|"\r")*
}
void MatchedBraces() : {} {
"{" [ MatchedBraces() ] "}" }
......
设置好javacc的bin目录后,在命令提示符下输入
javacc Simple1.jj
然后javacc就会为你生成下面几个java源代码文件
Simple1.java
Simple1TokenManager.java
Simple1Constants.java
SimpleCharStream.java
Token.java
TokenMgrError.java
JavaCC的输入文档是一个词法和语法的规范文件,其中也包括一些动作的描述,它的后缀应该是jj。
简而言之,一个jj文档由下面几个部分构成:
1、Options{}部分:这个部分对产生的语法分析器的特性进行说明,例如向前看的token的个数(用来解除冲突)。这一部分是可以省略的,因为每一个选项都有默认值,当我们没有对某个选项进行说明时,它就采用默认值。也可以把这些选项作为javacc命令的参数来启动javacc,可以达到同样的效果。
2、分析器类的声明:这个部分指定了分析器类的名字,以及其他类中成员的声明。这个部分是必须有的。这个部分的声明如下:
PARSER_BEGIN(classname)
Class classname {
……
}
PARSER_END(classname)
3、词法部分声明:这里面有四类:SKIP、TOKEN、SPECIAL_TOKEN、MORE。其中,SKIP用来说明被忽略的串,下面是一个例子:
SKIP {
“ “
|
“\n”
|
“\r”
}
TOKEN用来说明在词法层次上识别的token,下面是一个例子:
TOKEN {
<ID: (“a”-“z”|”A”-“Z”)+>
|
<NUM: (“0”-“9”)+>
}
这个部分是可以省略的。
4、在词法声明部分,以#开头的token只是在词法分析时使用,不能作为语法分析的输入,也就是说,它相对词法分析是局部的。
5、语法声明和动作代码:这一部分生成的代码会直接插入分析器类声明的结束括号之前。一般而言,语法中的每一个非终结符都对应一个函数,其中函数的形式如下:
Return_type function_name()
{变量声明和一些初始化的动作}
{上下文无关文法的右部分,其中每个组成部分的形式如下:
语法部分 {动作部分}
两个部分都可以省略。语法部分可以是一个字符串(简单的token常常可以这样处理),TOKEN中声明的token,或一个对某个非终结符对应的函数的调用。
}
以上说明的是jj文件的组成部分,下面再说明一下jj文件中语法的表示方法。Javacc中的语法表示吸收了UNIX中正规文法的一些记号,下面是一些:
[]:其中的内容是可选的。
+:前面的内容出现一次或多次。
-:前后构成的闭区间。
*: 前面的内容出现0次或多次。
?:前面的内容出现0次或一次。
~:后面的内容的补。
|:前面或后面。
():改变运算的优先级,把其中的内容作为一个整体。
Tomcat的UTF-8和配置SSL
[ 大恐龙 发表于 2007年4月28日 22:10 ]
存个档,免得每次去找。
<Context path="/roller" docBase="E:\MyWorks\Websites\4.5K\server\apache-tomcat\webapps\roller" debug="0">
<Resource name="jdbc/rollerdb" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&mysqlEncoding=utf8"
username="root"
password=""
maxActive="20"
maxIdle="3"
removeAbandoned="true"
maxWait="3000" />
<!-- If you want e-mail features, un-comment the section below -->
<!--
<Resource name="mail/Session" auth="Container"
type="javax.mail.Session"
mail.smtp.host="mailhost.example.com" />
-->
</Context>
server.xml
<Connector
port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"
URIEncoding="UTF-8" useBodyEncodingForURI="true" />
SSL:
<Connector port="8443" protocol="HTTP/1.1"
minSpareThreads="5" maxSpareThreads="75" SSLEnabled="true"
maxThreads="300" secure="true" acceptCount="100"
clientAuth="false" sslProtocol="TLS"
keystoreFile="C:\Documents and Settings\Administrator\.keystore" keystorePass="killkitty" />
Tags:
'
tomcat
'













![[Valid RSS]](http://www.w3cool.com//images/valid-rss.png)
![Validate my Atom 1.0 feed [Valid Atom 1.0]](http://www.w3cool.com//images/valid-atom.png)






[xxm] 于 10-07-13 发表: 现在是不是免费版本不能用了。 总提示我进行了不正确的封装....
[keke302] 于 10-07-02 发表: 做的不错,支持一个,中国人还是很牛滴 ...
[大恐龙
[大恐龙
[buno] 于 10-03-29 发表: 楼主快回来,你的http://speech.w3cool.com/swf/speech.js死链了~...
[123] 于 10-01-08 发表: 你的服务器端是自己开发的吗? 如果是用mut tts的话,就放开源吧。...
[淮安人生] 于 09-12-11 发表: 太ND了,不知如何使用,先看看~...
[武涛] 于 09-11-18 发表: 郁闷了我要免费试用拉,在哪排队...
[大恐龙
[ym] 于 09-10-18 发表: hi.你这个播放器的内容是怎么实现的?可否详细撰文介绍一下?...
[大恐龙
[大恐龙
[zi] 于 09-09-23 发表: 功能很不错,就是有的只读到一半就不给读了,一次最多能读多少字呢...
[ll] 于 09-09-23 发表: 可惜了 我测试俄语 不能朗读如果要是能的话就太好了...