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

通过out.println生成的JSP按钮无法执行Java代码的问题

问题分析与解决方案

你遇到的核心问题是混淆了服务器端代码和客户端代码的执行时机:

  • JSP里的<% %>代码是在服务器渲染页面时执行的后端逻辑;
  • 按钮的onclick是页面加载完成后,在浏览器中触发的客户端事件。

当你通过Java的out.println输出带<% %>的字符串时,服务器不会再解析这些标签,只会把它们当成普通文本输出到HTML里,所以绑定的Java代码根本不会被执行。直接在JSP里写按钮时,服务器会正常解析<% %>,所以代码能运行。

下面给出两种可行的解决方案:


方案一:使用表单提交(简单直接)

把每个按钮包装在一个表单里,点击按钮时提交表单到后端处理页面,传递菜品名称和数量参数。

修改getMenu方法:

public String getMenu(String Category) throws SQLException, IOException, ClassNotFoundException {
    Connection connection = Database.connectToDatabase();
    // 替换成PreparedStatement避免SQL注入风险
    String sql = "SELECT Name, Cost FROM MenuTable WHERE category = ?";
    PreparedStatement st = connection.prepareStatement(sql);
    st.setString(1, Category);
    ResultSet rs = st.executeQuery();
    
    String categoryMenu = "";
    while (rs.next()) {
        String itemName = rs.getString(1);
        categoryMenu += "<div class=\"menu-item\">\n"+
                    "<div class=\"menu-item-text\">\n"+
                        "<h3 class=\"menu-item-heading\">\n"+
                        "<form action=\"addToCart.jsp\" method=\"post\" style=\"display: inline;\">"+
                            "<input type=\"hidden\" name=\"itemName\" value=\"" + itemName + "\">"+
                            "<input type=\"hidden\" name=\"quantity\" value=\"1\">"+
                            "<button type=\"submit\">"+
                                "<span class=\"menu-item-name\">"+itemName+"</span>\n"+
                                "<span class=\"menu-item-price\">£"+rs.getString(2)+"</span>\n"+
                             "</button>"+
                        "</form>"+
                        "</h3>\n"+
                    "</div>\n"+
                "</div> \n";
    }
    
    // 务必关闭数据库资源
    rs.close();
    st.close();
    connection.close();
    return categoryMenu;
}

创建addToCart.jsp处理请求:

<%@ page import="Order" %>
<%
    request.setCharacterEncoding("UTF-8");
    String itemName = request.getParameter("itemName");
    int quantity = Integer.parseInt(request.getParameter("quantity"));
    
    if (itemName != null && !itemName.isEmpty()) {
        Order.inputIntoCtable(itemName, quantity);
        // 重定向回原页面,避免重复提交
        response.sendRedirect(request.getHeader("Referer"));
    }
%>

方案二:使用AJAX异步请求(无刷新体验更好)

通过JavaScript发送异步请求到后端接口,点击按钮时不刷新页面就能完成添加操作。

修改getMenu方法:

public String getMenu(String Category) throws SQLException, IOException, ClassNotFoundException {
    Connection connection = Database.connectToDatabase();
    PreparedStatement st = connection.prepareStatement("SELECT Name, Cost FROM MenuTable WHERE category = ?");
    st.setString(1, Category);
    ResultSet rs = st.executeQuery();
    
    String categoryMenu = "";
    while (rs.next()) {
        String itemName = rs.getString(1);
        categoryMenu += "<div class=\"menu-item\">\n"+
                    "<div class=\"menu-item-text\">\n"+
                        "<h3 class=\"menu-item-heading\">\n"+
                        "<button onclick=\"addToCart('" + itemName + "', 1)\">"+
                            "<span class=\"menu-item-name\">"+itemName+"</span>\n"+
                            "<span class=\"menu-item-price\">£"+rs.getString(2)+"</span>\n"+
                         "</button>"+
                        "</h3>\n"+
                    "</div>\n"+
                "</div> \n";
    }
    
    // 添加AJAX处理函数
    categoryMenu += "<script>\n"+
                    "function addToCart(itemName, quantity) {\n"+
                        "fetch('addToCartServlet', {\n"+
                            "method: 'POST',\n"+
                            "headers: {\n"+
                                "'Content-Type': 'application/x-www-form-urlencoded'\n"+
                            "},\n"+
                            "body: 'itemName=' + encodeURIComponent(itemName) + '&quantity=' + quantity\n"+
                        "})\n"+
                        ".then(response => response.text())\n"+
                        ".then(data => {\n"+
                            "console.log('添加成功:', data);\n"+
                            // 这里可以添加成功提示,比如弹出消息或更新购物车UI
                        "})\n"+
                        ".catch(error => console.error('添加失败:', error));\n"+
                    "}\n"+
                    "</script>";
    
    // 关闭数据库资源
    rs.close();
    st.close();
    connection.close();
    return categoryMenu;
}

创建AddToCartServlet后端接口:

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/addToCartServlet")
public class AddToCartServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        String itemName = request.getParameter("itemName");
        int quantity = Integer.parseInt(request.getParameter("quantity"));
        
        try {
            Order.inputIntoCtable(itemName, quantity);
            response.setContentType("text/plain");
            response.getWriter().write("添加成功");
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("添加失败: " + e.getMessage());
        }
    }
}

重要提醒

你原来的代码使用Statement拼接SQL字符串,存在严重的SQL注入风险,必须替换成PreparedStatement(上面的示例已经修改),这是Java数据库操作的基本规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:36:31