IM即時(shí)聊天系統(tǒng)-Openfire爬坑之路三 插件1

插件結(jié)構(gòu)

myplugin /
 |-pom.xml <-Maven項(xiàng)目的插件描述/配置文件(允許您定義Maven使用的POM(項(xiàng)目對象模型)。
 |-plugin.xml <-插件定義文件
 |-readme.html <-插件的可選自述文件,它將顯示給最終用戶
 |-changelog.html <-插件的可選changelog文件,它將顯示給最終用戶
 |-logo_small.gif <-與插件關(guān)聯(lián)的可選小(16x16)圖標(biāo)(也可以是.png文件)
 |-logo_large.gif <-與插件關(guān)聯(lián)的可選大(32x32)圖標(biāo)(也可以是.png文件)
 |-src   
    |-classes / <-插件所需的資源(即屬性文件)
    |-database/ <-插件所需的可選數(shù)據(jù)庫架構(gòu)文件
    |-i18n / <-可選的i18n文件晾匠,以允許插件國際化。
    |-lib / <-插件需要的庫(JAR文件)
    |-java / <-這是包含插件應(yīng)用程序(.java文件)源的目錄梯刚,位于軟件包中
    |-web <-管理控制臺集成的資源(如果有)
        |-WEB-INF /
            |-web.xml <-包含編譯的JSP條目的生成的web.xml
            |-web-custom.xml <-自定義servlet的可選用戶定義的web.xml
        |-images/

plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <!-- 插件主類 -->
    <class>org.example.ExamplePlugin</class>

    <!--插件信息-->
    <name>Example Plugin</name>
    <description>This is an example plugin.</description>
    <author>阿倫</author>
    <version>1.0</version>
    <date>07/01/2006</date>
    <url>http://www.baidu.com</url>
    <minServerVersion>3.0.0</minServerVersion>
    <licenseType>gpl</licenseType>

    <!-- 管理控制臺條目 -->
    <adminconsole>
        <!-- 控制臺內(nèi)容 -->
    </adminconsole>
</plugin>
  • name -- 插件的名稱凉馆。
  • description -- 插件的描述。
  • author -- 插件的作者亡资。
  • version -- 插件的版本澜共。
  • date -- 插件發(fā)布的日期。日期必須采用MM / dd / yyyy格式锥腻,例如07/01/2006嗦董。
  • url -- 其中提供了有關(guān)插件的其他信息。
  • minServerVersion -- 運(yùn)行插件所需的Openfire的最低版本(受Openfire 2.1.2和更高版本支持)瘦黑。如果服務(wù)器版本小于要求的值京革,則不會啟動(dòng)插件。
  • beforeToServerVersion -- 可以運(yùn)行此插件的服務(wù)器版本幸斥,但不包括此版本匹摇。
  • minJavaVersion --插件需要運(yùn)行的最低Java規(guī)范版本。
  • databaseKey -- 如果插件需要它自己的數(shù)據(jù)庫表甲葬,則應(yīng)使用架構(gòu)鍵名稱(通常與插件名稱相同)來設(shè)置databaseKey元素廊勃。然后,應(yīng)將每個(gè)受支持?jǐn)?shù)據(jù)庫的數(shù)據(jù)庫模式文件放置在 插件的數(shù)據(jù)庫目錄中经窖。例如坡垫,給定鍵“ foo”,模式文件將被稱為“ foo_mysql.sql”钠至,“ foo_oracle.sql”等葛虐。我們建議您為表加上“ of”(openfire)前綴胎源,以避免與其他應(yīng)用程序發(fā)生沖突安裝在同一數(shù)據(jù)庫中棉钧。腳本應(yīng)使用鍵在ofVersion表中進(jìn)行輸入,以便可以跟蹤架構(gòu)版本信息涕蚤,例如:
