使用 Struts2,您将不再需要使用Scriptlet
s ( <% stuff %>
)。它们很旧,很糟糕,它们是在视图页面中注入的业务逻辑,不要使用它们。您也不需要 JSTL,只需使用 Struts2 标签即可获得任何结果。
为了更好地解耦和分离代码和概念,您应该:
DAO Layer
:它只做简单的查询;
BUSINESS Layer
:它通过 (s) 暴露 DAO 层结果Service
,聚合多个 DAO 调用并在需要时执行多个业务操作;
PRESENTATION Layer
:动作,在 Struts2 中充当模型;这里你从业务层调用Service,来检索JSP需要的对象;
JSP (VIEW Layer)
:JSP 包含纯 HTML,并通过操作的访问器(Getter)访问所需的数据,并最终从值堆栈(、、等)中访问任何其他所需的#session
元素#request
。
在您的示例中,所有这些
<%
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();
%>
应该在 DAO/Business Layers 中,由 和 等两个函数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 中,而不是:
<select name="subject_id">
<%
for (Object subjectObject : subjectList) {
subject subject = (Subject) subjectObject;
%>
<option value="<%=subject.getId()%>"><%=subject.getName()%></option>
<%
} //end for
%>
</select>
您可以像访问列表一样(丑陋的混合 HTML/Struts2 方式):
<select name="subject_id">
<s:iterator value="subjectList">
<option value="<s:property value="id"/>">
<s:property value="name"/>
</option>
</s:iterator>
</select>
或者,对于 Select,使用正确的 Struts2 UI Select Tag:
<s:select name = "subject_id"
list = "subjectList"
listKey = "id"
listValue = "name" />
如果一开始分离所有层太难,把Actions中的前三个层次展平,只是为了了解如何分离Java(Action)和Struts2 UI Tags(JSP)。理解后,您可以将 DAO 逻辑移至业务层,最好移至 EJB。实现这一点后,以更细的粒度再次拆分...
动作将是这样的:
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 接口并将加载的东西放入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 提供了一些很好的支持...