重寫到邊緣–充分利用它! 在GlassFish上!

現代應用程序開發的一個重要主題是重寫。 自從Java Server Faces引入和Java EE 6中新的輕量級編程模型以來,您一直在努力使用漂亮,簡單,可添加書簽的URL。 PrettyFaces很久以來就一直存在,即使它在3.3.3版本中可以說是成熟的,我也不敢相信。

主要是因為我必須在xml中配置它。 如果您曾經做過JSF項目,那么您就會知道這是您稍后要做的事情。 或永遠不會。 最后一個選項是我看到的很多東西。 重寫將改變這一點。 程序化,易于使用和高度可定制的。 正是我想要的。

入門

從其中一個RedHat家伙那里獲得的東西入門非常容易。 啟動NetBeans,創建一個新的基于Maven的Webapp,將JSF和Primefaces添加到混合中并在GlassFish上運行。 向應用程序添加重寫魔術的第一步是向項目添加重寫依賴項。

<dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-servlet</artifactId><version>1.1.0.Final</version></dependency>

這還不夠,因為我將它與JSF一起使用,您還需要jsf-integration。

<dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-integration-faces</artifactId><version>1.1.0.Final</version></dependency>

接下來實現您自己的ConfigurationProvider。 這是發生大多數魔術的核心部分。現在我們將其稱為TricksProvider,我們還將擴展抽象的HttpConfigurationProvider。 一個簡單的第一個版本如下所示:

public class TricksProvider  extends HttpConfigurationProvider
{@Overridepublic int priority(){return 10;}@Overridepublic Configuration getConfiguration(final ServletContext context){return ConfigurationBuilder.begin().addRule(Join.path("/").to("/welcomePrimefaces.xhtml"));}
}

現在,您必須注冊您的ConfigurationProvider。 為此,您可以在應用程序/ META-INF / services /文件夾中添加一個名為org.ocpsoft.rewrite.config.ConfigurationProvider的簡單文本文件。 向其添加ConfigurationProvider實現的標準名稱,即可完成操作。 如果您啟動應用程序。

重寫基礎

復制上述提供程序時,您隱式添加了第一個重寫規則。 通過請求http:// host:8080 / yourapp /,您將直接轉到NetBeans生成的Primefaces歡迎頁面。 所有規則都基于相同的原則。 每個規則都由一個條件和一個運算組成。 類似“如果發生X,則執行Y”。 重寫知道兩種不同的規則。 一些預配置的(加入)以“ addRule()”開頭,而流暢的接口以defineRule()開頭。 這有點令人困惑,因為下一個主要版本將棄用defineRule()并將其重命名為addRule()。 因此,您發現的大多數示例(尤其是最新主干中的測試用例)都無法在1.1.0.Final中使用。 重寫知道兩個不同的方向。 入站和出站。 入站很有可能像您知道的每個重寫引擎(例如mod_rewrite)一樣工作。 請求到達并被轉發或重定向到規則中定義的資源。 出站方向幾乎沒有。 它基本上在HttpServletRequest的encodeURL()方法中具有一個鉤子,并重寫您頁面中的鏈接(如果它們完全是在encodeURL的幫助下呈現的)。 JSF開箱即用。 如果您打算將其與JSP一起使用,則必須確保自己調用它。

用一些魔法將.html轉發到.xhtml

讓我們看一下您可以用重寫做的一些事情。 首先,我們將以下內容添加到TricksProvider中:

.defineRule()
.when(Direction.isInbound()
.and(Path.matches("{name}.html").where("name").matches("[a-zA-Z/]+")))
.perform(Forward.to("{name}.xhtml"));

這是一條規則,用于檢查入站請求,并檢查所有與正則表達式模式[a-zA-Z /] +確認的補丁匹配{name} .html,并將其轉發到{name} .xhtml文件。

如果執行此規則,則對http:// host:8080 / yourapp / something.html的所有請求最終都將轉發到something.xhtml。 現在,您的用戶將不再知道您在下面使用的是花哨的JSF內容,并認為您正在使用html :)如果請求的URL與正則表達式不匹配,例如類似http:// host:8080 / yourapp / something123.html根本不會轉發,如果您的應用程序中不存在something123.html,您最終將收到404錯誤。

改寫出站鏈接

相反,您還可以添加以下規則:

.defineRule()
.when(Path.matches("test.xhtml")
.and(Direction.isOutbound()))
.perform(Substitute.with("test.html"))

你想像這是在做什么,對嗎? 如果您的facelet包含以下內容:

<h:outputLink value="test.xhtml">Normal Test</h:outputLink>

