日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【OSGI】4.实战OSGI-翻译助手项目02

發布時間:2025/3/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OSGI】4.实战OSGI-翻译助手项目02 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上次我們配置了運行Web項目所需要的Run Configuration環境,創建了客戶端入口插件TranslateClient模塊,下面我們來繼續完成客戶端模塊的程序。

因為是Web項目,我們要讓用戶通過瀏覽器去訪問我們的應用,所以我們要去寫一些Servlet來處理Http請求。

因為我們的工程是plug-in工程,不是傳統的Web project,所以不能直接創建一個Servlet(因為涉及到Web.xm的mapping映射和訪問路徑的設置),我們需要創建一個類,讓它去繼承HttpServlet來實現這個Servlet。

首先我們先在MANIFEST.MF文件中通過配置導入Servlet的相關包:

然后寫一個類繼承HttpServlet來實現這個Servlet:
package com.zyg.osgi.translateclient.servlet;import java.io.IOException;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.osgi.framework.BundleContext;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;public TranslateServiceServlet(BundleContext bundleContext) {// TODO Auto-generated constructor stub}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {} }我們先不寫其中的邏輯,我們先寫一個最后跳轉到的靜態頁面(html)。

一提到寫靜態頁面,那么問題來了,我們平時寫Web項目的時候,我們的靜態頁面都是寫在WebContext或者WebRoot文件夾下的:

那么我們這個項目并沒有這些目錄,那我們怎么去訪問我們的靜態頁面呢?用什么路徑去訪問呢?是不是感覺和我們之前的開發過程幾乎完全不一樣,有點不太習慣,不知道從哪里下手?

告訴大家,不!要!慌!雖然使用osgi進行Web開發和之前有很大不同,但是我們無非是把IDE工具中的Web project給我們自動做好的事情,我們手動去完成它而已~~~~

osgi的plug-in和普通web project的不同之處不外乎就是文件的組織夾結構上不太一樣。但是如果我們自己手動在工程中創建一個WebContext文件夾,然后里面創建META-INF、WEB-INF和一些jsp文件,形成和web project的靜態文件夾組織結構,我們再把這些文件和文件夾的路徑給需要加載這個靜態文件的程序(例如TomCat,當然我們這里不是TomCat),不就和之前的web project中的靜態文件被自動加載的原理一模一樣了嗎?所以我們可以這么做,只是需要我們多動一下手去實現它。(說白了,文件夾的擺放只是一個形式,重點在處理路徑的程序。我們掌握了處理路徑的程序之后,怎么使用我們不一定非要聽從第三方的規定,我們按照我們自己喜歡的方式來搞,豈不是更牛逼)

為了方便讀取,我們把我們的靜態文件直接放在類路徑下:


其中html文件的內容是:
<HTML> <HEAD> <TITLE>OSGi Dictionary Query Demo</TITLE> <meta http-equiv="Content-Type" content="text/html;charset=GBK" /> <script>function queryWord(){if(document.frmCalc.query_word.value==""){alert("必須輸入單詞");document.frmCalc.query_word.focus();return;}document.frmCalc.submit();} </script> </HEAD><BODY> <table style="width:100px;border:1px solid;height:100px"><form name="frmCalc" method="post" action="/servlet/translateServlet"><tr bgcolor="#C0C0C0"><td colspan="4" align="center">翻譯助手</td></tr><tr><td><input type="text" name="query_word" size="20"></td><td><input type=button name=btnSubmit value="查詢" οnclick="queryWord();"></td></tr></form> </table> </BODY> </HTML>
好的,我們將我們需要搜索的單詞提交上去,那么我們的后臺怎么接收呢?
我們之前寫Servlet的時候還需要在Web-INF的Web.xml中去注冊mapping映射,就像這樣:
<servlet><servlet-name>Add</servlet-name><servlet-class>cn.edu.hpu.test.add</servlet-class> </servlet><servlet-mapping><servlet-name>Add</servlet-name><url-pattern>/add</url-pattern> </servlet-mapping>但是我們的plug-in項目是沒有這種配置文件的,所以我們要來解決這個問題。

首先我們來剖析一下原來的Servlet的mapping映射原理,因為如果我們了解原理之后,我們可以模擬Web-INF的Web.xml中注冊mapping映射的原理,去給我們自己的Servlet去注冊映射。

開始剖析:
我們之前新建的Servlet我們如果不在Web.xml中做映射配置的話,我們的TomCat服務器是不知道這個Servlet的存在的,也就是我們訪問不到這個Servlet的,因為TomCat是通過讀取Web.xml文件來實例化Servlet到內存中去的。

我們沒有Web.xml文件的話怎么辦呢?我們來轉換一下思維:我們的Web.xml是要通過程序來讀取,然后把里面配置的Servlet給讀取到內存中去實例化。歸根結底還是需要程序來進行實例化,那么我們為什么不自己去進行實例化呢?我們不要Web.xml配置文件,我們手動在容器中去執行。

那么我們該怎么寫這種程序呢?又是一個問題。
如果大家分析過TomCat的源碼的話,應該會對這個有一些小小的思路,但是我們這里不會像TomCat這樣做的那么嚴格,我們簡單的來實現TomCat讀取配置和注冊這兩個部分的代碼,我們要把Servlet注冊到容器的服務中去。

我們將這些代碼在控制bundle聲明周期的Activator類中。
我們首先讓Activator首先實現osgi的ServiceListener接口,并重寫它的serviceChanged方法,我們才能夠通過它來得到jetty服務器給我們提供的各種http服務:
package com.zyg.osgi.translateclient;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;}public void stop(BundleContext bundleContext) throws Exception {Activator.context = null;}@Overridepublic void serviceChanged(ServiceEvent arg0) {// TODO Auto-generated method stub}}
我們在其中編寫獲取HttpService,注冊和注銷Servlet以及靜態資源的方法:
package com.zyg.osgi.translateclient;import javax.servlet.Servlet; import javax.servlet.ServletException;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpService; import org.osgi.service.http.NamespaceException;import com.zyg.osgi.translateclient.servlet.TranslateServiceServlet;public class Activator implements BundleActivator,ServiceListener {private static BundleContext context;private ServiceReference serviceReference;private Servlet servlet;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//在TranslateServiceServlet中創建一個構造方法,將bundleContext傳進去servlet=new TranslateServiceServlet(bundleContext);//注冊ServletregisterServlet();}public void stop(BundleContext bundleContext) throws Exception {//注銷Servlet等資源unRegisterServlet();serviceReference=null;Activator.context = null;}private void registerServlet() {if(null==serviceReference){//通過上下文獲取服務對象的“引用”(需要通過MANIFEST.MF引入org.osgi.service.http包)serviceReference=context.getServiceReference(HttpService.class);}if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注冊Servlet//四個參數分別是:(映射地址,Servlet類本身,Dictionary,上下文)httpService.registerServlet("/servlet/translateServlet", servlet, null, null);//注冊靜態資源(html等文件)位置//四個參數分別是(訪問地址,靜態文件所在路徑,上下文)httpService.registerResources("/page", "pages", null);System.out.println("翻譯助手服務已啟動成功,請通過/page/translate.html訪問!");} catch (ServletException e) {e.printStackTrace();} catch (NamespaceException e) {e.printStackTrace();}}}}private void unRegisterServlet() {if(null!=serviceReference){//得到http服務對象HttpService httpService=context.getService(serviceReference);if(httpService!=null){try {//注銷Servlet//四個參數分別是:映射地址httpService.unregister("/servlet/translateServlet");//注銷靜態資源(html等文件)位置//參數是訪問地址httpService.unregister("/page");System.out.println("翻譯助手服務已停用成功,謝謝使用!");} catch (Exception e) {e.printStackTrace();}}}}@Overridepublic void serviceChanged(ServiceEvent event) {// TODO Auto-generated method stubswitch (event.getType()) {case ServiceEvent.REGISTERED:registerServlet();break;case ServiceEvent.UNREGISTERING:unRegisterServlet();break;default:break;}} }
然后編寫我們的Servlet:
package com.zyg.osgi.translateclient.servlet;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.BundleContext; import org.osgi.framework.ServiceReference;import com.zyg.osgi.translateasslt.service.TranslateService;public class TranslateServiceServlet extends HttpServlet{private static final long serialVersionUID = 1L;private BundleContext context;public TranslateServiceServlet(BundleContext bundleContext) {this.context=bundleContext;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {//1、取得用戶傳來的英文單詞String queryWord=req.getParameter("query_word");//2、調用方法查找中文含義//獲取服務TranslateService translateService=null;ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());if(null!=serviceRef){translateService=(TranslateService)context.getService(serviceRef);}//3、返回結果給用戶resp.setContentType("text/html;charset=GBK");PrintWriter writer=resp.getWriter();if(translateService==null){writer.println("沒有開放翻譯服務!");writer.close();return;}String result=translateService.translate(queryWord);writer.println("結果"+result);writer.close();return;}}其中需要通過MANIFEST.MF引入com.zyg.osgi.translateasslt.service包。

同時,我們要在localTranslateAsslt和remoteTranslateAsslt這兩個插件的Activator中注冊相應的Service,這樣我們的TranslateClient就可以使用它們兩個提供的Service服務了:
package com.zyg.osgi.localtranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.localtranslateasslt.impls.TranslateServiceLocalImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceLocalImpl(), null);System.out.println("本地查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("本地查詢服務已停止!");Activator.context = null;} }
package com.zyg.osgi.remotetranslateasslt;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration;import com.zyg.osgi.remotetranslateasslt.impls.TranslateServiceRemoteImpl; import com.zyg.osgi.translateasslt.service.TranslateService;public class Activator implements BundleActivator {private static BundleContext context;private ServiceRegistration<TranslateService> sr;static BundleContext getContext() {return context;}public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext;//注冊Service服務sr=bundleContext.registerService(TranslateService.class, new TranslateServiceRemoteImpl(), null);System.out.println("遠程查詢服務已啟動!");}public void stop(BundleContext bundleContext) throws Exception {ServiceReference serviceRef=context.getServiceReference(TranslateService.class.getName());bundleContext.ungetService(serviceRef);System.out.println("遠程查詢服務已停止!");Activator.context = null;} }
好的,目前我們的工作基本完成!現在啟動osgi來看看我們的戰果把:

說明我們運行成功了,我們來進入瀏覽器訪問一下我們的靜態頁面:

這說明我們的Web項目起來了,并且靜態資源也訪問成功了。

然后我們來查詢一下單詞,看看我們的Servlet和Service是不是也注冊和實例化成功了:
我們先查本地服務的單詞“USA”的意思


于此同時控制臺端顯示:


我們再來查詢遠程服務的單詞“cat”的意思


于此同時控制臺端顯示:


出現這種原因的結果是我們兩個服務都開啟了,但是因為先注冊了Local服務后注冊了Remote服務,二者服務名相同,所以Remote服務把Local服務給覆蓋掉了,那么我們訪問本地Local服務的時候,就訪問不到相應的數據,訪問Remote服務卻可以。

大家可以在看控制臺出入ss,可以看到遠程和本地兩個服務都存在:

我們現在stop掉遠程服務:

因為通過熱部署,我們網站不需要重啟,我們直接訪問遠程服務:

發現遠程已經不能訪問,那么我們訪問本地的服務:


于此同時控制臺端顯示:

本地服務正常。
當然反過來只用遠程的服務也可以。
所以這體現了一種插件“即插即用”,拔除不影響其他組件的性能。

停止服務,關閉osgi的啟動,我們需要在控制臺中輸入close即可:


以上就是我們利用osgi完成的一個服務可插拔的Web項目。

上面是最原生的方式來注冊服務等,我們下次會介紹依賴注入的方式來對我們的這個Web項目進行改造。

轉載請注明出處:http://blog.csdn.net/acmman/article/details/50916011

總結

以上是生活随笔為你收集整理的【OSGI】4.实战OSGI-翻译助手项目02的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色涩视频在线观看 | 久久综合狠狠综合久久综合88 | 深夜福利久久 | 91精品国产一区二区三竹菊影视 | 久草剧场 | 日韩免费视频一区二区视频在线观看 | 日韩高清在线播放 | 欧性猛交ⅹxxx乱大交 | 成人乱码一区二区三区av | 丝袜视频在线观看 | 欧美成人乱码一区二区三区 | 日美av | 亚洲欧美日韩高清 | 成人综合区一区 | 在线播放黄色av | 牛牛热在线视频 | 尤物网站在线观看 | 人人妻人人藻人人爽欧美一区 | 日韩va视频| 免费看一级视频 | 四虎永久地址 | 色网网站 | 高中男男gay互囗交观看 | 色老头一区 | 激情四射av | 人人妻人人爽人人澡人人精品 | 欧美日韩免费一区二区 | 91女人18毛片水多国产 | 国产精品swag | 性综合网| 国产调教在线观看 | 九色视频91 | 屁股夹体温计调教play | 99精品欧美一区二区蜜桃免费 | 国产成人中文字幕 | 亚洲美女毛片 | 亚洲黄色在线免费观看 | 看国产毛片 | 官场艳妇疯狂性关系 | 无码国产69精品久久久久同性 | 国产成人8x视频一区二区 | 一区二区 中文字幕 | 五月婷婷七月丁香 | 素人av在线 | 日韩一二三四五区 | www.成人av | 制服.丝袜.亚洲.另类.中文 | 欧美大片xxx | 亚洲欧美另类在线观看 | 人妻在线日韩免费视频 | 美女啪啪无遮挡 | 6080亚洲精品一区二区 | 日日夜夜精 | 小说肉肉视频 | 精品人妻一区二区三区四区不卡 | 久久久久久久久久久福利 | 狠狠干天天 | 精品视频在线一区二区 | 国产男女爽爽爽 | 欧美日韩六区 | 日本在线网址 | 懂色a v| 亚洲av无码潮喷在线观看 | 欧美性生交xxxxx久久久缅北 | 色秀视频网 | 欧美体内she精高潮 日韩一区免费 | xxxx在线播放 | www天堂网| 亚洲专区第一页 | 国产在线高清视频 | 成人免费激情视频 | 免费看的一级片 | 亚洲福利在线播放 | 日韩图片一区 | 国产美女又黄又爽又色视频免费 | 男人的天堂视频在线观看 | 秋霞久久精品 | 性高湖久久久久久久久免费 | 午夜伦情 | 秋霞自拍 | n0659极腔濑亚美莉在线播放播放 | 97激情| 中国男人操女人 | 爆乳2把你榨干哦ova在线观看 | 91免费入口| 天堂网中文在线观看 | 欧美极品videos精品 | 欧美性生活在线视频 | 97国产资源 | 福利在线国产 | 国产精品二区一区二区aⅴ污介绍 | 欧美日韩一区二区三区在线播放 | 舐丝袜脚视频丨vk | 人妻偷人精品一区二区三区 | 色桃视频 | 亚洲无码乱码精品国产 | 日韩欧美高清片 | av福利在线播放 | 大尺度床戏视频 |