zoukankan      html  css  js  c++  java
  • 使用NetBeans6开发OSGi应用(4)——Servlet与Http服务[88250原创]

    转载请保留作者信息:

    作者:88250

    Bloghttp:/blog.csdn.net/DL88250

    MSN & Gmail & QQDL88250@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
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     */

    package cn.edu.ynu.sei.osgiservlet;

    import java.net.URL;
    import java.util.Hashtable;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.knopflerfish.service.log.LogRef;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.BundleException;
    import org.osgi.framework.ServiceEvent;
    import org.osgi.framework.ServiceListener;
    import org.osgi.framework.ServiceReference;
    import org.osgi.service.http.HttpContext;
    import org.osgi.service.http.HttpService;

    /**
     * OSGi activator for <code>InfoServlet</code>.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Mar 5, 2008
     */

    public class Activator implements BundleActivator {

        
    // This is my world
        static BundleContext bc;

        
    static LogRef log;

        
    static final String RES_ALIAS = "/";     // the http server root

        
    static final String RES_DIR = "/www";  // bundle resource directory 

        
    static final String SERVLET_ALIAS = "/servlet/firstservlet"; // a small servlet

        Hashtable registrations = 
    new Hashtable();

        
    public void start(BundleContext bc) throws BundleException {

            
    this.bc = bc;
            
    this.log = new LogRef(bc);

            ServiceListener listener = 
    new ServiceListener() {

                
    public void serviceChanged(ServiceEvent ev) {
                    ServiceReference sr = ev.getServiceReference();

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

            String filter = "(objectclass=" + HttpService.
    class.getName() + ")";

            
    try {
                bc.addServiceListener(listener, filter);

                ServiceReference[] srl = bc.getServiceReferences(
    null, filter);
                
    for (int i = 0; srl != null && i < srl.length; i++) {
                    listener.serviceChanged(
    new ServiceEvent(ServiceEvent.REGISTERED,
                                                             srl[i]));
                }
            } 
    catch (Exception e) {
                log.error("Failed to set up listener for http service", e);
            }
        }

        
    public void stop(BundleContext bc) throws BundleException {
        }

        
    void setRoot(ServiceReference sr) {

            
    if (registrations.containsKey(sr)) {
                
    return// already done
            }

            log.info("set root for " + sr);

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

            HttpContext context = 
    new HttpContext() {

                
    public boolean handleSecurity(HttpServletRequest request,
                                               HttpServletResponse response)
                        
    throws java.io.IOException {
                    
    return true;
                }

                
    public URL getResource(String name) {

                    
    // when registering the root, it seems
                    // like we get no separator before the file.
                    // Is that a bug?? Code below is a workaround      
                    if (name.startsWith(RES_DIR) &&
                            name.length() > RES_DIR.length() &&
                            '/' != name.charAt(RES_DIR.length())) {
                        name = RES_DIR + "/" + name.substring(RES_DIR.length());
                    }

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

                    
    // and send the plain file
                    URL url = getClass().getResource(name);

                    
    return url;
                }

                
    public String getMimeType(String reqEntry) {
                    
    return null// server decides type
                }
            };

            
    try {
                http.registerResources(RES_ALIAS, RES_DIR, context);
                http.registerServlet(SERVLET_ALIAS, 
    new InfoServlet(sr),
                                     
    new Hashtable(), context);

                registrations.put(sr, context);
            } 
    catch (Exception e) {
                log.error("Failed to register resource", e);
            }
        }

        
    void unsetRoot(ServiceReference sr) {
            
    if (!registrations.containsKey(sr)) {
                
    return// nothing to do
            }

            log.info("unset root for " + sr);

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

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


    /*
     * @(#)InfoServlet.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-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;

    /**
     * The first OSGi servlet application.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Mar 5, 2008
     
    */
    public class InfoServlet extends HttpServlet {

        ServiceReference httpSR;

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

        
    public void doPost(HttpServletRequest request,
                            HttpServletResponse response)
                
    throws ServletException,
                       IOException {
            
    // Handle just as GET
            doGet(request, response);
        }

        
    public void doGet(HttpServletRequest request,
                           HttpServletResponse response)
                
    throws ServletException, IOException {

            PrintWriter out 
    = response.getWriter();

            response.setContentType(
    "text/html");

            out.println(
    "<html>");
            out.println(
    "<head>");
            out.println(
    "<title>Demo</title>");
            out.println(
    "I am a simple servlet base running in OSGi :-)");
            out.println(
    "</head>");
            out.println(
    "<body>");

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

        }
    }

    还有一个简单的HTML页面(/www/index.html):
    <html>
        
    <head>
            
    <title>The First OSGi Servlet Appication</title>
        
    </head>
        
        
    <body>
            
    <h2>Test page for OSGi web server</h2>
            
    <p>
                Hello OSGi Servlet
            
    </p>
            
    <script type="text/javascript">
            document. writeln(
    "Test javascript!");
            
    </script>
        
    </body>
    </html>

    3. manifest.mf

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 
    2
    Bundle-Name: OSGi Servlet
    Bundle-SymbolicName: cn.edu.ynu.sei.osgiservlet
    Bundle-Version: 
    1.0.0.0
    Bundle-Category: example
    Bundle-Description: Demo HTTP servlet
    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是最好的选择。
  • 相关阅读:
    【CF-148E】Porcelain DP
    【CF-687C】The Values You Can Make 01背包变形
    【CF-269】B. Greenhouse Effect 最公共子序列
    【CF-1345】C.Hilbert's Hotel 数论
    【CF-607B】Zuma 经典区间DP
    【【模板】三分法】
    【CF-1355 E.Restorer Distance】三分,贪心
    【CF-1355 BCount Triangles】枚举
    【CF-1355 Sequence with Digits】
    触发器的类型有哪三种?
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470537.html
Copyright © 2011-2022 走看看