E81086713E446D36F62B2AA2A3502B5EB155

Java杂家

杂七杂八。。。一家之言

BlogJava 首页 新随笔 联系 聚合 管理
  141 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
一直以来,整合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

posted on 2008-06-19 15:38 DoubleH 阅读(4707) 评论(5)  编辑  收藏

Feedback

# re: 告别mod_jk,转向Apache Java Module(mod_java) 2008-06-19 17:34 po
先学习学习。观摩观摩。  回复  更多评论
  

# re: 告别mod_jk,转向Apache Java Module(mod_java) 2008-06-19 21:24 隔叶黄莺
通过 JVMLibrary D:\jdk6\jre\bin\server\jvm.dll
这种配置,看得出来 mod_java 能在 Apache 中把 Tomcat 作为一个子模块来启动,Apache 和 Tomcat 在同一个进程中,避免了 mod_jk 那样的 Apache 和 Tomcat 通过端口转发的进程间通信。  回复  更多评论
  

# re: 告别mod_jk,转向Apache Java Module(mod_java) 2008-06-20 10:04 demo
请这种情况下如何做到负载均衡和集群技术实现。  回复  更多评论
  

# re: 告别mod_jk,转向Apache Java Module(mod_java) 2008-06-20 12:35 DoubleH
@demo
如果直接在Apache里能获得更好的性能,为什么不直接Apache集群?  回复  更多评论
  

# re: 告别mod_jk,转向Apache Java Module(mod_java)[未登录] 2008-12-26 13:48 过客
如果使用现成框架:JSF
应该如何使用mod_java???????  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: