有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我发现Spring MVC控制器有一个奇怪的问题。此方法用于设置密码。它有两个表单参数“password”和“confirmPassword”。第一次调用表单时,它工作正常——字段被传递给方法

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

例如:

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

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

SpringMVC文档并不表示有多大用处。不知何故,旧的表单帖子被记住并包括在内。有人有解决这个问题的经验吗

控制器方法如下:

@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参数或隐藏的表单字段,从而导致重复的字段名。我向费德勒证实了事实并非如此。这是第三次尝试的原始请求。(稍微编辑以删除会话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

共 (6) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

    我认为这是因为

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

    重定向:框架使用url重写技术,类似于基本响应。sendRedirect(…)在Servlet中,以及参数中,值与请求一起附加到下一个后续请求中,依此类推

    尝试使用不同的机制,而不是“重定向:

  3. # 3 楼答案

    所以在一年多之后我发现了这一点

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

    机制是,当请求时。getParameter(Name)被称为SavedRequestCacheWrapper,然后将实际的HTTP请求参数与最后一个请求中存储的参数连接起来

    解决方案是:(a)让这个拦截器忽略重置密码屏幕,(b)忽略所有post请求,以防止这种请求参数值串联

    感谢其他响应者,感谢所有的好主意。(还有那个悬赏的匿名用户——谢谢你让我回去再看一眼。)

  4. # 4 楼答案

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

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

    此外,请参见this other response了解为什么数据可能位于用户会话中,例如,您在某处使用了@SessionAttributes注释

  5. # 5 楼答案

    看起来旧值以某种方式显示为GET参数,即第二种形式是<form action = ".../account/reset?password=abc">,或者action是空的,第二种形式本身的URL是.../account/reset?password=abc。虽然我在你的代码里找不到任何原因

  6. # 6 楼答案

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