public class YourAction {私人列表<对象>级别列表;//私人的私人列表<对象>主题列表;//私人的公共字符串执行()抛出异常{//调用服务,加载数据levelList = getMyService().getLevelList();subjectList = getMyService().getSubjectList();//转发到 JSP返回成功;}公共列表<对象>getLevelList() {返回级别列表;}公共列表<对象>获取主题列表(){返回主题列表;}}
并在您的 JSP 中,而不是:
<块引用>
你像这样访问列表(丑陋的 HTML/Struts2 混合方式):
或者,在选择的情况下,使用适当的 Struts2 UI 选择标签:
<s:select name = "subject_id"列表=主题列表"listKey = "id"listValue = "名称"/>
如果一开始分离所有的层太难了,把Actions中的前三个层次展平,只是为了理解如何分离Java(Action)和Struts2 UI标签(JSP).理解后,您可以将 DAO 逻辑移至业务层,最好移至 EJB.实现后,再次以更大的粒度拆分...
Action 将是这样的:
public class YourAction {私人列表<对象>级别列表;//私人的私人列表<对象>主题列表;//私人的公共字符串执行()抛出异常{会话 session2 = HibernateUtil.getSessionFactory().getCurrentSession();交易 tx = session2.beginTransaction();查询 q = session2.createQuery("来自主题");主题列表 = q.list();levelList = session2.createQuery("from Level").list();//转发到 JSP返回成功;}公共列表<对象>getLevelList() {返回级别列表;}公共列表<对象>获取主题列表(){返回主题列表;}}
I have a edit page in which I want to retrieve the subjects and levels from database and display as select option for user to edit the course.
When the form is submitted, it will make a new request , the user input is captured by courseBean with XML validation. When the XML validation failed, it will forward with the courseBean which just captured the user input to the edit.jsp.
So every time I go the edit.jsp, I will retrieve the database records. Should I do it in that way?
Besides, I tried to retrieve the subject lit and level lit and store them as the request attribute in the action class which displays edit.jsp at the first time. But when the new request is made from the user input, the subject list and level list retrieved from the database will be no longer available.
Using Struts2 you won't need to use Scriptlets (<% stuff %>) anymore. They're old, bad, they're business logic injected in view pages, do not use them. You do not need JSTL neither, just using Struts2 tags you can achieve any result.
For a better decoupling and separation of code and concepts, you should have:
DAO Layer: it does just the plain queries;
BUSINESS Layer: it exposes the DAO Layer results through Service(s), aggregating multiple DAOs calls and performing several business operations when needed;
PRESENTATION Layer: The Actions, that in Struts2 acts as the Model; here you call the Service from the Business Layer, to retrieve the objects needed by the JSP;
JSP (VIEW Layer): the JSP contains the plain HTML, and accesses the data needed through the Accessors (Getters) of the Action, and eventually any other needed element from the Value Stack (#session, #request, etc).
should be in DAO/Business Layers, exposed by two function like getSubjectList(); and getLevelList();. Then in your Action you should have something like:
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;
}
}
or, in the case of a Select, with the proper Struts2 UI Select Tag:
<s:select name = "subject_id"
list = "subjectList"
listKey = "id"
listValue = "name" />
If separating all the layers is too difficult at the beginning, flatten the first three levels in the Actions, just to understand how to separata Java (Action) and Struts2 UI Tags (JSP).
When understood, you can move the DAO logic to the business layer, preferably into an EJB. When achieved that, split again with more granularity...
The Action will be something LIKE this:
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;
}
}
About your question on multiple loading of the lists, you can use a cache (better if with a timer) if the list is fixed (it changes one a month for example), or loading it every time, there aren't problems in doing that.
Please note that if validation fails, the ValidationInterceptor will forward the request to the JSP mapped in the INPUT type result, without reaching the execute() method, so you should implement Preparable interface from Action and put the loading stuff into prepare() method, execute every time by the 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;
}
}
Proceed by steps, the framework is easy and powerful, the web has plenty of examples and StackOverflow provides some great support...