一直以來,整合Apache HTTP Server和其他Java容器時,可能你最好的選擇就是mod_jk,但是mod_jk在Apache和外部Java服務(wù)器之間使用socket來進(jìn)行協(xié)議轉(zhuǎn)換,性能不能盡如人意。
正如我上一篇博客里說的,mod_java通過在apache嵌入的JVM中直接執(zhí)行Java來響應(yīng)HTTP請求,當(dāng)然是要快于mod_jk的。
但是缺點是,不是Servlet API(雖然實現(xiàn)Servlet API不是很難,但是工作量肯定很大的),優(yōu)點是,接口很清晰,很靈活,可以做到的事情也就很多。
那么如何開發(fā)一個基于mod_java的java handler呢?OK,假設(shè)你要在Apache里響應(yīng)所有/test/*上的請求.
你要做的是:
1)配置Apache啟用mod_java
2)在配置文件里加入你將要開發(fā)的Java Handler
想上面文件中的
3)在配置文件里告訴Apache 你的handler名字對應(yīng)的路徑
完成這些配置動作后,apache在收到到/test/*的請求后mod_java會call你的handler class的processRequest方法了。
RequestHandler接口如下定義,你的Handler都需要實現(xiàn)該接口:
正如你看到的很簡單的接口,但是ModJRequest就不簡單了,該接口代表你跟Apache通行的直接的接口,目前定義如下:
下面給個發(fā)送文件的例子:
下載:
mod_java_0.1
正如我上一篇博客里說的,mod_java通過在apache嵌入的JVM中直接執(zhí)行Java來響應(yīng)HTTP請求,當(dāng)然是要快于mod_jk的。
但是缺點是,不是Servlet API(雖然實現(xiàn)Servlet API不是很難,但是工作量肯定很大的),優(yōu)點是,接口很清晰,很靈活,可以做到的事情也就很多。
那么如何開發(fā)一個基于mod_java的java handler呢?OK,假設(shè)你要在Apache里響應(yīng)所有/test/*上的請求.
你要做的是:
1)配置Apache啟用mod_java
LoadModule java_module modules/mod_java.so
<mod_java your_main_class>
JVMLibrary D:\jdk6\jre\bin\server\jvm.dll
CurDir D:\apache-tomcat-6.0.14
ADDJVMOpt -Djava.class.path=D:\apache-tomcat-6.0.14\bin\bootstrap.jar;D:\dev\vccode\mod_java\mod_java.jar
ADDJVMOpt -Djava.library.path=D:\apache-tomcat-6.0.14\bin
ADDJVMOpt -Dcatalina.home=D:\apache-tomcat-6.0.14
ADDJVMOpt -Duser.dir=D:\apache-tomcat-6.0.14
ADDJVMParam start
ADDJVMStopParam stop
ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
</mod_java>
這里main_class是可選的,如果有,那么JVM啟動時自動調(diào)用main方法。<mod_java your_main_class>
JVMLibrary D:\jdk6\jre\bin\server\jvm.dll
CurDir D:\apache-tomcat-6.0.14
ADDJVMOpt -Djava.class.path=D:\apache-tomcat-6.0.14\bin\bootstrap.jar;D:\dev\vccode\mod_java\mod_java.jar
ADDJVMOpt -Djava.library.path=D:\apache-tomcat-6.0.14\bin
ADDJVMOpt -Dcatalina.home=D:\apache-tomcat-6.0.14
ADDJVMOpt -Duser.dir=D:\apache-tomcat-6.0.14
ADDJVMParam start
ADDJVMStopParam stop
ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
</mod_java>
2)在配置文件里加入你將要開發(fā)的Java Handler
想上面文件中的
ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
這里 javatest是handler名字,后面是你的實現(xiàn)的class3)在配置文件里告訴Apache 你的handler名字對應(yīng)的路徑
<Location /test>
SetHandler javatest
</Location>
SetHandler javatest
</Location>
完成這些配置動作后,apache在收到到/test/*的請求后mod_java會call你的handler class的processRequest方法了。
RequestHandler接口如下定義,你的Handler都需要實現(xiàn)該接口:
package com.yovn.apache.modj;
import java.io.IOException;
/**
* @author yovn
*
*/
public interface RequestHandler {
public abstract void processRequest(ModJRequest request) throws IOException,
ModJavaException;
}
import java.io.IOException;
/**
* @author yovn
*
*/
public interface RequestHandler {
public abstract void processRequest(ModJRequest request) throws IOException,
ModJavaException;
}
正如你看到的很簡單的接口,但是ModJRequest就不簡單了,該接口代表你跟Apache通行的直接的接口,目前定義如下:
package com.yovn.apache.modj;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* @author yovn
*
*/
public interface ModJRequest {
/**
*
* @param name
* @return the request header value of that name
*/
String getRequestHeader(String name);
/**
*
* @return similar as HttpServletRequest.getRequestURI()
*/
String getRequestURI();
/**
*
* @param name header name
* @param value header value
*/
void setResponseHeader(String name,String value);
/**
*
* @param type 'text/html' etc..
*/
void setContentType(String type);
/**
*
* @param code response code
*/
void setResponseCode(int code);
/**
*
* @return HTTP method
*/
String getMethod();
/**
* Give you the chance when you need push datas to client
* Also,you can use it to close a connection
* Note:
* HTTP Server may close the connection when it timeout automatically.
* When you pass use an invalid connection id to call some function , it will failed.
* @see com.yovn.apache.modj.ApacheModule#flushConnection(long, byte[], int, int)
* @see com.yovn.apache.modj.ApacheModule#closeConnection(long)
* @return the connection id for this request.
*/
long getConnectionId();
/**
* same as HttpServletRequest.getServletInputStream
* @return
*/
InputStream getRequestInputStream();
/**
* same as HttpServletResponse.getServletOutputStream
* @return
*/
OutputStream getResponseOutputStream();
/**
* You should not call the {@link #getRequestInputStream()} before you call this method this method.
* In other words, You should either use this method or {@link #getRequestInputStream()} to do read data from clients
* @return the direct byte buffer from native side
* @throws IOException
*/
ByteBuffer readTotalRequestBody()throws IOException;
/**
* Use apache's apr_send_fd to send a file.
* Before send file, you may need setup proper HTTP headers, such as 'Content-Disposition'
* @param fileName
* @return
* @throws IOException
*/
boolean sendFile(String fileName)throws IOException;
}
如你所看,基本可以做任何事情(如果還有你想要而沒有請一定要告訴我哦)!import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* @author yovn
*
*/
public interface ModJRequest {
/**
*
* @param name
* @return the request header value of that name
*/
String getRequestHeader(String name);
/**
*
* @return similar as HttpServletRequest.getRequestURI()
*/
String getRequestURI();
/**
*
* @param name header name
* @param value header value
*/
void setResponseHeader(String name,String value);
/**
*
* @param type 'text/html' etc..
*/
void setContentType(String type);
/**
*
* @param code response code
*/
void setResponseCode(int code);
/**
*
* @return HTTP method
*/
String getMethod();
/**
* Give you the chance when you need push datas to client
* Also,you can use it to close a connection
* Note:
* HTTP Server may close the connection when it timeout automatically.
* When you pass use an invalid connection id to call some function , it will failed.
* @see com.yovn.apache.modj.ApacheModule#flushConnection(long, byte[], int, int)
* @see com.yovn.apache.modj.ApacheModule#closeConnection(long)
* @return the connection id for this request.
*/
long getConnectionId();
/**
* same as HttpServletRequest.getServletInputStream
* @return
*/
InputStream getRequestInputStream();
/**
* same as HttpServletResponse.getServletOutputStream
* @return
*/
OutputStream getResponseOutputStream();
/**
* You should not call the {@link #getRequestInputStream()} before you call this method this method.
* In other words, You should either use this method or {@link #getRequestInputStream()} to do read data from clients
* @return the direct byte buffer from native side
* @throws IOException
*/
ByteBuffer readTotalRequestBody()throws IOException;
/**
* Use apache's apr_send_fd to send a file.
* Before send file, you may need setup proper HTTP headers, such as 'Content-Disposition'
* @param fileName
* @return
* @throws IOException
*/
boolean sendFile(String fileName)throws IOException;
}
下面給個發(fā)送文件的例子:
/**
*
*/
package com.yovn.apache.modj;
import java.io.File;
import java.io.IOException;
/**
* @author yovn
*
*/
public class HelloWorld implements RequestHandler {
/**
*
*/
public HelloWorld() {
// TODO Auto-generated constructor stub
}
/*
* (non-Javadoc)
*
* @see com.yovn.apache.modj.RequestHandler#processRequest(ModJRequest request)
*/
public void processRequest(ModJRequest request) throws IOException,
ModJavaException {
request.setContentType("APPLICATION/OCTET-STREAM");
File f=new File("D:\\cspace\\mod_java\\release\\ddd.bin");
request.setResponseHeader("Content-Disposition", "attachment;filename=\"ddd.bin\"");
request.setResponseHeader("Content-Length",f.length()+"");
request.sendFile(f.getCanonicalPath());
}
}
*
*/
package com.yovn.apache.modj;
import java.io.File;
import java.io.IOException;
/**
* @author yovn
*
*/
public class HelloWorld implements RequestHandler {
/**
*
*/
public HelloWorld() {
// TODO Auto-generated constructor stub
}
/*
* (non-Javadoc)
*
* @see com.yovn.apache.modj.RequestHandler#processRequest(ModJRequest request)
*/
public void processRequest(ModJRequest request) throws IOException,
ModJavaException {
request.setContentType("APPLICATION/OCTET-STREAM");
File f=new File("D:\\cspace\\mod_java\\release\\ddd.bin");
request.setResponseHeader("Content-Disposition", "attachment;filename=\"ddd.bin\"");
request.setResponseHeader("Content-Length",f.length()+"");
request.sendFile(f.getCanonicalPath());
}
}
下載:
mod_java_0.1