Tomcat登录校验遇索引越界:如何实现用户名不存在时返回null?
问题:用户名不存在时抛出索引越界异常,而非返回null并展示登录失败页面
你在Tomcat部署的Web应用里,登录校验方法在输入不存在的用户名时,抛出了Index 0 out of bounds for length 0错误,而不是返回null并跳转到登录凭证无效页面。咱们来一步步解决这个问题。
问题根源分析
你的validateUser方法里,当查询不到对应用户名的数据时,jdbcTemplate.query会返回一个空的Listusers.get(0)——空列表没有索引为0的元素,自然就抛出了索引越界异常。另外还有个隐藏问题:你的SQL是直接拼接用户名的,存在SQL注入风险,这个也得一起修复。
同时,你的控制器逻辑也有漏洞:不管校验是否成功,最后一行return mav = new ModelAndView("loginIncorrect");都会覆盖之前的正确视图,导致就算登录成功也会跳转到错误页面。
修复步骤
1. 修复validateUser方法
先判断查询结果是否为空,为空直接返回null;同时把SQL改成预编译方式避免注入:
public User validateUser(Login login) { // 使用预编译SQL,彻底避免SQL注入风险 String sql = "select * from users where username = ?"; // 传入参数执行查询 List<User> users = jdbcTemplate.query(sql, new Object[]{login.getUsername()}, new UserMapper()); // 先检查列表是否为空,为空直接返回null if (users == null || users.isEmpty()) { return null; } User user = users.get(0); String encodedPassword = user.getPassword(); String rawPassword = login.getPassword(); boolean isPasswordMatch = passwordEncoder.matches(rawPassword, encodedPassword); return isPasswordMatch ? user : null; }
2. 修复控制器逻辑
调整条件判断逻辑,避免错误覆盖正确视图:
@RequestMapping(value = "/loginProcess", method = RequestMethod.POST) public ModelAndView loginProcess(HttpServletRequest request, HttpServletResponse response, @ModelAttribute("login") Login login) { ModelAndView mav; User user = userService.validateUser(login); if (user != null) { // 登录成功:跳转处理页面并保存会话 mav = new ModelAndView("loginProcess", "firstname", user.getFirstname()); HttpSession httpSession = request.getSession(true); httpSession.setAttribute("User", user); } else { // 登录失败:跳转凭证无效页面 mav = new ModelAndView("loginIncorrect"); } return mav; }
额外提醒
- 预编译SQL是Web应用安全的基础操作,通过
?占位符传入参数,JDBC会自动处理参数转义,彻底杜绝SQL注入攻击。 - 对集合进行索引操作前,一定要先判断集合是否为空,这是防御性编程的常规手段,能避免绝大多数索引越界类异常。
内容的提问来源于stack exchange,提问作者Sahil Chabria
相关产品推荐
相关产品推荐