INSERT INTO ofVersion (name, version) VALUES ('foo', 0);
  • databaseVersion -- 數(shù)據(jù)庫模式版本(如果定義了數(shù)據(jù)庫模式)宪卿。具有數(shù)據(jù)庫模式的新插件應(yīng)從版本0開始。如果插件的未來版本需要對該模式進(jìn)行更新万栅,則可以通過在數(shù)據(jù)庫/升級目錄中為每個(gè)版本號創(chuàng)建子目錄來定義這些更新佑钾。例如,目錄 database / upgrade / 1database / upgrade / 2將包含諸如“ foo_mysql.sql”和“ foo_oracle.sql”之類的腳本烦粒,這些腳本包含每個(gè)版本的相關(guān)數(shù)據(jù)庫更改休溶。每個(gè)腳本應(yīng)更新ofVersion表中的版本信息代赁,例如:
UPDATE ofVersion set version=1 where name='foo';
  • parentPlugin -- 父插件的名稱(對于“ foo.jar”插件,命名為“ foo”)兽掰。當(dāng)插件具有父插件時(shí)芭碍,將使用父插件的類加載器,而不是創(chuàng)建新的類加載器孽尽。這使插件可以更緊密地協(xié)同工作窖壕。沒有父插件,子插件將無法運(yùn)行杉女。
  • licenseType -- 指示插件受其管轄的許可協(xié)議瞻讽。有效值為:

“commercial”:該插件是根據(jù)商業(yè)許可協(xié)議發(fā)布的。
“gpl”:該插件是根據(jù)GNU公共許可證(GPL)發(fā)布的熏挎。
“apache”:該插件根據(jù)Apache許可發(fā)布速勇。
“internal”:該插件僅供組織內(nèi)部使用,不會重新分發(fā)坎拐。
“other”:該插件是根據(jù)許可協(xié)議發(fā)行的快集,該許可協(xié)議不屬于其他類別之一。許可協(xié)議應(yīng)該是插件自述文件中的詳細(xì)信息廉白。
如果未設(shè)置許可證類型个初,則假定為其他。

插件中可以存在幾個(gè)其他文件猴蹂,以向最終用戶提供其他信息(所有信息都放置在主插件目錄中):

  • readme.html -- 插件的可選自述文件院溺,將顯示給最終用戶。
  • changelog.html -- 插件的可選changelog文件磅轻,將顯示給最終用戶珍逸。
  • logo_small.png -- 與插件關(guān)聯(lián)的可選小(16x16)圖標(biāo)聋溜。它也可以是.gif文件谆膳。
  • logo_large.png -- 與插件關(guān)聯(lián)的可選大(32x32)圖標(biāo)。它也可以是.gif文件撮躁。

實(shí)現(xiàn) Plugin接口

插件實(shí)現(xiàn)Openfire APIPlugin 接口漱病,并且必須具有默認(rèn)(無參數(shù))構(gòu)造函數(shù)。Plugin接口具有用于初始化和銷毀??插件的方法把曼。

package org.example;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import java.io.File;
/**
 *實(shí)例
 */
public class ExamplePlugin implements Plugin {
    //初始插件回調(diào)
    public void initializePlugin(PluginManager manager, File pluginDirectory) {
        // 這里寫你的代碼
    }
  //銷毀插件回調(diào)
    public void destroyPlugin() {
        // 這里寫你的代碼
    }
}

修改管理控制臺

插件可以將標(biāo)簽杨帽,部分和頁面添加到管理控制臺。步驟:

  • 必須將<adminconsole />部分添加到 plugin.xml文件中嗤军。
  • 必須編譯JSP文件并將其放入插件的類路徑中注盈。一個(gè)web.xml中含有編譯JSP的servlet項(xiàng)文件必須放到插件目錄 web/。注意: Openfire構(gòu)建腳本可以幫助編譯JSP和創(chuàng)建web.xml叙赚。這在下面詳細(xì)說明老客。
  • JSP頁面所需的任何圖片都必須位于web / images / 目錄中僚饭。僅支持GIF和PNG圖像。

