在这里,我使用此 link 创建了动态下拉列表,但是当我从可用列表中选择某个值时,应该在操作类中调用它。
在图像中可以看到下拉列表,这里的值是从数据库动态加载的,现在我想要的是,当我从这两个下拉列表中选择任何值时,该值(我的意思是文本值)应该发送到操作类,我将根据这两个值执行一个 JDBC 选择查询,并将显示在图像中显示的表中,但所有内容都应该加载。操作应该是从下拉列表中选择值,而不是单击任何按钮。静态值我可以使用 name
属性将下拉列表中的值调用到操作类中。但在这种情况下我不能:(
我希望我现在清楚了。
我尝试使用 listkey、name 和 id 调用 select 标签,但没有一个起作用。
下面是我的 JSP 代码:
<div>
<div class="invoicetext1">Event Name :</div>
<s:select name="dp.eventState"
list="%{state}"
class="billlistbox1"
id="eventName" />
<div>
<s:select name="dp.companyState"
class="billlistbox2"
listKey="companyState"
list="%{status}">
</s:select>
</div>
<div class="invoicetext2">Company Name :</div>
<div class="clear"></div>
</div>
<s:form action="ActionSelect">
<s:submit value=" Click Here"/>
</s:form>
<div>
用于加载动态下拉列表的操作类:
package com.ca.actions;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.ca.database.Database;
import com.ca.pojo.Event;
import java.sql.PreparedStatement;
import com.opensymphony.xwork2.ActionSupport;
public class RetrieveEvNaCoNaAction extends ActionSupport {
private static final long serialVersionUID = -5418233715172672477L;
List<Event> dataForBillsJspList;
private List state = new ArrayList();
private List status = new ArrayList();
String eventName;
public String getEventName() {
return eventName;
}
public void setEventName(String eventName) {
this.eventName = eventName;
}
public RetrieveEvNaCoNaAction() {
// TODO Auto-generated constructor stub
}
public List<Event> getDataForBillsJspList() {
return dataForBillsJspList;
}
public void setDataForBillsJspList(List<Event> dataForBillsJspList) {
this.dataForBillsJspList = dataForBillsJspList;
}
public List getStatus() {
return status;
}
public void setStatus(List status) {
try {
Database database = new Database();
Connection con = database.Get_Connection();
PreparedStatement ps = con
.prepareStatement("SELECT EVENT_NAME,COMPANY_NAME,date_format(FROM_DATE,'%d/%m/%Y') as dateAsFrom,date_format(TO_DATE,'%d/%m/%Y') as dateAsTo FROM EVENT");
ResultSet rs = ps.executeQuery();
//dataForBillsJspList = new ArrayList<Event>();
while (rs.next()) {
/*dataForBillsJspList.add(new Event(rs.getString("EVENT_NAME"),
rs.getString("COMPANY_NAME"), rs
.getString("dateAsFrom"), rs
.getString("dateAsTo")));
System.out.println(rs.getString("EVENT_NAME"));*/
status.add(rs.getString("COMPANY_NAME"));
}
System.out.println("Data Collected ...");
}catch(Exception e)
{
e.printStackTrace();
}
}
public List getState() {
return state;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
setState(this.state);
setStatus(this.status);
return "success";
}
public String showEventDetails(){
System.out.println("Hi.."+eventName);
return SUCCESS;
}
public void setState(List state) {
//implement the application specific logic to
try {
Database database = new Database();
Connection con = database.Get_Connection();
PreparedStatement ps = con
.prepareStatement("SELECT EVENT_ID,EVENT_NAME,COMPANY_NAME,CONTACT_PERSON,CONTACT_NO,EMAIL_ID,EVENT_VENUE,date_format(FROM_DATE,'%d/%m/%Y') as dateAsFrom,date_format(TO_DATE,'%d/%m/%Y') as dateAsTo ,EVENT_TIME FROM EVENT");
ResultSet rs = ps.executeQuery();
dataForBillsJspList = new ArrayList<Event>();
while (rs.next()) {
dataForBillsJspList.add(new Event(rs.getString("EVENT_ID"),rs.getString("EVENT_NAME"),
rs.getString("COMPANY_NAME"),rs.getString("CONTACT_PERSON"),rs.getString("CONTACT_NO"),rs.getString("EMAIL_ID"),rs.getString("EVENT_VENUE"), rs
.getString("dateAsFrom"), rs
.getString("dateAsTo"),rs.getString("EVENT_TIME")));
//System.out.println(rs.getString("EVENT_NAME"));
state.add(rs.getString("EVENT_NAME"));
System.out.println(rs.getString("EVENT_ID"));
}
System.out.println("Data Collected ...");
}catch(Exception e)
{
e.printStackTrace();
}
//Here for displaying the data on UI, we are using few hardcoded values//
}
}
加载动态下拉列表后,现在我尝试通过 S.O.P 调用操作类中的选定值,但它给出了空指针异常。下面是我的 POJO 类:
package com.ca.pojo;
public class Dropdown
{
private String eventState;
private String companyState;
public Dropdown() {
// TODO Auto-generated constructor stub
}
public String getEventState() {
return eventState;
}
public void setEventState(String eventState) {
this.eventState = eventState;
}
public String getCompanyState() {
return companyState;
}
public void setCompanyState(String companyState) {
this.companyState = companyState;
}
}
下面是操作类,我尝试使用名称属性调用该选定值:
package com.ca.actions;
import com.ca.pojo.Dropdown;
import com.opensymphony.xwork2.ActionSupport;
public class DropdownAction extends ActionSupport
{
Dropdown dp;
public DropdownAction() {
// TODO Auto-generated constructor stub
}
public Dropdown getDp() {
return dp;
}
public void setDp(Dropdown dp) {
this.dp = dp;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println(dp.getEventState());
return "success";
}
}
struts.xml 已正确配置。现在,在选择两个值之后,我想在下表中相应地显示数据,而无需单击任何按钮,但在 jsp 中,我创建了按钮,只是为了查看是否在操作类中获取所选值,但实际上我希望无需单击任何按钮。
最佳答案
好吧,这里一团糟:D
首先,抛出 NullPointerException 是因为值未发送,而值未发送是因为它们不在表单中。
您应该将它们附在这样的表格中,以便将它们发送到 ActionSelect
行动:
<s:form action="ActionSelect">
<div class="invoicetext1">Event Name :</div>
<s:select name="dp.eventState"
list="%{state}"
class="billlistbox1"
id="eventName" />
<div>
<s:select name="dp.companyState"
class="billlistbox2"
listKey="companyState"
list="%{status}">
</s:select>
</div>
<div class="invoicetext2">Company Name :</div>
<div class="clear"></div>
</div>
<s:submit value=" Click Here"/>
</s:form>
解决了这个谜题,但这并不能解决你的问题。
您有两种主要方式来联系页面中的操作:
使用标准提交(正如您所做的那样):
您可以提交包含其内容的表单,或者通过最终在查询字符串中传递参数来调用链接。这将创建一个请求,该请求将联系一个操作,该操作将返回整个 JSP,该 JSP 将加载到您现在所在的页面的位置。
使用 AJAX:
您可以在不更改当前页面的情况下对某个操作进行 POST 或 GET,并且该操作可以返回任何内容,例如 JSP 片段、JSON 结果、二进制结果(通过 Struts2 Stream 结果)等...
然后您可以选择如何处理返回的数据,例如将其加载到
<div>
中之前是空的,或者有不同的内容。
现在你的问题是你正在联系一个不是你来自的 Action (无法重新渲染你所在的整个JSP)并且你在不使用AJAX的情况下调用它,然后无论对象映射到 "success"
结果是(整个 JSP 或 JSP 片段),它将代替您所在的 JSP 进行加载,并且会失败。
由于您对此似乎很陌生,因此我建议您从简单的解决方案(不使用 AJAX)开始,在熟练掌握之后,下次尝试使用 AJAX。
也就是说,
- 避免将逻辑放入 getter 和 setter 中;
- 避免将非 setter 的方法调用为 setter(
setState
、setStatus
...); - 始终将您的属性设为私有(private);
- 尝试为变量命名:事件状态和公司状态的状态和状态确实令人困惑;那么用“state”代替“name”怎么样(在jsp和DB中是“name”);
- 考虑加载信息,例如
prepare()
中的选择框内容方法,因此在出现错误时它们也可用; - 您没有关闭连接(顺便说一句,最好使用更先进的东西,例如 Spring JDBC,或更好的 Hibernate,甚至更好的 JPA,但现在继续使用原始查询)
以下是对代码的重构,以使其实现目标。我将使用@Getter
和@Setter
仅用于语法糖(它们是 Lombok 注释,但您继续使用 getter 和 setter,这只是为了清楚起见):
<head>
<script>
$(function(){
$("#event, #company").on('change',function(){
$("#myForm").submit();
});
});
</script>
</head>
<body>
<form id="myForm">
<div>
...
<s:select id="event" name="event" list="events" />
...
<s:select id="company" name="company" list="companies" />
...
</div>
</form>
<div>
...
Table - iterate **dataForBillsJspList** here
...
</div>
</body>
public class RetrieveEvNaCoNaAction extends ActionSupport {
private static final long serialVersionUID = -5418233715172672477L;
@Getter private List<Event> dataForBillsJspList = new ArrayList<Event>();
@Getter private List<String> events = new ArrayList<String>();
@Getter private List<String> companies = new ArrayList<String>();
@Getter @Setter private String event = null;
@Getter @Setter private String company = null;
@Override
public void prepare() throws Exception {
Connection con;
try {
con = new Database().Get_Connection();
// load companies
PreparedStatement ps = con.prepareStatement("SELECT DISTINCT company_name FROM event");
ResultSet rs = ps.executeQuery();
while (rs.next()) { companies.add(rs.getString("company_name")); }
// load events
ps = con.prepareStatement("SELECT DISTINCT event_name FROM event");
rs = ps.executeQuery();
while (rs.next()) { events.add(rs.getString("event_name")); }
} catch(Exception e) {
e.printStackTrace();
} finally {
con.close();
}
}
@Override
public String execute() {
Connection con;
try {
con = new Database().Get_Connection();
// load the table. The first time the table is loaded completely
String sql = "SELECT EVENT_ID, EVENT_NAME, COMPANY_NAME, CONTACT_PERSON, CONTACT_NO, EMAIL_ID, EVENT_VENUE, " +
"date_format(FROM_DATE,'%d/%m/%Y') as dateAsFrom, date_format(TO_DATE,'%d/%m/%Y') as dateAsTo ,EVENT_TIME " +
"FROM event";
String where = "";
// if instead this action has been called from the JSP page,
// the result is filtered on event and company:
if (event!=null && company!=null) {
where = " WHERE event_name = ? AND company_name = ?";
}
// load companies
PreparedStatement ps = con.prepareStatement(sql + where);
if (where.length()>0) {
ps.setString(1,event);
ps.setString(2,company);
}
ResultSet rs = ps.executeQuery();
while (rs.next()) {
dataForBillsJspList.add(new Event(rs.getString("EVENT_ID"),rs.getString("EVENT_NAME"),rs.getString("COMPANY_NAME"),
rs.getString("CONTACT_PERSON"),rs.getString("CONTACT_NO"),rs.getString("EMAIL_ID"),
rs.getString("EVENT_VENUE"), rs.getString("dateAsFrom"), rs.getString("dateAsTo"),
rs.getString("EVENT_TIME")));
}
} catch(Exception e) {
e.printStackTrace();
} finally {
con.close();
}
return SUCCESS;
}
}
这是一个启动示例,但它应该可以工作。
接下来的步骤是:
- 创建一个带有 ID 和描述的 POJO,在选择框中显示描述,但发送 ID
- 使用 header 值(“请选择一个事件”...)并在操作条件 WHERE 中进行处理(仅公司、仅事件、两者)
- 分页
祝你好运
关于java - 如何使用struts2从动态创建的下拉列表中选择值后调用操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37291791/