使用NetBeans6开发OSGi应用(4)——Servlet与Http服务[88250原创]

转载请保留作者信息:

作者:88250

Blog:http:/blog.csdn.net/DL88250

MSN & Gmail & QQ:DL88250@gmail.com


摘要

上一次,我们分析了KF(Knopflerfish)框架的设计,实践了基于OSGi的应用程序框架的设计。这一讲,我们将基于KF实现的OSGi规范 Http Service,做一个简单的Servlet结合HTML/Javascript的实践。

关于基于OSGi的Web开发

在开始前,我们先看一下一些关于OSGi在Web应用方面的尝试。

开发Web应用,最重要的要属Web Server了(亦或Application Server)。在Server的厂商中 IBM、BEA和JBoss应用服务器采用OSGi,虽然目前我们的主要任务的做应用,但是可以了解这些最基本的东西。

好了,简要说一下OSGi在Web上的开发方式:

1. 将Web Server作为Bundle插入OSGi

目前,Apache Jetty可以做到。使用Spring DM(Spring-OSGi)的话,Tomcat的OSGi整合在未来应该也可以做。参考 这个

2. 在Web Server内使用OSGi的Bundle

在Web容器里使用Spring DM(Spring-OSGi)可以做到。

目前来说

在Java的Web开发上,Spring Framework是首选,但是如果应用是以OSGi作为底层的话,情况就不同了:

1. 使用Spring,从Web应用开发的角度来说,视图/持久化/事务管理方便,可结合其他框架或技术的选择余地大
2. 使用OSGi,从系统整体开发角度来说,扩展性、维护性超好,系统整体结构清晰,可以把商业/控制逻辑做到很优良的组件话
3. 结合这两者使用的话(Spring DM),支持的扩展有限且技术相当复杂,得不偿失

所以,权衡后,我更偏向与直接使用OSGi来做Web应用,因为现在手头的一个项目只是运用例简单的HTML,AJAX与Servlet。

让我们简单实践一下!

准备

上一次 :-)

开工:

1. 创建工程

打开NB6,创建一个普通Java应用工程——OSGiServlet:



注意,www文件夹是存放HTML源文件的地方,要直接放在src文件夹下。然后要导入3个Jar libs:
http_all-2.0.0.jar: OSGi 的 http service实现
knopflerfish-osgi.jar: 基本OSGi实现
servlet-api.jar: Sun的servlet实现

2.编写Activator与Servlet类

/*
*@(#)Activator.java
*
*Thisprogramisfreesoftware;youcanredistributeitand/ormodify
*itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby
*theFreeSoftwareFoundation;eitherversion3oftheLicense,or
*(atyouroption)anylaterversion.
*
*Thisprogramisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
*GNULibraryGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
*alongwiththisprogram;ifnot,writetotheFreeSoftware
*Foundation,Inc.,59TemplePlace-Suite330,Boston,MA02111-1307,USA.
*/

packagecn.edu.ynu.sei.osgiservlet;

importjava.net.URL;
importjava.util.Hashtable;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.knopflerfish.service.log.LogRef;
importorg.osgi.framework.BundleActivator;
importorg.osgi.framework.BundleContext;
importorg.osgi.framework.BundleException;
importorg.osgi.framework.ServiceEvent;
importorg.osgi.framework.ServiceListener;
importorg.osgi.framework.ServiceReference;
importorg.osgi.service.http.HttpContext;
importorg.osgi.service.http.HttpService;

/**
*OSGiactivatorfor<code>InfoServlet</code>.
*
@author88250
*
@version1.0.0.0,Mar5,2008
*/