plugin.xml的<adminconsole />部分定義了管理控制臺框架中的其他選項(xiàng)卡胧砰,部分和條目浪慌。一個(gè)示例 plugin.xml文件可能如下所示:
plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <!-- Main plugin class -->
    <class>org.example.ExamplePlugin</class>
    <!-- Admin console entries -->
    <adminconsole>
        <tab id="mytab" name="Example" url="my-plugin-admin.jsp" description="Click to manage...">
            <sidebar id="mysidebar" name="My Plugin">
               <item id="my-plugin" name="My Plugin Admin"
                   url="my-plugin-admin.jsp"
                   description="Click to administer settings for my plugin"
                   order="4" />
               <item id="my-plugin" name="My Plugin Overview"
                   url="my-plugin-overview.jsp"
                   description="Click to have an Overview of Plugin usage"
                   order="2" />
            </sidebar>
        </tab>
    </adminconsole>
</plugin>

在此示例中,我們定義了一個(gè)新選項(xiàng)卡“ Example”朴则,一個(gè)側(cè)欄部分“ My Plugin”和兩個(gè)頁面:“ My Plugin Admin”和“ My Plugin Overview”权纤。我們已經(jīng)分別將my-plugin-admin.jsp和my-plugin-overview.jsp注冊 為頁面。
默認(rèn)情況下乌妒,選項(xiàng)卡汹想,側(cè)邊欄和頁面將按照定義順序顯示。但是撤蚊,您可以通過向每個(gè)元素添加“ order”屬性來定義顯式排序古掏。它的數(shù)值定義順序。如果未指定任何順序侦啸,則默認(rèn)值為0槽唾。在上面的示例中,使用此構(gòu)造對項(xiàng)目??進(jìn)行排序光涂。在管理控制臺中庞萍,“My Plugin Overview”頁面將在“My Plugin Admin”頁面之前顯示,因?yàn)槠洹皁rder”值較低忘闻。如果兩個(gè)項(xiàng)目都未定義'order'屬性钝计,則兩個(gè)頁面的顯示都將被反轉(zhuǎn)(因?yàn)樗?jīng)用來對以XML定義頁面的順序進(jìn)行排序)。
您可以使用自己的<adminconsole>定義中的現(xiàn)有id屬性值來覆蓋現(xiàn)有的tabs, sections和items 齐佳。

管理控制臺最佳做法

通過插件更改Openfire管理控制臺時(shí)私恬,需要考慮幾種最佳做法。一般主題是插件應(yīng)無縫集成:

  • 盡可能將其集成到現(xiàn)有的選項(xiàng)卡和側(cè)邊欄部分中炼吴,而不是自己創(chuàng)建本鸣。僅為非常重要的新功能創(chuàng)建新選項(xiàng)卡。
  • 標(biāo)簽硅蹦,側(cè)邊欄和項(xiàng)目名稱中請勿使用“插件”一詞荣德。例如,與其具有名為“ Gateway Plugin”的項(xiàng)目提针,不如將其稱為“ Gateway Settings”命爬。
  • 嘗試在您的自定義插件頁面中匹配現(xiàn)有管理控制臺的用戶界面。
  • 無需創(chuàng)建管理控制臺條目即可顯示插件元數(shù)據(jù)辐脖。相反,讓Openfire通知用戶有關(guān)已安裝哪些插件的信息并提供插件管理皆愉。

編寫管理控制臺頁面

Openfire使用Sitemesh 框架在管理控制臺中裝飾頁面嗜价。如下圖所示艇抠,將全局定義的裝飾器應(yīng)用于每個(gè)頁面以呈現(xiàn)最終輸出:

Sitemesh

