告别mod_jk,转向Apache Java Module(mod_java)

告别mod_jk,转向Apache Java Module(mod_java)
一直以来,整合Apache HTTP Server和其他Java容器时,可能你最好的选择就是mod_jk,但是mod_jk在Apache和外部Java服务器之间使用socket来进行协议转换,性能不能尽如人意。
正如我上一篇博客里说的,mod_java通过在apache嵌入的JVM中直接执行Java来响应HTTP请求,当然是要快于mod_jk的。

但是缺点是,不是Servlet API(虽然实现Servlet API不是很难,但是工作量肯定很大的),优点是,接口很清晰,很灵活,可以做到的事情也就很多。


那么如何开发一个基于mod_java的java handler呢?OK,假设你要在Apache里响应所有/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启动时自动调用main方法。

2)在配置文件里加入你将要开发的Java Handler
想上面文件中的
ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
这里 javatest是handler名字,后面是你的实现的class
3)在配置文件里告诉Apache 你的handler名字对应的路径
< Location  /test >
    SetHandler javatest
</ Location >

完成这些配置动作后,apache在收到到/test/*的请求后mod_java会call你的handler class的processRequest方法了。

RequestHandler接口如下定义,你的Handler都需要实现该接口:
package  com.yovn.apache.modj;

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;

}
如你所看,基本可以做任何事情(如果还有你想要而没有请一定要告诉我哦)!

下面给个发送文件的例子:

/**
 * 
 
*/
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

你可能感兴趣的:(告别mod_jk,转向Apache Java Module(mod_java))