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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

重写到边缘–充分利用它! 在GlassFish上!

發(fā)布時(shí)間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重写到边缘–充分利用它! 在GlassFish上! 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
現(xiàn)代應(yīng)用程序開發(fā)的一個(gè)重要主題是重寫。 自從Java Server Faces引入和Java EE 6中新的輕量級(jí)編程模型以來,您一直在努力使用漂亮,簡單,可添加書簽的URL。 PrettyFaces很久以來就一直存在,即使它在3.3.3版本中可以說是成熟的,我也不敢相信。

主要是因?yàn)槲冶仨氃趚ml中配置它。 如果您曾經(jīng)做過JSF項(xiàng)目,那么您就會(huì)知道這是您稍后要做的事情。 或永遠(yuǎn)不會(huì)。 最后一個(gè)選項(xiàng)是我看到的很多東西。 重寫將改變這一點(diǎn)。 程序化,易于使用和高度可定制的。 正是我想要的。

入門

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

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

這還不夠,因?yàn)槲覍⑺cJSF一起使用,您還需要jsf-integration。

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

接下來實(shí)現(xiàn)您自己的ConfigurationProvider。 這是發(fā)生大多數(shù)魔術(shù)的核心部分。現(xiàn)在我們將其稱為TricksProvider,我們還將擴(kuò)展抽象的HttpConfigurationProvider。 一個(gè)簡單的第一個(gè)版本如下所示:

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"));} }

現(xiàn)在,您必須注冊(cè)您的ConfigurationProvider。 為此,您可以在應(yīng)用程序/ META-INF / services /文件夾中添加一個(gè)名為org.ocpsoft.rewrite.config.ConfigurationProvider的簡單文本文件。 向其添加ConfigurationProvider實(shí)現(xiàn)的標(biāo)準(zhǔn)名稱,即可完成操作。 如果您啟動(dòng)應(yīng)用程序。

重寫基礎(chǔ)

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

用一些魔法將.html轉(zhuǎn)發(fā)到.xhtml

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

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

這是一條規(guī)則,用于檢查入站請(qǐng)求,并檢查所有與正則表達(dá)式模式[a-zA-Z /] +確認(rèn)的補(bǔ)丁匹配{name} .html,并將其轉(zhuǎn)發(fā)到{name} .xhtml文件。

如果執(zhí)行此規(guī)則,則對(duì)http:// host:8080 / yourapp / something.html的所有請(qǐng)求最終都將轉(zhuǎn)發(fā)到something.xhtml。 現(xiàn)在,您的用戶將不再知道您在下面使用的是花哨的JSF內(nèi)容,并認(rèn)為您正在使用html :)如果請(qǐng)求的URL與正則表達(dá)式不匹配,例如類似http:// host:8080 / yourapp / something123.html根本不會(huì)轉(zhuǎn)發(fā),如果您的應(yīng)用程序中不存在something123.html,您最終將收到404錯(cuò)誤。

改寫出站鏈接

相反,您還可以添加以下規(guī)則:

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

你想像這是在做什么,對(duì)嗎? 如果您的facelet包含以下內(nèi)容:

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

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

OutputBuffer

重寫中最令人驚訝的東西稱為OutputBuffer。 至少直到我們正在使用的發(fā)行版為止。 它會(huì)在2.0中重命名,但現(xiàn)在讓我們簡單地看一下您可以做什么。 OutputBuffer是您對(duì)響應(yīng)的了解。 在響應(yīng)真正到達(dá)客戶瀏覽器之前,您想對(duì)響應(yīng)做什么。 考慮轉(zhuǎn)換標(biāo)記? 轉(zhuǎn)換CSS? 甚至GZIP壓縮? 太好了,這正是您所能做的。 讓我們實(shí)現(xiàn)一個(gè)簡單的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縮小通過此方法接收的流。 接下來,我們必須將相關(guān)規(guī)則添加到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"))))

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

通過重寫增強(qiáng)安全性

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

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

并定義以下規(guī)則:

.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"))

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

底線

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

GlassFish部分在哪里?

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

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


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

總結(jié)

以上是生活随笔為你收集整理的重写到边缘–充分利用它! 在GlassFish上!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。