SpringMVC中用@ParamVariable传递的参数包含斜杠(/)时,匹配不了报404错误的解决方案

今天作网站标签筛选功能时,出现了这么个奇葩的问题。
我是直接经过<a>标签中href来跳转的,url中包含汉字
<a href="/tags/标签A">标签A</a>

后台代码是这样的:html

@RequestMapping(value = "/tags/{tagname}")
public String tags(@PathVariable String tagname) {
   // ISO-8859-1 ==> UTF-8 进行编码转换
   tagname = encode_to_utf8(tagname);
   // 其他处理略
}

按理说这样就好了,各大浏览器也正常执行了。前端

可是,一不下心发现,只要URL中出现“”这个汉字,直接就报404错误java

例如这样:后端

<a href="/tags/标签充A">标签充A</a>

奇葩吧。浏览器

通过漫长的调查发现,缘由有可能是:app

这个汉字在URL中直接提交,通过浏览器转码后,会变成一串包含“/”的“乱码”。测试

后来通过相似测试发现,果真只要URL中包含“/”的参数,都没法经过@PathVariable正确匹配。网站

 

有人说不如改为这样:编码

方案1:url

在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
相关文章
相关标签/搜索