呈現給用戶的鏈接將被重寫為test.html。 這是您永遠需要的出站鏈接的最基本操作。 大多數魔術都發生在入站鏈接上。 看到encodeURL()掛鉤的作用范圍非常有限,這并不讓人感到意外。

OutputBuffer

重寫中最令人驚訝的東西稱為OutputBuffer。 至少直到我們正在使用的發行版為止。 它會在2.0中重命名,但現在讓我們簡單地看一下您可以做什么。 OutputBuffer是您對響應的了解。 在響應真正到達客戶瀏覽器之前,您想對響應做什么。 考慮轉換標記? 轉換CSS? 甚至GZIP壓縮? 太好了,這正是您所能做的。 讓我們實現一個簡單的ZipOutputBuffer

public class ZipOutputBuffer implements OutputBuffer {private final static Logger LOGGER = Logger.getLogger(ZipOutputBuffer.class.getName());@Overridepublic InputStream execute(InputStream input) {String contents = Streams.toString(input);LOGGER.log(Level.FINER, "Content {0} Length {1}", new Object[]{contents, contents.getBytes().length});byte[] compressed = compress(contents);LOGGER.log(Level.FINER, "Length: {0}", compressed.length);return new ByteArrayInputStream(compressed);}public static byte[] compress(String string) {ByteArrayOutputStream os = new ByteArrayOutputStream(string.length());byte[] compressed = null;try {try (GZIPOutputStream gos = new GZIPOutputStream(os)) {gos.write(string.getBytes());} compressed = os.toByteArray();os.close();} catch (IOException iox) {LOGGER.log(Level.SEVERE, "Compression Failed: ", iox);}return compressed;}
}

如您所見,我在弄亂一些流,并使用java.util.zip.GZIPOutputStream縮小通過此方法接收的流。 接下來,我們必須將相關規則添加到TricksProvider中:

.defineRule()
.when(Path.matches("/gziptest").and(Direction.isInbound()))
.perform(Forward.to("test.xhtml")
.and(Response.withOutputBufferedBy(new ZipOutputBuffer())
.and(Response.addHeader("Content-Encoding", "gzip"))
.and(Response.addHeader("Content-Type", "text/html"))))

入站規則(我們不愿意在此處重寫頁面中的鏈接..因此必須入站),該規則將ZipOutputBuffer添加到Response中。 還要注意額外的響應標頭(兩個),除非您想讓瀏覽器抱怨我混在一起的內容:)就是這樣。 現在,請求http:// host:8080 / yourapp / gziptest提供了具有GZIP壓縮功能的te??st.xhtml。 那是2,6KB和1.23 KB! 不到尺寸的一半! 使用流和byte []并不是很方便。 而且我不確定這是否可以在較大的頁面大小上使用內存碎片,但是如果您沒有壓縮過濾器或者只需要壓縮應用程序的單個部分,這是一個簡單的解決方法。

通過重寫增強安全性

但這還不是您能做的:您還可以通過重寫來增強安全性。 林肯發表了關于用重寫保護您的應用程序的精彩文章。 關于如何使用此功能,有很多可能的示例。 我想到了一個用例,其中不想使用歡迎文件功能,而是希望單獨分派用戶。 在執行此操作時,我還將檢查他們的路徑,并檢查他們輸入的內容是否惡意。 您可以使用.matches()條件或使用自定義約束來執行此操作。 將以下內容添加到TricksProvider中:

Constraint<String> selectedCharacters = new Constraint<String>() {@Overridepublic boolean isSatisfiedBy(Rewrite event,EvaluationContext context, String value) {return value.matches("[a-zA-Z/]+");}};

并定義以下規則:

.defineRule()
.when(Direction.isInbound()
.and(Path.matches("{path}").where("path").matches("^(.+)/$")
.and(Path.captureIn("checkChar").where("checkChar").constrainedBy(selectedCharacters))))
.perform(Redirect.permanent(context.getContextPath() + "{path}index.html"))

另一個入站修改。 檢查路徑是否具有文件夾模式,并將其捕獲到根據自定義約束進行檢查的變量中。 大! 現在,您已經有了保存和輕松轉發的機制。 現在,所有http:// host:8080 / yourapp / folder /請求都被重寫為http:// host:8080 / yourapp / index.html。 如果您從上方查看其他規則,那么.html將被轉發到.xhtml……,您就完成了!

底線

