Thymeleaf+Spring Boot搜索后URL变更致页面渲染404错误
解决Spring Boot+Thymeleaf搜索后URL异常导致404的问题
问题背景
用Thymeleaf开发前端、Spring Boot开发后端,现有用户列表页面,需实现搜索功能:搜索过滤后在原页面展示,同时URL要带上搜索参数(类似/registeredUsers/0?keyword=xxx的形式)。
现有默认加载用户列表的控制器代码:
@GetMapping("/registeredUsers/{page}") public String registeredUsers(Model model, @PathVariable("page") Integer page) { model.addAttribute("title", "Registered User"); // PageRequest pageable =PageRequest.of(page, perPageResultCount); Pageable pageable = PageRequest.of(page, perPageResultCount); int totalNumberOfRegisteredUser = this.userRepository.findAll().size(); Page<Users> listOfUserDetails = this.userRepository.findAll(pageable); List<Users> listOfUsers = listOfUserDetails.getContent(); model.addAttribute("totalNumberOfRegisteredUser", totalNumberOfRegisteredUser); model.addAttribute("totalPage", listOfUserDetails); model.addAttribute("detailsOfTotalRegisteredUsers", listOfUsers); model.addAttribute("registeredUserClass", "active"); model.addAttribute("currentPage", page); model.addAttribute("totalPages", listOfUserDetails.getTotalPages()); //model.addAttribute("queryParameter", queryParameter); return "/admin/registeredUsers"; }
搜索控制器代码:
@GetMapping("/searchKeyword/{page}") public String searchKeyword(@RequestParam("keyword") String keyword, Model model, @PathVariable("page") Integer page) { model.addAttribute("pageNum", page); List<Users> listOfUsers = this.userRepository.searchByKeyword(keyword); model.addAttribute("detailsOfTotalRegisteredUsers", listOfUsers); return "/admin/registeredUsers"; }
当前问题:搜索控制器返回/admin/registeredUsers页面,但URL变为/searchKeyword/{page},导致页面404,因为不存在/admin/searchKeyword/0这类页面。
解决方案
1. 合并路由逻辑,复用原接口
不需要单独创建/searchKeyword/{page}接口,直接在原有的/registeredUsers/{page}接口中添加可选的keyword请求参数,统一处理默认加载和搜索逻辑,这样URL会保持在/registeredUsers/{page}路径下,同时可以带上搜索参数:
修改后的控制器代码:
@GetMapping("/registeredUsers/{page}") public String registeredUsers(Model model, @PathVariable("page") Integer page, @RequestParam(value = "keyword", required = false) String keyword) { model.addAttribute("title", "Registered User"); Pageable pageable = PageRequest.of(page, perPageResultCount); Page<Users> listOfUserDetails; int totalNumberOfRegisteredUser; // 判断是否有搜索关键词 if (keyword != null && !keyword.trim().isEmpty()) { // 执行分页搜索 listOfUserDetails = this.userRepository.searchByKeyword(keyword, pageable); totalNumberOfRegisteredUser = (int) listOfUserDetails.getTotalElements(); } else { // 默认加载全部用户 listOfUserDetails = this.userRepository.findAll(pageable); totalNumberOfRegisteredUser = (int) listOfUserDetails.getTotalElements(); } List<Users> listOfUsers = listOfUserDetails.getContent(); model.addAttribute("totalNumberOfRegisteredUser", totalNumberOfRegisteredUser); model.addAttribute("totalPage", listOfUserDetails); model.addAttribute("detailsOfTotalRegisteredUsers", listOfUsers); model.addAttribute("registeredUserClass", "active"); model.addAttribute("currentPage", page); model.addAttribute("totalPages", listOfUserDetails.getTotalPages()); model.addAttribute("keyword", keyword); // 回显搜索关键词到页面搜索框 return "/admin/registeredUsers"; }
2. 调整前端搜索表单
确保搜索表单提交到原路由,使用GET方法,这样URL会自动带上keyword参数:
<form th:action="@{/registeredUsers/0}" method="get"> <input type="text" name="keyword" th:value="${keyword}" placeholder="输入关键词搜索"/> <button type="submit">搜索</button> </form>
3. 修复Repository的搜索方法
原searchByKeyword返回List<Users>不支持分页,需要修改为返回Page<Users>,示例如下:
public interface UserRepository extends JpaRepository<Users, Long> { @Query("SELECT u FROM Users u WHERE u.username LIKE %?1% OR u.email LIKE %?1%") Page<Users> searchByKeyword(String keyword, Pageable pageable); }
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

