SpringMVC中用@ParamVariable傳遞的參數包含斜杠(/)時,匹配不了報404錯誤的解決方案


今天做網站標簽篩選功能時,出現了這么個奇葩的問題。
我是直接通過<a>標簽中href來跳轉的,url中包含漢字
<a href="/tags/標簽A">標簽A</a>

后台代碼是這樣的:

@RequestMapping(value = "/tags/{tagname}")
public String tags(@PathVariable String tagname) {
   // ISO-8859-1 ==> UTF-8 進行編碼轉換
   tagname = encode_to_utf8(tagname);
   // 其余處理略
}

按理說這樣就行了,各大瀏覽器也正常執行了。

但是,一不下心發現,只要URL中出現“”這個漢字,直接就報404錯誤

例如這樣:

<a href="/tags/標簽充A">標簽充A</a>

奇葩吧。

經過漫長的調查發現,原因有可能是:

這個漢字在URL中直接提交,經過瀏覽器轉碼后,會變成一串包含“/”的“亂碼”。

后來經過類似測試發現,果然只要URL中包含“/”的參數,都無法通過@PathVariable正確匹配。

 

有人說不如改成這樣:

方案1:

在Server端通過urlencode把漢字先進行UTF-8編碼,然后扔到前端。

否決這樣做的話,URL就會變成這個丑樣,這和亂碼有什么區別?真心不喜歡。

<a href="/tags/%D6%D0%B9%FA">標簽充A</a>

 

后來縱觀各大站點,各有各的做法

方案2:

<a href="/tags?tagname=標簽充A">標簽充A</a>

然后在Controller中用@RequestParam來接收參數,這樣確實是可以的。

否決:但是SEO大神說,url中包含?的動態參數后,有可能會被蜘蛛重復抓取,不利於SEO。

 

方案3 :把漢字便簽轉換成拼音

<a href="/tags/biaoqianchongA">標簽充A</a>

否決:這樣可以是可以,但是還要在搞一個漢字轉拼音插件,而且看上去也不直觀,不好。

 

方案4:給標簽一個ID

<a href="/tags/T1">標簽充A</a>

否決這樣可以是可以,但是我還要該表結構,蛋疼。

 

方案5:用JS阻斷A的href,實現POST跳轉

 否決:現在百度已經可以解析JS了嗎?

 

大家還有別的方案沒有??

 

難道就沒有辦法在保持URL格式與漢字都不變的情況,實現這個功能嗎?

最后終於發現,有人這樣搞定了!

前端:

<a href="/tags/標簽充A">標簽充A</a>

后端:

@RequestMapping(value = "/tags/**")
public String tags(HttpServletRequest request) {
   // ISO-8859-1 ==> UTF-8 進行編碼轉換
  String tagname = extractPathFromPattern(request);
      tagname = ToolUtils.encodeStr(tagname);
   // 其余處理略
}

// 把指定URL后的字符串全部截斷當成參數
// 這么做是為了防止URL中包含中文或者特殊字符(/等)時,匹配不了的問題
private static String extractPathFromPattern(
            final HttpServletRequest request)
{
     String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
     String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
     return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
}

搞完之后,不管你輸入什么樣的URL,都能進入到指定的方法!

<a href="/tags/標簽充A">標簽充A</a>
<a href="/tags/標簽充A/asd/asd">標簽充A</a>
<a href="/tags/標簽充A/BB/cc.html">標簽充A</a>



參考原文地址:http://kamatama41.hatenablog.com/entry/20130411/1365668200


免責聲明!

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



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