我非常喜歡重寫。 與配置prettyfaces的xml文件相比,這感覺要容易得多,在使用林肯和Christian的第一步中,我真的很享受Lincoln和Christian的支持。 我很好奇2.0即將推出的產品,我希望我能為規則配置獲得更多調試輸出,以便了解正在發生的事情。 默認值是空,并且找到具有工作規則的條件的正確組合可能非常棘手。 尋找完整的資源? 在github上找到它們 。 很高興閱讀您的經歷。

GlassFish部分在哪里?

哦耶。 我在標題中提到了吧? 那應該更像是默認值。 我正在使用最新的GlassFish 3.1.2.2運行所有程序,因此可以確保它可以正常運行。 NetBeans目前為7.2 ,如果尚未嘗試,則應嘗試一下。 我沒有遇到任何與GlassFish相關的問題,我很高興在此強調這一點。 做得好! 最后一句話:在瘋狂地實現OutputBuffer之前,請看一下您最喜歡的應用服務器所擁有的庫存。 GlassFish已經了解GZIP壓縮 ,因此可以將其打開! 在這里實施之前,請三思而后行是一個好主意。

參考: 重寫邊緣-充分利用它! 在GlassFish上! 來自我們的JCG合作伙伴 Markus Eisele在Java的企業軟件開發博客中。


翻譯自: https://www.javacodegeeks.com/2012/08/rewrite-to-edge-getting-most-out-of-it.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371566.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php yii框架路由,yii框架路由配置

首先要在服務器配置(httpd.conf)中開啟重寫模塊#開啟重寫模塊&#xff0c;將其前面的#去掉LoadModule rewrite_module modules/mod_rewrite.so#Directory中允許覆蓋開啟## Possible values for the Options directive are "None", "All",# or any combinat…

前端面試總結二

一、響應式和自適應的區別&#xff1a; 聯系(相同點)&#xff1a; 響應式設計(responsive design)和自適應設計(adaptive design)都是用來解決網頁在不同分辨率的屏幕和設備上展示的一項技術(或者說一種方法)。 區別&#xff1a; 響應式設計&#xff1a;通過CSS Media Queries(…

“Spring入門”教程系列

大家好&#xff0c; 我很高興向您介紹“Spring入門”教程系列&#xff01; 這是一系列文章&#xff0c;最初由我們的JCG合作伙伴 Michal Vrtiak在vrtoonjava博客上撰寫 。 本系列中將逐步創建一個時間表管理應用程序&#xff0c;并且每個教程都在前一個教程的基礎上構建。 處…

【看番雜感】Clannad系列觀后感(劇透慎入)

前言 之前看第一季時&#xff0c;彈幕里總有人在刷“寫作cl&#xff0c;讀作人生”。當時我想&#xff0c;盲目把一部催淚番上升到人生的高度&#xff0c;這未免有些武斷&#xff0c;也是對作品本身的不尊重。當看完第二季的我驀然回首&#xff0c;發現這才是最最貼切的評價&am…

oracle+tns+01106,TNS-01106:Listener using listener name already been started

最近在做HACMP雙機互備切換測試的時候&#xff0c;發現一個問題&#xff1a;A節點的listener端口為1521 &#xff0c;B節點的listener端口為1522&#xff0c;為什么兩個節點的監聽要用不同的端口號&#xff1f;當時AB機使用不同端口是基于如下考慮&#xff1a;HACMP的切換數據庫…

Centos7 開機顯示 ERST: Failed to get Error Log Address Range” 導致無法開機解決方法

開機顯示 ERST: Failed to get Error Log Address Range” 導致無法開機&#xff0c;也無法重新安裝系統&#xff0c;解決方法&#xff1a;開機進入BIOS &#xff0c; 關閉ACPI選項即可正常開機 轉載于:https://www.cnblogs.com/zhangjianghua/p/6376811.html

Spring MVC 3模板和Apache Tiles

對于任何Web應用程序而言&#xff0c;有效的設計考慮因素是使用模板引擎&#xff08;或工具&#xff09;&#xff0c;并且由于具有Spring的“可插拔”特性&#xff0c;因此集成模板機制&#xff08;例如Apache Tiles&#xff09;的確要容易得多。 在這篇簡單的文章中&#xff0…

hihocoder1543 SCI表示法

題意&#xff1a;任何一個數可以表示為連續整數相加&#xff0c;問這些連續整數的最大長度 題解&#xff1a;假設左右是l,r,那么(lr)*(l-r1)/2就是這段序列的和&#xff0c;枚舉2n的所有因子&#xff0c;找到最大的就可以了 我的做法是預處理前綴和&#xff0c;二分找到答案位置…

linux自動安裝Java環境腳本,Linux 自動添加JAVA環境腳本

