Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 593|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-9-5 16:34:10 | 显示全部楼层 |阅读模式
    今天做网站【标签】筛选功能时,出现了这么个奇葩的问题。
    我是直接通过<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
    http://www.cnblogs.com/notDog/p/5122106.html

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-27 22:43 , Processed in 0.069950 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表