如何从XHTML获取Bean的字符串变量并传递给列表查询方法以更新结果列表?
如何将JSF页面输入值传递到Bean并更新查询结果列表?
首先,你得先补上searchWord的getter和setter方法——JSF是通过这些方法来实现页面和Bean之间的数据绑定的,没有的话页面输入的值根本传不到Bean里去。另外,你原来把查询逻辑直接写在getSearchList()里也有问题:每次页面渲染调用这个getter时,都会重新创建SessionFactory并执行查询,不仅性能拉胯,也不符合逻辑。咱们一步步来改:
1. 重构你的Bean类
先完善属性的读写方法,把查询逻辑抽成单独的方法,还要注意避免SQL注入的风险(你之前用字符串拼接的方式很危险):
public class ProductsController { private String searchWord; private List<Product> searchList; // 把SessionFactory做成单例,避免每次查询都重复创建,浪费资源 private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); // 给searchWord添加getter和setter,JSF需要这些来绑定页面输入 public String getSearchWord() { return searchWord; } public void setSearchWord(String searchWord) { this.searchWord = searchWord; } // 单独的搜索方法,由页面按钮触发 public String searchProducts() { Session session = sessionFactory.openSession(); try { session.beginTransaction(); // 使用参数绑定替代字符串拼接,彻底避免SQL注入 Query query = session.createQuery("From Product where name LIKE :searchPattern"); query.setParameter("searchPattern", searchWord + "%"); searchList = query.list(); session.getTransaction().commit(); } finally { // 确保session关闭,避免资源泄漏 session.close(); } return "success"; // 这里可以返回你需要的导航结果,比如留在当前页面就返回null或者"" } // getSearchList只负责返回已查询好的列表,不再执行查询逻辑 public List<Product> getSearchList() { return searchList; } }
2. 修改XHTML页面,添加输入和触发按钮
在你的form里加上搜索输入框和提交按钮,还要用AJAX来局部刷新表格,提升用户体验:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Products</title> </h:head> <h:body> <h:form id="id-form" > <!-- 添加搜索输入框,绑定到Bean的searchWord属性 --> <h:inputText id="searchInput" value="#{products_controller.searchWord}" placeholder="输入产品名称前缀"/> <!-- 搜索按钮,点击触发Bean的searchProducts方法,并用AJAX刷新表格 --> <h:commandButton value="搜索" action="#{products_controller.searchProducts}"> <f:ajax render="productTable" /> </h:commandButton> <h2><h:outputText value ="List of all products"></h:outputText></h2> <!-- 给表格加上id,方便AJAX定位刷新 --> <h:dataTable id="productTable" style="border: 4px solid black;" value = "#{products_controller.searchList}" rows="#{products_controller.searchList.size()}" var = "item" border="1" headerClass="tableHeader" > <h:column> <f:facet name="header"> Product ID </f:facet> <h:outputText value="#{item.p_id}" /> </h:column> <h:column> <f:facet name="header"> Product Name </f:facet> <h:outputText value="#{item.p_name}" /> </h:column> <h:column> <f:facet name="header"> Product Class </f:facet> <h:outputText value="#{item.p_class}" /> </h:column> <h:column> <f:facet name="header" > Product price </f:facet> <h:outputText value="#{item.p_price}" /> </h:column> <h:column> <f:facet name="header"> Product Description </f:facet> <h:outputText value="#{item.p_property}" /> </h:column> <h:column> <f:facet name="header"> Product Total </f:facet> <h:outputText value="#{item.p_total}" /> </h:column> </h:dataTable> </h:form> </h:body> </html>
关键要点说明
- getter/setter的必要性:JSF的EL表达式
#{products_controller.searchWord}底层是通过调用getSearchWord()和setSearchWord()来读写属性的,没有这两个方法,页面输入的值根本传不到Bean里。 - 避免SQL注入:用
setParameter绑定参数的方式,能防止恶意用户输入特殊字符篡改你的SQL语句,比直接字符串拼接安全得多。 - SessionFactory单例:每次创建SessionFactory都是重量级操作,做成单例能大幅提升性能,避免资源浪费。
- AJAX局部刷新:
<f:ajax render="productTable">会让点击按钮后只刷新表格部分,不用整页重载,用户体验更好。
内容的提问来源于stack exchange,提问作者user023835
相关产品推荐
相关产品推荐