publicclassActivatorimplementsBundleActivator{

//Thisismyworld
staticBundleContextbc;

staticLogReflog;

staticfinalStringRES_ALIAS="/";//thehttpserverroot

staticfinalStringRES_DIR="/www";//bundleresourcedirectory

staticfinalStringSERVLET_ALIAS="/servlet/firstservlet";//asmallservlet

Hashtableregistrations=
newHashtable();

publicvoidstart(BundleContextbc)throwsBundleException{

this.bc=bc;
this.log=newLogRef(bc);

ServiceListenerlistener=
newServiceListener(){

publicvoidserviceChanged(ServiceEventev){
ServiceReferencesr=ev.getServiceReference();

switch(ev.getType()){
caseServiceEvent.REGISTERED:
setRoot(sr);
break;
caseServiceEvent.UNREGISTERING:
unsetRoot(sr);
break;
}
}
};

Stringfilter="(objectclass="+HttpService.
class.getName()+")";

try{
bc.addServiceListener(listener,filter);

ServiceReference[]srl=bc.getServiceReferences(
null,filter);
for(inti=0;srl!=null&&i<srl.length;i++){
listener.serviceChanged(
newServiceEvent(ServiceEvent.REGISTERED,
srl[i]));
}
}
catch(Exceptione){
log.error("Failedtosetuplistenerforhttpservice",e);
}
}

publicvoidstop(BundleContextbc)throwsBundleException{
}

voidsetRoot(ServiceReferencesr){

if(registrations.containsKey(sr)){
return;//alreadydone
}

log.info("setrootfor"+sr);

HttpServicehttp=(HttpService)bc.getService(sr);

HttpContextcontext=
newHttpContext(){

publicbooleanhandleSecurity(HttpServletRequestrequest,
HttpServletResponseresponse)
throwsjava.io.IOException{
returntrue;
}

publicURLgetResource(Stringname){

//whenregisteringtheroot,itseems
//likewegetnoseparatorbeforethefile.
//Isthatabug??Codebelowisaworkaround
if(name.startsWith(RES_DIR)&&
name.length()>RES_DIR.length()&&
'/'!=name.charAt(RES_DIR.length())){
name=RES_DIR+"/"+name.substring(RES_DIR.length());
}

//defaulttoindex.html
if(name.equals(RES_DIR)){
name="/www/index.html";
}

//andsendtheplainfile
URLurl=getClass().getResource(name);

returnurl;
}

publicStringgetMimeType(StringreqEntry){
returnnull;//serverdecidestype
}
};

try{
http.registerResources(RES_ALIAS,RES_DIR,context);
http.registerServlet(SERVLET_ALIAS,
newInfoServlet(sr),
newHashtable(),context);

registrations.put(sr,context);
}
catch(Exceptione){
log.error("Failedtoregisterresource",e);
}
}

voidunsetRoot(ServiceReferencesr){
if(!registrations.containsKey(sr)){
return;//nothingtodo
}

log.info("unsetrootfor"+sr);

HttpServicehttp=(HttpService)bc.getService(sr);

if(http!=null){
http.unregister(RES_ALIAS);
http.unregister(SERVLET_ALIAS);
bc.ungetService(sr);
}
registrations.remove(sr);
}
}


/*
*@(#)InfoServlet.java
*
*Thisprogramisfreesoftware;youcanredistributeitand/ormodify
*itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby
*theFreeSoftwareFoundation;eitherversion3oftheLicense,or
*(atyouroption)anylaterversion.
*
*Thisprogramisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
*GNULibraryGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
*alongwiththisprogram;ifnot,writetotheFreeSoftware
*Foundation,Inc.,59TemplePlace-Suite330,Boston,MA02111-1307,USA.
*/
package cn.edu.ynu.sei.osgiservlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.framework.ServiceReference;

/**
*ThefirstOSGiservletapplication.
*
@author 88250
*
@version 1.0.0.0,Mar5,2008
*/
public class InfoServlet extends HttpServlet{

ServiceReferencehttpSR;

public InfoServlet(ServiceReferencehttpSR){
this .httpSR = httpSR;
}

public void doPost(HttpServletRequestrequest,
HttpServletResponseresponse)
throws ServletException,
IOException{
// HandlejustasGET
doGet(request,response);
}

public void doGet(HttpServletRequestrequest,
HttpServletResponseresponse)
throws ServletException,IOException{

PrintWriterout
= response.getWriter();

response.setContentType(
" text/html " );

out.println(
" <html> " );
out.println(
" <head> " );
out.println(
" <title>Demo</title> " );
out.println(
" IamasimpleservletbaserunninginOSGi:-) " );
out.println(
" </head> " );
out.println(
" <body> " );

try {
}
catch (Exceptione){
out.println(
" <pre> " );
e.printStackTrace(out);
out.println(
" </pre> " );
}

}
}

还有一个简单的HTML页面(/www/index.html):
< html >
< head >
< title > TheFirstOSGiServletAppication </ title >
</ head >

< body >
< h2 > TestpageforOSGiwebserver </ h2 >
< p >
HelloOSGiServlet
</ p >
< script type ="text/javascript" >
document.writeln(
" Testjavascript! " );
</ script >
</ body >
</ html >

3. manifest.mf

Manifest-Version: 1.0
Bundle-ManifestVersion:
2
Bundle-Name:OSGiServlet
Bundle-SymbolicName:cn.edu.ynu.sei.osgiservlet
Bundle-Version:
1.0.0.0
Bundle-Category:example
Bundle-Description:DemoHTTPservlet
Bundle-Activator:cn.edu.ynu.sei.osgiservlet.Activator
Import-Package:javax.servlet
,
javax.servlet.http
,
org.knopflerfish.service.log
,
org.osgi.framework
,
org.osgi.service.http

4. 测试

编译这个Bundle,安装它到KF里并运行之,结果如下图:

以地址 http://localhost:8080/servlet/firstservlet 访问我们的Servlet:


总结


本次,我们基于OSGi做了一个简单的HTTP/Servlet 容器,可以满足简单的应用。这样,我们可以把我们的应用统一在一个框架里,简化了很多技术细节。但是,做企业应用的话这样是远远不够的,我们也不是太有可能基于OSGi构建一个自己的Application Server,所以,只要容器支持OSGi,结合Spring DM是最好的选择。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值