OSGI企业应用开发(十三)OSGI Web应用开发(二)
上篇文章介绍了OSGI Web应用的两种开发模式,并把Jetty应用服务器以Bundle的形式整合到Equinox容器中,已这种模式开发Web应用,所有的应用程序资源,例如Servlet、JSP、HTML页面等,都需要使用OSGI规范提供的HttpService服务进行注册,否则无法通过浏览器请求服务器端资源。
一、HttpService服务详解
接着我们就来了解一些HttpService服务,它实际上就是一个接口,具体的服务类由OSGI框架(例如Felix、Equinox等)实现,HttpService接口的定义如下:
org.osgi.service.http.HttpService
package org.osgi.service.http;
import java.util.Dictionary;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
public interface HttpService {
public void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context) throws ServletException, NamespaceException;
public void registerResources(String alias, String name, HttpContext context) throws NamespaceException;
public void unregister(String alias);
public HttpContext createDefaultHttpContext();
}
如上面代码所示,HttpService接口仅有4个方法,而且这些方法在实际开发中使用非常广泛,所以我们必须清楚的知道每个方法的作用,以及每个参数的含义。
registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context)
传统Java EE应用中Servlet只需要在web.xml文件中配置即可,但是使用將应用服务器整合到OSGI容器这种模式开发Web应用,Servlet实例必须被注册后才能被客户端访问。
HttpService接口的registerServlet()方法就是用于注册Servlet,参数含义如下:
第一个参数alias用于指定请求Servlet的URL模式,例如参数值为/login.do时,我们可以在浏览器中以http://localhost:8080/login.do的形式请求该Servlet,除此之外该参数还支持使用通配符,如/*.do,表示任意以.do结尾的请求都会被该Servlet处理。
第二个参数是一个Servlet实例,通常我们通过new关键字实例化一个Servlet对象即可。
大家在传统Java EE项目web.xml配置Servlet时,可以指定一些初始化参数,第三个参数作用就是为Servlet指定初始化参数。
第四个参数是一个HttpContext实例,他表示Http请求上下文,可以通过createDefaultHttpContext()方法创建一个默认的HttpContext实例,也可以將该参数指定为null。
registerResources(String alias, String name, HttpContext context)
该方法的作用和registerServlet()方法类似,只不过它用于注册静态的资源,例如CSS、图片、JavaScript文件等,使用方法也很简单,参数含义如下:
前面两个参数要结合起来使用,第一个参数表示客户端请求资源的URL模式,第二个参数表示资源映射在Bundle中的位置。
例如alias参数内容为”/js”,name参数值为”/WebContent/js”时,当客户端请求的URL为http://localhost:8080/js/index.js时,会返回Bundle中WebContent/js/index.js文件。
第三个参数和registerServlet()方法一样,不在赘述。
unregister()方法就比较简单了,当资源不需要被客户端请求时,可以调用该方法卸载资源;createDefaultHttpContext()方法用于创建默认的HttpContext实例。
二、Web应用开发实战
前面介绍了一些HttpService的理论基础,这对我们后面整合Spring MVC框架非常重要,接下来就介绍一下实际项目中何如使用HttpService的。
我们在前面文章中搭建的环境基础上进行演示,首先新建一个新的Plug-in Project,名称为com.csdn.osgi.test.web,完成后整个项目结构如下图所示:
需要注意的是,在新建com.csdn.osgi.test.web工程选择模版时,选择Hello OSGI Bundle,这样Eclipse会为我们生成一个Activator类,我们可以在该类中完成资源的注册操作,当然并不一定要使用工具生成,读者也可以自己注册一个Bundle生命周期类。
接下来我们就来新建一个Servlet,由于是演示用的,名称就叫TestServlet,代码如下:
com.csdn.osgi.web.servlet.TestServlet
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;
public class TestServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("Hello OSGI Web Appication!");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
}
如上面代码所示,我们重写了HttpServlet的doPost()和doGet()方法,在doPost()方法中,向客户端返回一段简单的文本信息,接下来还需要注册该Servlet。
修改Eclipse为com.csdn.osgi.test.web工程生成的Activator类,增加如下内容:
package com.csdn.osgi.test.web;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.servlet.Servlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import com.csdn.osgi.web.servlet.TestServlet;
public class Activator implements BundleActivator {
public void start(BundleContext bundleContext) throws Exception {
ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());
HttpService service = (HttpService) bundleContext.getService(serviceReference);
// 注册Servlet
Servlet testServlet = new TestServlet();
Dictionary<String, String> initparams = new Hashtable<String, String>();
initparams.put("load-on-startup", "1");
initparams.put("servlet-name", "testServlet");
service.registerServlet("/testServlet.do", testServlet, initparams, null);
}
public void stop(BundleContext bundleContext) throws Exception {
System.out.println("Goodbye World!!");
}
}
我们首先通过下面两行代码获取HttpService实例,如下:
ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());
HttpService service = (HttpService) bundleContext.getService(serviceReference);
接着new了一个TestServlet实例,然后调用HttpService实例的registerServlet()方法注册testServlet对象,请求的URL为/testServlet.do。
接下来我们可以重新启动OSGI容器,然后打开浏览器访问http://localhost:8080/testServlet.do,如下图所示,会发现浏览器中显示Servlet返回的文本内容:
接下来我们再来了解一下JSP的注册,首先在com.csdn.osgi.test.web工程中新建一个WebContent/jsp目录,然后在该目录中新建一个test.jsp文件,内容如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<title>首页面</title>
</head>
<body>
<h1>这是首页面!</h1>
</body>
</html>
在这种情况下,客户端是没办法访问到JSP页面的,Jetty服务器也不会把test.jsp文件作为JSP解析,这就需要我们对JSP进行注册,將客户端请求的URL映射到Bundle中的JSP文件。
我们依然在Activator 类的start()方法中对JSP进行注册,代码如下:
package com.csdn.osgi.test.web;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.servlet.Servlet;
import org.eclipse.equinox.jsp.jasper.JspServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import com.csdn.osgi.web.servlet.TestServlet;
public class Activator implements BundleActivator {
public void start(BundleContext bundleContext) throws Exception {
ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());
HttpService service = (HttpService) bundleContext.getService(serviceReference);
// 注册Servlet
Servlet testServlet = new TestServlet();
Dictionary<String, String> initparams = new Hashtable<String, String>();
initparams.put("load-on-startup", "1");
initparams.put("servlet-name", "testServlet");
service.registerServlet("/testServlet.do", testServlet, initparams, null);
Dictionary jspParams = new Hashtable<String, String>();
JspServlet jspServlet = new JspServlet(bundleContext.getBundle(), "/WebContent/jsp", "/jsp");
service.registerServlet("/jsp", jspServlet, jspParams, null);
}
public void stop(BundleContext bundleContext) throws Exception {
System.out.println("Goodbye World!!");
}
}
其中下面几行代码为新增:
Dictionary jspParams = new Hashtable<String, String>();
JspServlet jspServlet = new JspServlet(bundleContext.getBundle(), "/WebContent/jsp", "/jsp");
service.registerServlet("/jsp", jspServlet, jspParams, null);
注册JSP需要使用JspServlet类,该类的构造方法有三个参数,第一个参数为bundle实例,后面两个参数需要配合起来使用,第二个参数为请求URL映射到Bundle中JSP文件的路径,第三个参数为请求的URL模式,上面代码中创建的JspServlet实例的含义为:
將请求URL中的/jsp/*.jsp映射到Bundle中/WebConten/jsp目录下对应的JSP文件,例如请求URL为http://localhost:8080/jsp/test.jsp时,则返回Bundle中/WebConten/jsp/test.jsp文件内容。
注意:需要將org.eclipse.equinox.jsp.jasper这个Bundle添加到运行环境中。
接下来我们可以重新启动OSGI容器,然后打开浏览器访问http://localhost:8080/jsp/test.jsp,如下图所示,可以发现页面中显示对应JSP文件的内容:
最后就是图片资源的注册,也很简单,以图片资源为例,注册代码如下:
service.registerResources("/img", "/WebContent/img", null);
重新启动OSGI容器,在/WebContent/img目录下放一张test.png图片,浏览器中访问http://localhost:8080/img/test.png,如下图所示:
再来看一下com.csdn.osgi.test.web工程的项目结构,如下图所示:
到此为止,OSGI Web应用开发的内容就介绍的差不多了,下篇文章开始介绍在Web应用中整合Spring MVC框架,尽请期待!
OSGI企业应用开发(十三)OSGI Web应用开发(二)的更多相关文章
- amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules
amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...
- WEB前端开发--1(Web前端开发综述)
Web前端开发 Web--Web系统 前端--网页上为用户呈现的部分 开发--编写代码 1. 前端与后端 前端:网页上为用户呈现的部分 后端:与数据库进行交互,完成数据存取 2. 网站与 ...
- 《开发技巧》WEB APP开发调试技巧
前言 随着html5和nodejs的兴起.web APP越来越火,一套代码可以多平台使用.减少了很大的开发成本.很多APP中也集成了很多的html5页面,增强很高的应用体验.所以移动端页面也事关重要! ...
- go语言开发教程之web项目开发实战
Golang介绍Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性.谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件 ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】
<Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十七】
<Web 前端开发精华文章推荐>2013年第五期(总第十七期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...
- Web 前端开发人员和设计师必读文章推荐【系列二十八】
<Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十八】
<Web 前端开发精华文章推荐>2013年第六期(总第十八期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...
- Web 前端开发人员和设计师必读精华文章【系列二十六】
<Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】
<Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...
随机推荐
- 判断一个类是否为另一个类的实例 instanceof关键字和isAssignableFrom方法的区别
Which of the following is better? a instanceof B or B.class.isAssignableFrom(a.getClass()) The only ...
- PHP使用APC获取上传文件进度
今天发现使用PHP的APC也能获取上传文件的进度.这篇文章就说下如何做. 安装APC 首先安装APC的方法和其他PHP模块的方法没什么两样,网上能找出好多 phpinfo可以看到APC的默认配置有: ...
- macOS Java安装与配置
运行环境: macOS Hight Sierra(Version 10.13.6) Terminal(oh my zsh) 下载安装JRE Download URL 下载安装JDK Download ...
- List集合中的对象按照某个字段去重实现
package com.liying.banana.user; import java.util.ArrayList; import java.util.Comparator; import java ...
- MathType试用期到了如何继续用
1,卸载原来的MathType(不知道需不需要,其实删不删应该无所谓吧) 2,删除注册表中的一个值(不是默认,而是另外一个值) HKEY_CURRENT_USER\Software\Install O ...
- Tomcat学习总结(11)——Linux下的Tomcat安全优化
1.web.xml配置及修改: 站点默认主页: <welcome-file-list> <welcome-file>index.html</welcome-file> ...
- Golang 函数function
函数function Go函数不支持嵌套.重载和默认参数 但支持以下特性: 无需声明原型 不定长度变参 多返回值 命名返回值参数 匿名函数 闭包 定义函数使用关键字func,且左大括号不能另起一行 函 ...
- zoj 1151 Word Reversal(字符串操作模拟)
题目连接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1151 题目描述: For each list of words ...
- 【angular5项目积累总结】侧栏菜单 navmenu
View Code import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/co ...
- js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...