創(chuàng)建適用于Sitemesh的頁面很容易。只需創(chuàng)建有效的HTML頁面久锥,然后使用元標(biāo)記將指令發(fā)送到Sitemesh家淤。呈現(xiàn)輸出時(shí),Sitemesh將使用您提供的說明來呈現(xiàn)裝飾器以及HTML頁面正文中的任何內(nèi)容瑟由⌒踔兀可以使用以下元標(biāo)記:

  • pageID -- 頁面的ID,必須與上述管理控制臺XML中的條目匹配歹苦。必須指定pageID或subPageID 青伤。
  • subPageID -- 子頁面的ID,必須與上述管理控制臺XML中的條目匹配殴瘦。子頁面用于與父頁面ID相關(guān)的管理操作狠角。例如,編輯或刪除特定組蚪腋。必須指定pageID或subPageID 丰歌。
  • extraParams(可選)--應(yīng)該傳遞給頁面的額外參數(shù)。例如屉凯,在要?jiǎng)h除組的頁面上立帖,它可能是該組的ID。參數(shù)必須經(jīng)過URL編碼悠砚。
  • decorator(可選)-- 覆蓋用于頁面的Sitemesh裝飾器厘惦。可以使用名為none的裝飾器哩簿,該裝飾器將在沒有裝飾器的情況下簡單地呈現(xiàn)頁面宵蕉。
   <html>
       <head>
           <title>My Plugin Page</title>
           <meta name="pageID" content="myPluginPage"/>
       </head>
       <body>
            Body here!
       </body>
   </html>

在插件中使用i18n

可以將您的插件翻譯成多種語言(i18n)。為此节榜,請使用以下過程:

  • 在插件的根目錄中創(chuàng)建一個(gè)“ i18n”目錄羡玛。
  • 使用%[plugin_name]%_i18n "_" language ".properties"命名約定添加每個(gè)資源文件,其中[plugin_name]是插件目錄的名稱宗苍。有關(guān)資源束的更多信息稼稿,請參見 翻譯指南
  • 將JSP文件中的字符串轉(zhuǎn)換為引用國際化密鑰讳窟。例如:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 ...
<fmt:message key="some.key.name" />
  • 使用LocaleUtils類將Java文件中的字符串國際化:
org.jivesoftware.util.LocaleUtils.getLocalizedString("some.key.name", "[plugin_name]");

使用$ {var}格式將plugin.xml文件中的字符串國際化:

<sidebar id="gateways" name="${plugin.sidebar.name}" description="${plugin.sidebar.description}">
<description>${plugin.description}</description>

使用Openfire構(gòu)建腳本
Openfire構(gòu)建腳本將幫助您構(gòu)建和開發(fā)插件让歼。它以以下格式查找插件開發(fā)目錄:
插件結(jié)構(gòu)

myplugin/
 |- plugin.xml      <- Plugin definition file
 |- readme.html     <- Optional readme file for plugin
 |- changelog.html  <- Optional changelog file for plugin
 |- logo_small.gif  <- Optional small (16x16) icon associated with the plugin (can also be a .png file)
 |- logo_large.gif  <- Optional large (32x32) icon associated with the plugin (can also be a .png file)
 |- classes/        <- Resources your plugin needs (i.e., a properties file)
 |- lib/            <- Libraries your plugin needs
 |- src/
     |- database    <- Optional database scripts for your plugin
     |- java        <- Java source code for your plugin
     |   |- com
     |       |- mycompany
     |           |- *.java
     |- web
         |- *.jsp      <- JSPs your plugin uses for the admin console
         |- images/    <- Any images your JSP pages need (optional)
         |- WEB-INF
             |- web.xml    <- Optional file where custom servlets can be registered

構(gòu)建腳本將編譯源文件和JSP,并創(chuàng)建有效的插件結(jié)構(gòu)和JAR文件丽啡。將您的插件目錄放在 源發(fā)行版的src / plugins目錄中谋右,然后使用ant插件來構(gòu)建您的插件。

您的插件在編譯過程中需要的所有JAR文件都應(yīng)放在lib目錄中补箍。在構(gòu)建過程中改执,還將這些JAR文件復(fù)制到插件的生成的lib目錄中啸蜜。

