概述
本文將重點(diǎn)介紹在 spring 中實(shí)現(xiàn)重定向(redirect),并將討論每個(gè)策略背后的原因。
為什么要重定向?
讓我們先來考慮在 spring 應(yīng)用程序中為什么您可能需要做一個(gè)重定向的原因。
當(dāng)然有很多可能的例子和原因。 一個(gè)簡單的可能是 post 表單數(shù)據(jù),圍繞雙重提交問題,或者只是將執(zhí)行流委托給另一個(gè)控制器方法。
附注一點(diǎn),典型的 post / redirect / get 模式并不能充分解決雙重提交問題 - 在初始提交完成之前刷新頁面的問題可能仍然會(huì)導(dǎo)致雙重提交。
使用 redirectview 重定向
我們從這個(gè)簡單的方法開始 - 直接來一個(gè)例子:
在背后,redirectview 會(huì)觸發(fā) httpservletresponse.sendredirect() - 這將執(zhí)行實(shí)際的重定向。
注意這里我們是如何注入重定向?qū)傩缘椒椒ɡ锩娴?- 由框架完成這部分繁重的工作,讓我們能夠與這些屬性交互。
我們添加 attribute 到模型redirectattributes中 - 將其作為 http 查詢參數(shù)(query parameter)暴露。 該模型包含的對(duì)象 - 通常是字符串或可以被轉(zhuǎn)換成字符串的對(duì)象。
現(xiàn)在讓我們來測(cè)試我們的重定向功能 - 用一個(gè)簡單的 curl 命令來幫助實(shí)現(xiàn):
結(jié)果將是:
使用 redirect: 前綴進(jìn)行重定向
前面一個(gè)方法使用redirectview,因?yàn)橐恍┰蛩⒉皇亲顑?yōu)的。
首先,我們現(xiàn)在是耦合于spring api的,因?yàn)槲覀冊(cè)谖覀兊拇a里直接地使用redirectview。
其次,我們需要從一開始就知道,當(dāng)實(shí)現(xiàn)控制器操作的時(shí)候,它的結(jié)果將總是重定向的,但情況并非總是如此。
更好的選擇是使用redirect:前綴——重定向視圖名稱像其它邏輯視圖名稱一樣被注入到控制器中。控制器甚至不知道重定向正在發(fā)生。
它看起來像是這樣的:
當(dāng)視圖名稱跟redirect:一起返回的時(shí)候,urlbasedviewresolver類(以及它的所有子類)會(huì)將其識(shí)別為一個(gè)需要進(jìn)行重定向的特殊指示。視圖名稱剩下的部分會(huì)被當(dāng)作重定向url。
這里有一個(gè)地方需要注意——當(dāng)我們?cè)谶@里使用redirect:/redirectedurl邏輯視圖的時(shí)候,我們正在做一個(gè)跟當(dāng)前servlet上下文相關(guān)的重定向。
如果需要重定向到一個(gè)絕對(duì)url,我們可以使用像這樣的名稱:redirect: http://localhost:8080/spring-redirect/redirectedurl。
所以現(xiàn)在,當(dāng)我們執(zhí)行curl命令:
我們會(huì)立刻得到一個(gè)重定向:
使用 forward 前綴轉(zhuǎn)發(fā)
我們現(xiàn)在看看如何做一些略有不同的事——一個(gè)轉(zhuǎn)發(fā)。
在看代碼之前,我們先來看一下對(duì)轉(zhuǎn)發(fā)與重定向的語義的快速、高層概括:
重定向?qū)⒁园?02響應(yīng)碼和location頭的新url進(jìn)行響應(yīng);然后瀏覽器/客戶端將再次向新的url發(fā)出請(qǐng)求
轉(zhuǎn)發(fā)完全在服務(wù)器端發(fā)生; servlet容器將相同的請(qǐng)求轉(zhuǎn)發(fā)到目標(biāo)url;瀏覽器中的url無須改變
現(xiàn)在我們來看看代碼:
與redirect:一樣,forward:前綴將由urlbasedviewresolver及其子類解析。在內(nèi)部,這將創(chuàng)建一個(gè)internalresourceview,它為新視圖執(zhí)行一個(gè)requestdispatcher.forward()操作。
當(dāng)我們用curl執(zhí)行該命令時(shí):
我們會(huì)得到http 405 (不允許的方法):
與我們?cè)谥囟ㄏ蚪鉀Q方案中的兩個(gè)請(qǐng)求相比,在這種情況下,我們只有一個(gè)請(qǐng)求從瀏覽器/客戶端發(fā)送到服務(wù)器端。當(dāng)然,以前由重定向添加的屬性也不需要了。
包含 redirectattributes 的屬性
接下來 - 讓我們看看在一個(gè)重定向中傳遞屬性 - 充分利用框架中的redirectattribures:
如前所述,我們可以直接在方法中插入屬性對(duì)象 - 這使得該機(jī)制非常容易使用。
還要注意,我們也添加一個(gè)flash屬性 - 這是一個(gè)不會(huì)被添加到url中的屬性。我們可以通過這種屬性來實(shí)現(xiàn)——我們稍后可以在重定向的最終目標(biāo)的方法中使用@modelattribute(“flashattribute”)來訪問flash屬性:
因此,圓滿完工——如果你需要使用curl測(cè)試該功能:
我們將會(huì)被重定向到新的位置:
這樣,使用redirectattribures代替modelmap,賦予我們僅在重定向操作中涉及的兩種方法之間共享一些屬性的能力。
沒有前綴的另一種配置
現(xiàn)在讓我們探索另一種配置——沒有前綴的重定向。
為了實(shí)現(xiàn)這一點(diǎn),我們需要使用org.springframework.web.servlet.view.xmlviewresolver:
代替我們?cè)谥芭渲美锸褂玫膐rg.springframework.web.servlet.view.internalresourceviewresolver:
我們還需要在配置里面定義一個(gè)redirectview bean:
現(xiàn)在我們可以通過id來引用這個(gè)新的bean來觸發(fā)重定向:
為了測(cè)試它,我們?cè)俅问褂胏url命令:
結(jié)果會(huì)是:
重定向 http post 請(qǐng)求 request
對(duì)于類似銀行付款這樣的用例,我們可能需要重定向http post請(qǐng)求。根據(jù)返回的http狀態(tài)碼,post請(qǐng)求可以重定向到http get或post上。
根據(jù)http 1.1協(xié)議參考,狀態(tài)碼301(永久移除)和302(已找到)允許請(qǐng)求方法從post更改為get。該規(guī)范還定義了不允許將請(qǐng)求方法從post更改為get的相關(guān)的307(臨時(shí)重定向)和308(永久重定向)狀態(tài)碼。
現(xiàn)在,我們來看看將post請(qǐng)求重定向到另一個(gè)post請(qǐng)求的代碼:
現(xiàn)在,讓我們使用curl命令來測(cè)試下重定向的post:
我們正在被重定向到目標(biāo)地址:
結(jié)論
本文介紹了在spring中實(shí)現(xiàn)重定向的三種不同方法,在執(zhí)行這些重定向時(shí)如何處理/傳遞屬性以及如何處理http post請(qǐng)求的重定向。
以上所述是小編給大家介紹的vspring 重定向(redirect)指南及相關(guān)策略問題,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:https://dzone.com/articles/hacking-the-integercache-in-java-9