You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web应用添加「按流派搜索」功能异常,请求排查代码问题

问题排查与修复:流派筛选不生效返回全部数据

核心问题分析

你的代码存在三个关键问题导致流派筛选失效:

1. 数据库查询逻辑错误

findByKeyword方法中同时执行了关键词查询和流派查询,并将两个结果集的所有数据合并返回。即使选择了流派,也会先返回所有匹配关键词(关键词为空时是全部数据)的内容,再追加流派匹配的内容,最终结果就是全部数据。

2. 未处理流派参数为空的情况

Servlet中只处理了word为空的情况,没处理genre为空的场景。当用户未选择流派时,genre为null,传到DAO层后会生成Genre like "%null%"的查询条件,这显然不符合预期。

3. JSP按钮Value写法冗余且易出错

按钮的value属性使用<%= genre = "Fantasy" %>这种赋值表达式完全没必要,直接写固定字符串即可,否则如果genre变量未提前声明还会引发编译错误。


修复步骤

步骤1:修正JSP表单按钮

把按钮的value改为直接写流派名称,去掉冗余的JSP赋值(同时补充搜索框输入项,确保关键词功能正常):

<form action="ItemListController">
    <div class="btn-group me-2" role="group" aria-label="Genres">
        <button class="btn btn-outline-secondary" type="submit" name="gnr" value="Fantasy">Fantasy</button>
        <button class="btn btn-outline-secondary" type="submit" name="gnr" value="Action">Action</button>
        <button class="btn btn-outline-secondary" type="submit" name="gnr" value="FPS">FPS</button>
    </div>
    <input type="text" name="keyword" placeholder="搜索游戏..." value="${word}">
    <button type="submit">搜索</button>
</form>

步骤2:修正Servlet的参数处理

补充genre为空的处理,确保空参数不会干扰查询:

@WebServlet("/ItemListController")
public class ItemListController extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String word = request.getParameter("keyword");
        String genre = request.getParameter("gnr");

        // 处理空参数
        if (word == null) {
            word = "";
        }
        if (genre == null) {
            genre = "";
        }

        ItemModel im = new ItemModel();
        List<Item> items = im.findByKeyword(getServletContext(), word, genre);

        request.setAttribute("items", items);
        request.setAttribute("word", word);
        request.setAttribute("genre", genre);
        request.getRequestDispatcher("/itemListView3.jsp").forward(request, response);
    }

}

步骤3:重构DAO层的查询逻辑

根据word和genre的实际值动态生成SQL,实现关键词和流派的组合筛选,而不是分开查询再合并:

public List<Item> findByKeyword(ServletContext context, String word, String genre) {
    List<Item> result = new ArrayList<>();
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    try {
        Class.forName("org.sqlite.JDBC");
        String url = "jdbc:sqlite:" + context.getRealPath("WEB-INF/webapp.db");
        conn = DriverManager.getConnection(url);

        // 动态构建SQL条件,1=1用于简化条件拼接
        StringBuilder sqlBuilder = new StringBuilder("select * from games where 1=1");
        List<Object> params = new ArrayList<>();

        // 添加关键词筛选条件
        if (!word.isEmpty()) {
            sqlBuilder.append(" and GameName like ?");
            params.add("%" + word + "%");
        }

        // 添加流派筛选条件
        if (!genre.isEmpty()) {
            sqlBuilder.append(" and Genre like ?");
            params.add("%" + genre + "%");
        }

        sqlBuilder.append(" order by GameID");
        stmt = conn.prepareStatement(sqlBuilder.toString());

        // 批量设置参数
        for (int i = 0; i < params.size(); i++) {
            stmt.setObject(i + 1, params.get(i));
        }

        rs = stmt.executeQuery();

        // 封装结果集
        while (rs.next()) {
            Item item = new Item();
            item.setItemId(rs.getInt("GameID"));
            item.setItemName(rs.getString("GameName"));
            item.setGenre(rs.getString("Genre"));
            item.setDescription(rs.getString("Description"));
            item.setImage(rs.getString("GameCover"));
            item.setPrice(rs.getInt("Price"));
            item.setLink(rs.getString("Link"));
            result.add(item);
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 统一关闭数据库资源,避免连接泄漏
        try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (conn != null) conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return result;
}

额外优化说明

  • 资源管理:改用finally块统一关闭数据库连接、语句和结果集,避免内存泄漏。
  • 组合筛选:现在支持同时使用关键词和流派筛选,比如搜索"war"并选择"Action",会返回名称含war且流派为Action的游戏,符合常规搜索需求。

内容的提问来源于stack exchange,提问作者furkanzdm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:42:05