如果創(chuàng)建src / web / WEB-INF / web.xml文件,則在插件啟動(dòng)時(shí)將初始化在此注冊的所有servlet辈挂。從web.xml文件中僅接受servlet注冊和servlet映射衬横。注意:此功能是通過將您的自定義web.xml文件合并到JSP編譯過程生成的web.xml文件中來實(shí)現(xiàn)的。
***********=============現(xiàn)在推薦用maven構(gòu)建,下一章介紹===========************

實(shí)施您的插件

插件具有對Openfire API的完全訪問權(quán)限终蒂。這為插件可以完成的工作提供了極大的靈活性蜂林。但是,有幾個(gè)最常見的集成點(diǎn):

  1. 將插件注冊為Component拇泣。組件接收所有發(fā)往特定子域的數(shù)據(jù)包噪叙。例如, test_component.example.com挫酿。因此构眯,發(fā)送到 joe_component.example.com 的數(shù)據(jù)包將被傳遞到該組件。請注意早龟,定義為組件的子域與子域的DNS條目無關(guān)惫霸。套接字級別的所有XMPP路由都使用主服務(wù)器域(在上面的示例中為example.com)完成;子域僅用于XMPP服務(wù)器中的路由葱弟。

  2. 將插件注冊為IQHandler壹店。IQ處理程序以特定的元素名稱和名稱空間響應(yīng)IQ數(shù)據(jù)包。以下代碼段演示了如何注冊IQHandler:

  IQHandler myHandler = new MyIQHander();
  IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
  iqRouter.addHandler(myHandler);

  1. 將插件注冊為 PacketInterceptor以接收通過系統(tǒng)發(fā)送的所有數(shù)據(jù)包芝加,并有選擇地拒絕它們硅卢。例如,攔截器可以拒絕所有包含敏感詞的郵件或?qū)⑵錁?biāo)記為由管理員查看藏杖。

  2. 您可以使用JiveGlobals.getProperty(String)和JiveGlobals.setProperty(String将塑,String)方法將持久性插件設(shè)置存儲為Openfire屬性。通過實(shí)現(xiàn)org.jivesoftware.util.PropertyEventListener方法蝌麸,使插件成為屬性偵聽器点寥,以偵聽對其屬性的更改 。您可以使用PropertyEventDispatcher.addListener(PropertyEventListener)方法將插件注冊為偵聽器来吩。確保在插件的destroyPlugin()方法中將插件注冊為偵聽器敢辩。

Openfire管理員標(biāo)簽

Openfire提供了可以使用的有用的JSP標(biāo)簽。要在JSP頁面上啟用它們弟疆,只需在JSP頁面

<%@ taglib uri="admin" prefix="admin" %> 

頂部添加標(biāo)簽,包括:

<admin:ASN1DER value="${ASN.1 DER certificate as a byte[]}"/>
<!-- (自O(shè)penfire 4.0.0起)將在HTML表中顯示ASN.1 DER編碼的證書戚长。-->
<admin:FlashMessage/>
<!--(自O(shè)penfire 4.5.0起)將在呈現(xiàn)的頁面上最多顯示三個(gè)經(jīng)過適當(dāng)裝飾的會話屬性。
這些會話屬性的密鑰是由定義 FlashMessageTag.SUCCESS_MESSAGE_KEY怠苔,
WARNING_MESSAGE_KEY和 ERROR_MESSAGE_KEY同廉。這允許在頁面之間
導(dǎo)航時(shí)向用戶顯示消息。-->

CSRF保護(hù)

