更改Web根目錄


配置緩存

默認情況下,靜態處理程序將設置緩存標頭以使瀏覽器能夠有效地緩存文件。

Vert.x的Web設置標題cache-controllast-modifieddate

cache-controlmax-age=86400默認設置為。這相當於一天。setMaxAgeSeconds如果需要,可以配置它 。

如果瀏覽器發送帶有if-modified-since標頭的GET或HEAD請求,並且該資源自該日期起未被修改,304則返回狀態,告知瀏覽器使用其本地緩存的資源。

如果不需要處理緩存頭,則可以禁用它setCachingEnabled

啟用緩存處理后,Vert.x-Web將緩存內存中資源的最后修改日期,這樣可以避免磁盤命中每次都檢查實際的上次修改日期。

緩存中的條目具有到期時間,在此之后,將再次檢查磁盤上的文件並更新緩存條目。

如果您知道您的文件永遠不會在磁盤上更改,那么緩存條目將永遠不會過期。這是默認值。

如果您知道在服務器運行時您的文件可能在磁盤上發生更改,那么您可以將只讀文件設置為false setFilesReadOnly

要在任何時候啟用可以在內存中緩存的最大條目數,您可以使用 setMaxCacheSize

要配置可以使用的緩存條目的到期時間setCacheEntryTimeout

配置索引頁面

對根路徑的任何請求/都將導致索引頁面被提供。默認情況下,索引頁面是index.html。這可以配置setIndexPage

更改Web根目錄

默認情況下,將從目錄提供靜態資源webroot。配置此用途 setWebRoot

提供隱藏文件

默認情況下,服務器將提供隱藏文件(以文件開頭.)。

如果您不想要提供隱藏文件,可以使用它進行配置setIncludeHidden

目錄列表

服務器還可以執行目錄列表。默認情況下,禁用目錄列表。要啟用它setDirectoryListing

啟用目錄列表時,返回的內容取決於accept標頭中的內容類型。

對於text/html目錄列表,可以使用用於呈現目錄列表頁面的模板進行配置setDirectoryTemplate

禁用磁盤上的文件緩存

默認情況下,Vert.x會將從類路徑提供的文件緩存到磁盤上的文件中,該文件位於.vertx當前工作目錄中調用的目錄的子目錄中。這在將服務部署為生產中的fatjars時非常有用,每次從類路徑提供文件都很慢。

在開發過程中,這可能會導致問題,就像在服務器運行時更​​新靜態內容一樣,緩存文件將不會提供更新的文件。

要禁用文件緩存可以提供您vert.x選項的屬性fileResolverCachingEnabledfalse。為了向后兼容,它還會將該值默認為系統屬性vertx.disableFileCaching。例如,您可以在IDE中設置運行配置,以便在運行主類時進行設置。

CORS處理

跨源資源共享是一種安全機制,允許從一個域請求資源並從另一個域提供資源。

Vert.x-Web包含一個處理CorsHandlerCORS協議的處理程序。

這是一個例子:

router.route().handler(CorsHandler.create("vertx\\.io").allowedMethod(HttpMethod.GET)); router.route().handler(routingContext -> { // Your app handlers });

模板

Vert.x-Web包括動態頁面生成功能,包括對幾個流行模板引擎的開箱即用支持。您也可以輕松添加自己的。

模板引擎由描述TemplateEngine。為了渲染模板 render,使用了。

使用模板最簡單的方法不是直接調用模板引擎而是使用模板引擎 TemplateHandler。此處理程序根據HTTP請求中的路徑為您調用模板引擎。

默認情況下,模板處理程序將在名為的目錄中查找模板templates。這可以配置。

處理程序將返回具有text/html默認內容類型的呈現結果。這也可以配置。

創建模板處理程序時,您將傳入所需模板引擎的實例。模板引擎未嵌入到vertx-web中,因此您需要配置項目以訪問它們。為每個模板引擎提供配置。

這里有些例子:

TemplateEngine engine = HandlebarsTemplateEngine.create(); TemplateHandler handler = TemplateHandler.create(engine); // This will route all GET requests starting with /dynamic/ to the template handler // E.g. /dynamic/graph.hbs will look for a template in /templates/graph.hbs router.get("/dynamic/*").handler(handler); // Route all GET requests for resource ending in .hbs to the template handler router.getWithRegex(".+\\.hbs").handler(handler);

MVEL模板引擎

要使用MVEL,您需要將以下依賴項添加到項目中: io.vertx:vertx-web-templ-mvel:3.8.0。使用以下命令創建MVEL模板引擎的實例:io.vertx.ext.web.templ.MVELTemplateEngine#create()

使用MVEL模板引擎時,.templ如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

路由上下文RoutingContext在MVEL模板中可用作context變量,這意味着您可以基於上下文中的任何內容(包括請求,響應,會話或上下文數據)來呈現模板。

這里有些例子:

請求路徑是@ {context.request()。path()}

會話中的變量'foo'是@ {context.session()。get('foo')}

上下文數據中的值“bar”是@ {context.get('bar')}

有關如何編寫MVEL模板的信息,請參閱MVEL模板文檔

玉模板引擎

要使用Jade模板引擎,您需要將以下依賴項添加到項目中: io.vertx:vertx-web-templ-jade:3.8.0。使用以下方法創建Jade模板引擎的實例:io.vertx.ext.web.templ.JadeTemplateEngine#create()

使用Jade模板引擎時,.jade如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

路由上下文RoutingContext在Jade模板中可用作context變量,這意味着您可以基於上下文中的任何內容(包括請求,響應,會話或上下文數據)來呈現模板。

這里有些例子:

!五
HTML
 頭
   title = context.get('foo')+ context.request()。path()
 身體

有關如何編寫Jade模板的信息,請參閱Jade4j文檔

把手模板引擎

要使用Handlebars,您需要將以下依賴項添加到項目中: io.vertx:vertx-web-templ-handlebars:3.8.0。使用以下方法創建Handlebars模板引擎的實例:io.vertx.ext.web.templ.HandlebarsTemplateEngine#create()

使用Handlebars模板引擎時,.hbs如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

Handlebars模板無法調用對象中的任意方法,因此我們不能將路由上下文傳遞給模板,讓模板像我們可以使用其他模板引擎一樣內省它。

相反,上下文data在模板中可用。

如果要訪問其他數據(如請求路徑,請求參數或會話數據),則應在模板處理程序之前將其添加到處理程序中的上下文數據中。例如:

TemplateHandler handler = TemplateHandler.create(engine); router.get("/dynamic").handler(routingContext -> { routingContext.put("request_path", routingContext.request().path()); routingContext.put("session_data", routingContext.session().data()); routingContext.next(); }); router.get("/dynamic/").handler(handler);

有關如何編寫把手模板的信息,請參閱Handlebars Java端口文檔

Thymeleaf模板引擎

要使用Thymeleaf,您需要為項目添加以下依賴項: io.vertx:vertx-web-templ-thymeleaf:3.8.0。使用以下方法創建Thymeleaf模板引擎的實例:io.vertx.ext.web.templ.ThymeleafTemplateEngine#create()

使用Thymeleaf模板引擎時,.html如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

路由上下文RoutingContext在Thymeleaf模板中可用作context變量,這意味着您可以基於上下文中的任何內容(包括請求,響應,會話或上下文數據)來呈現模板。

這里有些例子:

[剪斷]
<p th:text =“$ {context.get('foo')}”> </ p>
<p th:text =“$ {context.get('bar')}”> </ p>
<p th:text =“$ {context.normalisedPath()}”> </ p>
<p th:text =“$ {context.request()。params()。get('param1')}”> </ p>
<p th:text =“$ {context.request()。params()。get('param2')}”> </ p>
[剪斷]

有關如何編寫Thymeleaf模板的信息,請參閱Thymeleaf文檔

Apache FreeMarker模板引擎

要使用Apache FreeMarker,您需要將以下依賴項添加到項目中: io.vertx:vertx-web-templ-freemarker:3.8.0。使用以下方法創建Apache FreeMarker模板引擎的實例:io.vertx.ext.web.templ.Engine#create()

使用Apache FreeMarker模板引擎時,.ftl如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

路由上下文RoutingContext在Apache FreeMarker模板中作為context變量提供,這意味着您可以基於上下文中的任何內容(包括請求,響應,會話或上下文數據)來呈現模板。

這里有些例子:

[剪斷]
<p th:text =“$ {context.foo}”> </ p>
<p th:text =“$ {context.bar}”> </ p>
<p th:text =“$ {context.normalisedPath()}”> </ p>
<p th:text =“$ {context.request()。params()。param1}”> </ p>
<p th:text =“$ {context.request()。params()。param2}”> </ p>
[剪斷]

有關如何編寫Apache FreeMarker模板的信息,請參閱Apache FreeMarker文檔

卵石模板引擎

要使用Pebble,您需要為項目添加以下依賴項: io.vertx:vertx-web-templ-pebble:3.8.0。使用以下方法創建Pebble模板引擎的實例:io.vertx.ext.web.templ.PebbleTemplateEngine#create(vertx)

使用Pebble模板引擎時,.peb如果文件名中未指定擴展名,它將默認查找帶擴展名的模板。

路由上下文RoutingContext在Pebble模板中可用作context變量,這意味着您可以基於上下文中的任何內容(包括請求,響應,會話或上下文數據)來呈現模板。

這里有些例子:

[剪斷]
<p th:text =“{{context.foo}}”> </ p>
<p th:text =“{{context.bar}}”> </ p>
<p th:text =“{{context.normalisedPath()}}”> </ p>
<p th:text =“{{context.request()。params()。param1}}”> </ p>
<p th:text =“{{context.request()。params()。param2}}”> </ p>
[剪斷]

有關如何編寫Pebble模板的信息,請參閱Pebble文檔

搖桿模板引擎

要使用Rocker,請將其io.vertx:vertx-web-templ-rocker:3.8.0作為依賴項添加到項目中。然后,您可以使用創建Rocker模板引擎實例io.vertx.ext.web.templ.rocker#create()

然后,傳遞給render方法的JSON上下文對象的值將作為模板參數公開。鑒於:

[剪斷]
final JsonObject context = new JsonObject()
 .put(“foo”,“badger”)
 .put(“bar”,“fox”)
 .put(“context”,new JsonObject()。put(“path”,“/ foo / bar”));

engine.render(context,“somedir / TestRockerTemplate2”,render  - > {
 //(...)
});
[剪斷]

然后模板可以作為以下somedir/TestRockerTemplate2.rocker.html資源文件:

@import io.vertx.core.json.JsonObject
@args(JsonObject context,String foo,String bar)
你好@foo和@bar
請求路徑是@ context.getString(“path”)

禁用緩存

在開發期間,您可能希望禁用模板緩存,以便在每個請求上重新評估模板。為此,您需要設置系統屬性:io.vertx.ext.web.TemplateEngine.disableCacheto true

默認情況下,它將為false。因此始終啟用緩存。

錯誤處理程序

您可以使用模板處理程序或其他方式呈現自己的錯誤,但Vert.x-Web還包含一個可以為您呈現錯誤頁面的四四方方的“漂亮”錯誤處理程序。

處理程序是ErrorHandler。要使用錯誤處理程序,只需將其設置為您想要覆蓋的任何路徑的失敗處理程序。

請求記錄器

Vert.x-Web包含一個LoggerHandler可用於記錄HTTP請求的處理程序。您應該在任何可能失敗的處理程序之前安裝此處理程序RoutingContext

默認情況下,請求會記錄到Vert.x記錄器,該記錄器可以配置為使用JUL日志記錄,log4j或SLF4J。

LoggerFormat

提供favicon

Vert.x-Web包含FaviconHandler特別用於服務favicons 的處理程序。

可以使用文件系統的路徑指定Favicons,或者默認情況下,Vert.x-Web將使用名稱在類路徑中查找文件favicon.ico。這意味着您將favicon捆綁在應用程序的jar中。

超時處理程序

Vert.x-Web包含一個超時處理程序,如果處理時間過長,您可以使用它來超時請求。

這是使用的實例配置的TimeoutHandler

如果請求在寫入503響應之前超時,則響應將返回給客戶端。

下面是一個使用超時處理程序的示例,該處理程序將/foo超過5秒后開始的所有路徑請求:

router.route("/foo/").handler(TimeoutHandler.create(5000));

響應時間處理程序

此處理程序設置標頭x-response-time響應標頭,其中包含從接收請求到寫入響應標頭的時間(以毫秒為單位),例如:

x響應時間:1456ms

內容類型處理程序

ResponseContentTypeHandler可以設置Content-Type自動報頭。假設我們正在構建一個RESTful Web應用程序。我們需要在所有處理程序中設置內容類型:

router.get("/api/books").produces("application/json").handler(rc -> findBooks(ar -> { if (ar.succeeded()) { rc.response().putHeader("Content-Type", "application/json").end(toJson(ar.result())); } else { rc.fail(ar.cause()); } }));

如果API表面變得非常大,則設置內容類型會變得很麻煩。要避免這種情況,請添加ResponseContentTypeHandler到相應的路由:

router.route("/api/*").handler(ResponseContentTypeHandler.create()); router.get("/api/books").produces("application/json").handler(rc -> findBooks(ar -> { if (ar.succeeded()) { rc.response().end(toJson(ar.result())); } else { rc.fail(ar.cause()); } }));

處理程序從中獲取適當的內容類型getAcceptableContentType。因此,您可以輕松共享同一個處理程序以生成不同類型的數據:

router.route("/api/*").handler(ResponseContentTypeHandler.create()); router.get("/api/books").produces("text/xml").produces("application/json").handler(rc -> findBooks(ar -> { if (ar.succeeded()) { if (rc.getAcceptableContentType().equals("text/xml")) { rc.response().end(toXML(ar.result())); } else { rc.response().end(toJson(ar.result())); } } else { rc.fail(ar.cause()); } }));

SockJS

SockJS是一個客戶端JavaScript庫和協議,它提供了一個簡單的類似WebSocket的接口,允許您連接到SockJS服務器,而不管實際的瀏覽器或網絡是否允許真正的WebSockets。

它通過支持瀏覽器和服務器之間的各種不同傳輸,並根據瀏覽器和網絡功能在運行時選擇一個來實現這一點。

所有這些對您來說都是透明的 - 您只需使用類似WebSocket的界面即可

有關SockJS的更多信息,請訪問SockJS網站

SockJS處理程序

Vert.x提供了一個開箱即用的處理程序SockJSHandler,在Vert.x-Web應用程序中使用SockJS。

您應該使用每個SockJS應用程序創建一個處理程序SockJSHandler.create。您還可以在創建實例時指定配置選項。配置選項用實例描述SockJSHandlerOptions

Router router = Router.router(vertx); SockJSHandlerOptions options = new SockJSHandlerOptions().setHeartbeatInterval(2000); SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options); router.route("/myapp/*").handler(sockJSHandler);

處理SockJS套接字

在服務器端,您在SockJS處理程序上設置了一個處理程序,每次從客戶端建立SockJS連接時都會調用它:

傳遞給處理程序的對象是SockJSSocket。這有一個熟悉的類似套接字的接口,你可以讀取和寫入類似於a NetSocket或a WebSocket。它還實現了ReadStream, WriteStream因此您可以將其與其他讀寫流相連。

下面是一個簡單的SockJS處理程序的示例,該處理程序只返回它讀取的任何數據:

Router router = Router.router(vertx);

SockJSHandlerOptions options = new SockJSHandlerOptions().setHeartbeatInterval(2000); SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options); sockJSHandler.socketHandler(sockJSSocket -> { // Just echo the data back sockJSSocket.handler(sockJSSocket::write); }); router.route("/myapp/*").handler(sockJSHandler);

客戶端

在客戶端JavaScript中,您使用SockJS客戶端庫進行連接。

你可以在這里找到。

有關使用SockJS JavaScript客戶端的完整詳細信息,請訪問SockJS網站,但總結一下,您可以使用以下內容:

var sock = new SockJS('http://mydomain.com/myapp');

sock.onopen = function(){
 的console.log( '開放');
};

sock.onmessage = function(e){
 console.log('message',e.data);
};

sock.onclose = function(){
 的console.log( '關閉');
};

sock.send( '試驗');

sock.close();

配置SockJS處理程序

可以使用各種選項配置處理程序SockJSHandlerOptions

insertJSESSIONID

插入JSESSIONID cookie,以便負載均衡器確保對特定SockJS會話的請求始終路由到正確的服務器。默認是true

sessionTimeout

close當一段時間沒有看到接收連接的客戶端時,服務器發送事件。此延遲由此設置配置。默認情況下,在close5秒內未看到接收連接時將發出事件。

heartbeatInterval

為了防止代理和負載均衡器關閉長時間運行的http請求,我們需要假裝連接處於活動狀態並偶爾發送心跳包。此設置控制此操作的頻率。默認情況下,每25秒發送一次心跳包。

maxBytesStreaming

大多數流傳輸在客戶端保存響應,並且不釋放傳遞的消息使用的內存。這種運輸需要偶爾進行垃圾收集。max_bytes_streaming設置在關閉之前可通過單個HTTP流請求發送的最小字節數。之后客戶端需要打開新請求。將此值設置為1可以有效地禁用流式傳輸,並使流式傳輸的行為類似於輪詢傳輸。默認值為128K。

libraryURL

不支持跨域通信的傳輸('eventsource'到名稱之一)使用iframe技巧。一個簡單的頁面從SockJS服務器(使用其外部域)提供,並放置在一個不可見的iframe中。從這個iframe運行的代碼不需要擔心跨域問題,因為它從域本地運行到SockJS服務器。這個iframe也需要加載SockJS javascript客戶端庫,這個選項允許你指定它的url(如果你不確定,請指向最新的縮小的SockJS客戶端版本,這是默認值)。默認值為http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js

disabledTransports

這是您要禁用的傳輸列表。可能的值為WEBSOCKET,EVENT_SOURCE,HTML_FILE,JSON_P,XHR。

SockJS事件總線橋

Vert.x-Web附帶一個稱為事件總線橋的內置SockJS套接字處理程序,它有效地將服務器端Vert.x事件總線擴展到客戶端JavaScript。

這將創建一個分布式事件總線,它不僅跨越服務器端的多個Vert.x實例,還包括在瀏覽器中運行的客戶端JavaScript。

因此,我們可以創建一個包含許多瀏覽器和服務器的龐大分布式總線。只要連接服務器,瀏覽器就不必連接到同一台服務器。

這是通過提供一個簡單的客戶端JavaScript庫來實現的,該庫vertx-eventbus.js提供了一個非常類似於服務器端Vert.x事件總線API的API,它允許您向事件總線發送和發布消息並注冊處理程序以接收消息。

此JavaScript庫使用JavaScript SockJS客戶端通過終止於SockJSHandler服務器端的SockJS連接來隧道傳輸事件總線流量。

然后在其SockJSHandler上安裝一個特殊的SockJS套接字處理程序,它處理SockJS數據並將其與服務器端事件總線橋接。

要激活網橋,只需調用 bridgeSockJS處理程序即可。

Router router = Router.router(vertx); SockJSHandler sockJSHandler = SockJSHandler.create(vertx); BridgeOptions options = new BridgeOptions(); sockJSHandler.bridge(options); router.route("/eventbus/*").handler(sockJSHandler);

在客戶端JavaScript中,您使用'vertx-eventbus.js`庫來創建與事件總線的連接以及發送和接收消息:

<script src="http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script> <script src='vertx-eventbus.js'></script> <script>  var eb = new EventBus('http://localhost:8080/eventbus'); eb.onopen = function() { // set a handler to receive a message eb.registerHandler('some-address', function(error, message) { console.log('received a message: ' + JSON.stringify(message)); }); // send a message eb.send('some-address', {name: 'tim', age: 587}); } </script>

該示例的第一件事是創建事件總線的實例

var eb = new EventBus('http://localhost:8080/eventbus');

構造函數的參數是連接到事件總線的URI。由於我們使用前綴創建橋,eventbus我們將在那里連接。

在打開連接之前,您無法對連接執行任何操作。當它打開時,onopen將調用處理程序。

該橋支持自動重新連接,具有可配置的延遲和退避選項。

var eb = new EventBus('http://localhost:8080/eventbus'); eb.enableReconnect(true); eb.onopen = function() {}; // Set up handlers here, will be called on initial connection and all reconnections eb.onreconnect = function() {}; // Optional, will only be called on reconnections // Alternatively, pass in an options object var options = { vertxbus_reconnect_attempts_max: Infinity, // Max reconnect attempts vertxbus_reconnect_delay_min: 1000, // Initial delay (in ms) before first reconnect attempt vertxbus_reconnect_delay_max: 5000, // Max delay (in ms) between reconnect attempts vertxbus_reconnect_exponent: 2, // Exponential backoff factor vertxbus_randomization_factor: 0.5 // Randomization factor between 0 and 1 }; var eb2 = new EventBus('http://localhost:8080/eventbus', options); eb2.enableReconnect(true); // Set up handlers...

您可以使用依賴項管理器檢索客戶端庫:

  • Maven(在你的pom.xml):

<dependency> <groupId>io.vertx</groupId> <artifactId>vertx-web</artifactId> <version>3.8.0</version> <classifier>client</classifier> <type>js</type> </dependency>
  • Gradle(在您的build.gradle文件中):

compile 'io.vertx:vertx-web:3.8.0:client'

該圖書館也可用於:

請注意,API已在3.0.0和3.1.0版本之間進行了更改。請檢查更改日志。以前的客戶端仍然兼容,仍然可以使用,但新客戶端提供更多功能,並且更接近vert.x事件總線API。

保護橋梁

如果您在沒有保護它的情況下啟動了上述示例中的橋接器,並嘗試通過它發送消息,您會發現消息神秘地消失了。他們發生了什么?

對於大多數應用程序,您可能不希望客戶端JavaScript能夠向服務器端的任何處理程序或所有其他瀏覽器發送任何消息。

例如,您可能在事件總線上有一個服務,允許訪問或刪除數據。我們不希望行為不端或惡意的客戶端能夠刪除數據庫中的所有數據!

此外,我們不一定希望任何客戶端能夠監聽任何事件總線地址。

為了解決這個問題,SockJS橋將默認拒絕通過任何消息。您可以告訴橋接器哪些消息可以通過。(對於總是允許通過的回復消息,有一個例外)。

換句話說,網橋就像一種具有默認拒絕所有策略的防火牆。

配置網橋告訴它應該通過哪些消息很容易。

您可以使用在調用bridge時傳入的內容來指定要允許入站和出站流量的 匹配項BridgeOptions

每個匹配都是一個PermittedOptions對象:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM