Spring控制器方法的不需要的逗号分隔参数

时间:2011-03-15 04:48:45

标签: java spring spring-mvc

我看到Spring MVC控制器出现了一个奇怪的问题。此方法用于设置密码。它需要两个表单参数“password”和“confirmPassword”。第一次调用表单时,这很好 - 将字段传递给方法。

第二次提交表单时会出现问题。如果表单第一次填写不正确,则会正确地将用户发送回表单页面并提示再次输入密码。但是,第二次尝试时该方法的参数不正确。参数是逗号分隔的列表,其中包括与第二个连接的第一个表单条目。

示例:

带字段“password”的第一个表单帖子的值为“abc”。方法参数“password”的值为“abc”。

第二个表单帖子,字段为“password”,值为“xyz”。方法参数“password”的值为“xyz,abc”。

Spring MVC文档并未表明有用。不知何故,旧的表格帖子被记住并包括在内。有人有解决这个问题的经验吗?

控制器方法如下:

@RequestMapping(value = "/account/reset", method = RequestMethod.POST)
public String resetPassword(@RequestParam("password") String password,
        @RequestParam("confirmPassword") String confirmPassword,
        @RequestParam("hash") String hash, ModelMap model) throws EncryptionException
{
    String userName = stringEncrypterService.decrypt(hash);
    User user = userService.findUserByPath(userName);

    if (!password.equals(confirmPassword))
    {
        model.put("hash", hash);
        model.put("user", user);
        model.put("error",
                "The two passwords you entered below do not match. Please try again.");

        return "users/resetPassword";
    }

    userService.updatePassword(user, password);
    emailService.sendUserInfoChange(user);
    return "redirect:/session/signin?passwordReset=true";
}

更新。一些响应者已经建议可能有问题的帖子有额外的URL参数或隐藏的表单字段导致重复的字段名称。我向Fiddler确认情况并非如此。这是第三次尝试的原始请求。 (略微编辑以删除会话cookie)。

POST http://wintest.foriodev.com/simulate/account/reset/ HTTP/1.1
Host: wintest.foriodev.com
Connection: keep-alive
Referer: http://wintest.foriodev.com/simulate/account/reset/
Content-Length: 73
Cache-Control: max-age=0
Origin: http://wintest.foriodev.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Content-Type: application/x-www-form-urlencoded
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: AUTOLOGIN_TOKEN=xyz; SIMULATE_WORKER=wintest; JSESSIONID=xyz; 

password=a&hash=xyz&confirmPassword=a&save=Reset+Password

8 个答案:

答案 0 :(得分:8)

我认为这是因为

返回“重定向: / session / signin?passwordReset = true”;

使用重定向:框架使用url重写技术,类似于servlet中的基本response.sendRedirect(...),因此参数值与请求一起附加到下一个后续请求等等

尝试使用其他机制而不是“重定向:

答案 1 :(得分:5)

所以经过一年多的努力,我发现了这一点。

问题是一个自定义拦截器,它在每个请求上存储了请求缓存。我这样做是为了当用户登录时,他将返回上一个屏幕。但这对于“重置密码”屏幕来说是完全不合适的。

机制是,当调用request.getParameter(Name)时,SavedRequestCacheWrapper会将实际的HTTP请求参数与最后一个请求中存储的参数连接起来。

解决方案是(a)让这个拦截器忽略重置密码屏幕,(b)忽略所有发布请求以防止这种请求参数值连接。

对于其他响应者,感谢所有好主意。 (以及对此给予赏金的匿名用户 - 感谢让我回去再看看。)

答案 2 :(得分:4)

如果你第三次发帖,那么这个名单也会增加到三个吗?这表明问题与用户的会话有关。或者,如果列表保持为2,则问题出在请求中。我猜这个列表增长到三个,因为你从Fiddler发布的信息在请求中没有显示重复的迹象。

要确认数据在会话中,请检查其内容(例如,打印到日志,使用调试器,在开发环境中打印到网页)以获取相同密钥下的数据 - “密码”,“哈希“等等。

此外,请参阅this other response,了解数据可能在用户会话中的原因,例如。你在某处使用了@SessionAttributes注释。

答案 3 :(得分:3)

当您有多个具有相同名称的表单字段时,您将获得逗号分隔值。造成这种情况的常见原因是隐藏的输入和文本输入具有相同的名称。页面第一次发布时,隐藏的输入将为空,因此没有逗号。页面发布的第二个(和次要的)时间,隐藏的输入将具有值,因此您可以获得逗号。

答案 4 :(得分:2)

看起来旧值以某种方式显示为GET参数,即您在第二种形式中有<form action = ".../account/reset?password=abc">,或者action为空,第二种形式的网址为.../account/reset?password=abc 。虽然我在代码中找不到任何责任。

答案 5 :(得分:0)

当您从验证步骤返回时,您是否以某种方式再次指定表单字段?使用Firebug或类似的东西来检查您发送的内容和/或发布您的jsp(或类似)页面。

答案 6 :(得分:0)

看起来这可能是由https://jira.springsource.org/browse/SEC-1258问题引起的 &#34; SavedRequestAwareWrapper与Spring MVC结合导致3.0 M2的麻烦&#34;

答案 7 :(得分:0)

就我而言,我将隐藏字段与未使用的路径相关联。删除隐藏字段帮助我解决了这个问题。