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
时间: 2024-12-20 18:08:26

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

对于springmvc 很奇妙的报404错误的记录

@RequestMapping("/editItems") public ModelAndView editItems(Integer id) throws Exception { @RequestMapping("/editItemsSubmit") public String editItemsSubmit(Integer id, ItemsCustom itemsCustom)throws Exception { 上述两段代码,其中/editItems.act

问题处理:php json_decode函数处理的字符串中含有反斜杠“\”时,处理出错,返回的结果为NULL

php json_decode函数处理的字符串中含有反斜杠“\”时,处理出错,返回的结果为NULL. 处理方法,将字符串中的反斜杠1个替换成2个: /** * 一个反斜杠要替换成4个,否则json_decode不能解析 */ $json_str = str_replace('\\','\\\\',$json_str); $json = json_decode($json_str,true);

koa2 get请求后台正常接收参数 前端报404错误

刚学习一门技术时,总会踩一些坑. 前端代码 function del(mId){ $.ajax({ type:"get", url:"/delUser", data:{id:mId}, success:function(data){ console.log('成功了'); console.log(data); } }); } 后台接收请求代码 router.get('/delUser',async (ctx,next)=>{ console.log('接收请求

sed命令替换字符包含斜杠\,引号的处理方法

在字符替换中,可能会遇见引号,"/"等的替换,这时应该注意,sed的命令原型是: sed -i  "s/oldstring/goalstring/g" file 如果一个路径是data/path/abc,现在要将此路径换成一个字符串cde 但是这时跟在s后边的其实是分隔符,用以将oldstring替换成cde;他可以使用任意字符,这时如果字符串中有"/",就会发生混乱,在这个时候可以用#当做分隔符,就变成 sed -i "s#abc#c

SpringMVC + Spring + MyBatis 学习笔记:提交数据遭遇基础类型和日期类型报400错误解决方法

系统:WIN7 数据库:mysql 开发工具:Eclipse 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 使用SpringMVC开发的时候,页面如果有日期格式的数据,后台接受也是java.util.Date,则报告400错误 . 在controller使用对象来接收前台页面的date数据类型时报400错误 下面是解决方案的演示示例: 这个是实体类,里面createDate就是java.util.Date类型 1 import java.util.Date

正则表达式 反斜杠的匹配 2018-11-30

问题引入: 在学习正则表达式的过程中,遇到了一直无法正确匹配反斜杠\,初始使用的是下面两种方法: 使用普通字符串,匹配一个反斜杠,需要再用一个反斜杠来转义:\\ 使用带r的原始字符串,这样就不用再转义:r'\' 使用上面两种方法一直无法匹配 4\5 中的反斜杠,最终经过查询,发现自己理解错误,字符串存在转义,正则也存在转义 1. 字符串转义: 在字符串中,我们会用一反斜杠加特定的字符来表达一些特定的功能,比如,\n表示换行,\"表示双引号等等,而如果要输出反斜杠本身,则用\\如下所示: >

ajax调取springmvc controller报404错误及表格提交

今天遇到一个很奇怪的问题,前台ajax中写的url地址明明与controller requestmapping地址匹配,但一直报404的错.后来和其他的方法一比对,发现是没有加@ResponseBody注解.加上之后就正常了. @ResponseBody注解的意思是直接输出,所以我一直以为只和输出内容有关,总觉得应该是先匹配地址,然后匹配对了,执行方法再输出内容,看来不是如此. 另外记下提交前台表格的两种方法: ① $.ajax({ url:"your_url", data:$(&qu

springmvc引入静态文件报404错误

springmvc项目在引入jquery.js文件的时候报了404的错误,当然jquery也是无法使用了,出现这样的错误主要是由于dispatcherServlet拦截设置的问题,请看以下例子: 当我们在web.xml里面设置dispatcherServlet时设置了拦截"/",所以引入静态文件的时候也会因为这个设置而导致无法寻找文件 解决方案: 1.可以把这个拦截设置为*.do,那么页面中照常引入文件,web.xml设置: JSP使用并测试: 2.第二种方式可以添加文件后缀的拦截,建

SpringMVC接收不到前端传递的参数原因分析

前言 ?在学习SpringMvc的时候遇到了一个问题,后台一直接收不到前台传递过来的参数,耽误了好长时间终于找到了原因,写篇博客记录下这个坑,嘤嘤嘤 --__-- 代码清单 ?使用SpringMvc接受前台传递的参数非常简单,只要参数名和前台表单中的名称一致即可,我弄得是一个文件上传的例子,所以看下我的前台页面 <body> <!-- enctype="multipart/form-data"在文件上传时加入,编码类型,其值默认是application/x-www-f