Linux 自動添加JAVA環境腳本1. 刪除原有的JAVA環境變量配置### --------------delete old config -------------------- ###sed -i -e /JAVA_HOME/d -e /JRE/d /etc/profile刪除包含JAVA_HME 、JRE的行2. 加入現有的JAVA環境變量配置### -------------- add new config ----…

輾轉相除法的證明

輾轉相除法的證明設兩數為a、b(b&#xff1c;a)&#xff0c;求它們最大公約數的步驟如下&#xff1a;用b除a&#xff0c;得a&#xff1d;bq&#xff0b;r&#xff08;0≤r&#xff1c;b&#xff09;&#xff08;q是這個除法的商&#xff09;。若r0,則b是a和b的最大公約數。若r≠…

linux查看有幾個終端命令,如何知道你在 Linux 里最常使用的幾個命令?

不知道大家自接觸 Linux 以來&#xff0c;都使用過哪些命令&#xff0c;其中最常用的命令是什么&#xff1f;我最常用的命令之一是 sudo &#xff0c;因為我每天都在使用它在 Linux 上安裝、更新、刪除軟件包以及其它各種需要超級用戶權限的操作。那么你知道你自己最經常使用的…

使用JUnit的ExpectedException和@Rule測試自定義異常

異常測試 為什么要測試異常流&#xff1f; 就像所有代碼一樣&#xff0c;測試覆蓋率會在代碼和應該生成的業務功能之間寫一個合同&#xff0c;從而為您提供代碼的有效文檔 &#xff0c;以及增加的盡早且經常強調功能的功能。 我不會介紹測試的許多好處&#xff0c;而是只關注異…

線程的工具類(Exchange)

public class Exchanger<V>extends Object 可以在對中對元素進行配對和交換的線程的同步點。每個線程將條目上的某個方法呈現給 exchange 方法&#xff0c;與伙伴線程進行匹配&#xff0c;并且在返回時接收其伙伴的對象。Exchanger 可能被視為 SynchronousQueue 的雙向形…

js 判斷瀏覽器是否64位

js判斷是否64位 瀏覽器 navigator.userAgent.match(/x64/i); 轉載于:https://www.cnblogs.com/fanlinglong/p/7298733.html

linux ss 軟件,linux ss 網絡狀態工具

ss是Socket Statistics的縮寫查看網絡狀態&#xff0c;經常用的命令&#xff1a; watch ss -lntss命令用于顯示socket狀態. 他可以顯示PACKET sockets, TCP sockets, UDP sockets, DCCP sockets, RAW sockets, Unix domain sockets等等統計. 它比其他工具展示等多tcp和state信…

Lambda項目:邁向多核及超越

周一下午在JavaOne 2011的希爾頓舊金山大宴會廳B上做了“ Project Lambda&#xff1a;邁向多核和超越”&#xff08;會議27400&#xff0c;不要與Brian Goetz的同名演講相混淆&#xff09; 的演示 。大宴會廳關閉&#xff0c;這是一個非常大型的非主題演講場地&#xff0c;并且…

Python 06-字典

字典是一種key-value的數據類型&#xff0c;就像日常用的字典&#xff0c;通過字母或者筆畫來查找對應頁的詳細內容。 字典是無序的&#xff0c;沒有順序。因為有key。 info {stu1001:wang er,stu1002:zhang san,stu1003:li si } print(info)#打印字典所有kv print(info[stu10…

hashMap 源碼解讀理解實現原理和hash沖突

hashMap 怎么說呢。 我的理解是 外表是一個set 數組&#xff0c;無序不重復 。 每個set元素是一個bean &#xff0c;存著一對key value 看看代碼吧 package test;import java.util.HashMap; import java.util.Map.Entry;public class HashMaptest {public static void main(Str…

浙江大學linux網絡通信,浙江大學鐘財軍副教授——“Wireless Powered Communication Networks”...

2016年5月17日&#xff0c;浙江大學鐘財軍副教授應徐正元教授邀請在中科大西區科技實驗樓東樓十層1011會議室做了一場題為“Wireless Powered Communication Networks”的學術報告。報告會由龔晨教授主持&#xff0c;共50余名師生參加。此次報告會得到了“中科院無線光電通信重…

自定義Spring Data JPA存儲庫

Spring Data是一個非常方便的庫。 但是&#xff0c;由于該項目是一個相當新的項目&#xff0c;因此功能不佳。 默認情況下&#xff0c;Spring Data JPA將基于SimpleJpaRepository提供DAO的實現。 在最近的項目中&#xff0c;我開發了一個定制的存儲庫基類&#xff0c;以便可以在…