我有一个编辑页面,我想在其中从数据库中检索 主题 级别 并显示为用户编辑 类(class) 的选择选项。

当表单被提交时,它会发出一个新的请求,用户输入被 courseBean 用 XML 验证捕获。当 XML 验证失败时,它会将 courseBean 转发给 edit.jsp ,它刚刚捕获了用户输入。

所以每次我去 edit.jsp 时,我都会检索数据库记录。我应该那样做吗?

此外,我尝试检索 主题 lit level lit 并将它们作为请求属性存储在第一次显示 edit.jsp 的 Action 类中。但是当从用户输入发出新请求时,从数据库中检索到的 主题列表 级别列表 将不再可用。

代码(edit.jsp):

<%
    Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = session2.beginTransaction();
    Query q = session2.createQuery("from Subject");
    List subjectList = q.list();
    List levelList = session2.createQuery("from Level").list();
%>

<div class="control-group">
    <label class="control-label" for="inputPassword">Subject</label>
    <div class="controls">
        <select name="subject_id">
            <%
                for (Object subjectObject : subjectList) {
                    Subject subject = (Subject) subjectObject;
            %>
            <option value="<%=subject.getId()%>"><%=subject.getName()%></option>
            <%  } //end for %>
        </select>
    </div>
</div>

<div class="control-group">
    <label class="control-label" for="inputPassword">Level</label>
    <div class="controls">
        <select name="level_id">
            <%
                for (Object levelObject : levelList) {
                    Level level = (Level) levelObject;
            %>
            <option value="<%=level.getId()%>"><%=level.getName()%></option>
            <%  } //end for %>
        </select>
    </div>
</div>

最佳答案

使用 Struts2,您将不再需要使用 Scriptlet ( <% stuff %> )。它们是旧的,坏的,它们是在 View 页面中注入(inject)的业务逻辑,不要使用它们。您也不需要 JSTL,只需使用 Struts2 标签就可以实现任何结果。

为了更好地解耦和分离代码和概念,您应该:

  • DAO Layer :它只做简单的查询;
  • BUSINESS Layer :通过Service(s)暴露DAO层的结果,聚合多个DAO调用,在需要的时候执行多个业务操作;
  • PRESENTATION Layer : Actions,在Struts2中作为Model;在这里,您从业务层调用服务,以检索 JSP 所需的对象;
  • JSP (VIEW Layer) :JSP 包含纯 HTML,并通过 Action 的访问器 (Getter) 访问所需的数据,并最终访问值堆栈中的任何其他所需元素( #session#request 等)。

    在您的示例中,所有这些



  • 应该在 DAO/业务层中,由两个函数公开,如 getSubjectList();getLevelList(); 。然后在你的 Action 中你应该有类似的东西:

    public class YourAction {
    
        private List<Object> levelList; // private
        private List<Object> subjectList; // private
    
        public String execute() throws Exception {
            // Call the service, load data
            levelList = getMyService().getLevelList();
            subjectList = getMyService().getSubjectList();
    
            // Forwarding to the JSP
            return SUCCESS;
        }
    
        public List<Object> getLevelList() {
            return levelList;
        }
        public List<Object> getSubjectList() {
            return subjectList;
        }
    
    }
    

    并在您的 JSP 中,而不是:



    您可以像这样访问列表(丑陋的 HTML/Struts2 混合方式):

    <select name="subject_id">
        <s:iterator value="subjectList">
            <option value="<s:property value="id"/>">
                <s:property value="name"/>
            </option>
        </s:iterator>
    </select>
    

    或者,在选择的情况下,使用适当的 Struts2 UI 选择标签:

    <s:select name = "subject_id"
              list = "subjectList"
           listKey = "id"
         listValue = "name" />
    

    如果一开始分离所有的层太难了,把Actions中的前三层展平,只是为了理解如何分离Java(Action)和Struts2 UI标签(JSP)。
    理解后,您可以将 DAO 逻辑移至业务层,最好移至 EJB。实现后,再次以更大的粒度拆分......

    Action 将是这样的:

    public class YourAction {
    
        private List<Object> levelList; // private
        private List<Object> subjectList; // private
    
        public String execute() throws Exception {
                Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
                Transaction tx = session2.beginTransaction();
                Query q = session2.createQuery("from Subject");
                subjectList = q.list();
                levelList = session2.createQuery("from Level").list();
    
            // Forwarding to the JSP
                return SUCCESS;
        }
    
        public List<Object> getLevelList() {
            return levelList;
        }
        public List<Object> getSubjectList() {
            return subjectList;
        }
    }
    

    关于多次加载列表的问题,如果列表是固定的(例如每月更改一个),您可以使用缓存(如果有计时器更好),或者每次都加载它,这样做没有问题那。
    请注意,如果验证失败,ValidationInterceptor 会将请求转发到 INPUT 类型结果中映射的 JSP,而不会到达 execute() 方法,因此您应该从 Action 实现 Preparable 接口(interface)并将加载的东西放入 prepare() 方法中,执行每个PrepareInterceptor 的时间

    public class YourAction implements Preparable {
    
        private List<Object> levelList; // private
        private List<Object> subjectList; // private
    
        public void prepare() throws Exception {
            // Call the service, load data,
            // every time even if validation fails
            levelList = getMyService().getLevelList();
            subjectList = getMyService().getSubjectList();
        }
    
        public String execute() throws Exception {
    
            // Forwarding to the JSP
            return SUCCESS;
        }
    
        public List<Object> getLevelList() {
            return levelList;
        }
        public List<Object> getSubjectList() {
            return subjectList;
        }
    }
    

    循序渐进,框架简单而强大,网络上有大量的例子,StackOverflow 提供了一些很好的支持......

    关于java - 我应该在 Struts2 View 层中检索数据库记录吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13833456/

    10-09 07:08
    查看更多