管理員頁面容易受到CSRF攻擊。Openfire提供了一些工具來幫助插件作者在其管理頁面上防御這些攻擊恤溶。啟用CSRF保護(hù):

  1. 將plugin.xml設(shè)置minServerVersion為4.5.0或更高版本乓诽,因?yàn)檫@是添加支持時(shí)的狀態(tài)帜羊。
  2. 將plugin.xml csrfProtectionEnabled設(shè)置true為啟用插件的CSRF保護(hù)咒程。這將;
    • 防范CSRF攻擊,除了 GET請求讼育,所有對管理頁面的請求
    • 使用鍵“ csrf”設(shè)置servlet請求屬性
  3. 確保GET請求不會修改任何設(shè)置或更改任何數(shù)據(jù)帐姻,因?yàn)槲礊镚ET請求啟用此保護(hù)
  4. 確保在管理頁面中提交的任何表單都有一個(gè)名為csrf的字段,該字段的值由請求屬性“ csrf”定義-例如:
<input name="csrf" value="<c:out value="${csrf}"/>" type="hidden">

如果檢測到CSRF攻擊奶段,將使用FlashMessageTag.ERROR_MESSAGE_KEY設(shè)置了session屬性以指示問題的狀態(tài)(使用簡單的HTTP GET請求)重新加載管理頁面-因此建議<admin:FlashMessage/>在JSP頁面的頂部包含饥瓷。
注意 :使用<c:out>標(biāo)簽或等效標(biāo)簽確保所有輸出正確轉(zhuǎn)義仍然很重要 。

插件常見問題

我可以將插件部署為目錄而不是JAR嗎痹籍?
不呢铆,所有插件都必須部署為JAR或WAR文件。當(dāng)插件不存在JAR或WAR時(shí)蹲缠,Openfire會假定該文件已被刪除棺克,并且用戶希望銷毀該插件,因此它也會刪除該目錄线定。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娜谊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子斤讥,更是在濱河造成了極大的恐慌纱皆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芭商,死亡現(xiàn)場離奇詭異派草,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铛楣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門近迁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛉艾,你說我怎么就攤上這事钳踊。” “怎么了勿侯?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵拓瞪,是天一觀的道長。 經(jīng)常有香客問我助琐,道長祭埂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蛆橡,結(jié)果婚禮上舌界,老公的妹妹穿的比我還像新娘。我一直安慰自己泰演,他們只是感情好呻拌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著睦焕,像睡著了一般藐握。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垃喊,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天猾普,我揣著相機(jī)與錄音,去河邊找鬼本谜。 笑死初家,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乌助。 我是一名探鬼主播溜在,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眷茁!你這毒婦竟也來了炕泳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤上祈,失蹤者是張志新(化名)和其女友劉穎培遵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體登刺,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡籽腕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纸俭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皇耗。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖揍很,靈堂內(nèi)的尸體忽然破棺而出郎楼,到底是詐尸還是另有隱情,我是刑警寧澤窒悔,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布呜袁,位于F島的核電站,受9級特大地震影響简珠,放射性物質(zhì)發(fā)生泄漏阶界。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膘融。 院中可真熱鬧芙粱,春花似錦、人聲如沸氧映。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屯耸。三九已至拐迁,卻和暖如春蹭劈,著一層夾襖步出監(jiān)牢的瞬間疗绣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工铺韧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留多矮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓哈打,卻偏偏與公主長得像塔逃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子料仗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • openfire服務(wù)器下載:https://www.igniterealtime.org/downloads/in...
    huangxiongbiao閱讀 580評論 0 0
  • JSPXCMS開發(fā)架構(gòu)介紹 V1 – 架構(gòu)概述 基本概述 配置文件目錄 /src/main/resources/...
    Java_Evan閱讀 4,389評論 0 0
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評論 0 11
  • IOC 控制反轉(zhuǎn)容器控制程序?qū)ο笾g的關(guān)系湾盗,而不是傳統(tǒng)實(shí)現(xiàn)中,有程序代碼之間控制立轧,又名依賴注入格粪。All 類的創(chuàng)建,...
    irckwk1閱讀 942評論 0 0
  • 青翠欲滴嬌艷氛改,潔白黃蕊撩眼帐萎, 羞靨花蕾欲放,芳香充溢人間胜卤!
    efab227f5376閱讀 123評論 2 18