java - 如何使用struts2从动态创建的下拉列表中选择值后调用操作

标签 java jsp struts2

在这里,我使用此 link 创建了动态下拉列表,但是当我从可用列表中选择某个值时,应该在操作类中调用它。 在图像中可以看到下拉列表,这里的值是从数据库动态加载的,现在我想要的是,当我从这两个下拉列表中选择任何值时,该值(我的意思是文本值)应该发送到操作类,我将根据这两个值执行一个 JDBC 选择查询,并将显示在图像中显示的表中,但所有内容都应该加载。操作应该是从下拉列表中选择值,而不是单击任何按钮。静态值我可以使用 name 属性将下拉列表中的值调用到操作类中。但在这种情况下我不能:(
我希望我现在清楚了。

Screenshot

我尝试使用 listkey、name 和 id 调用 select 标签,但没有一个起作用。
下面是我的 JSP 代码:

<div>
    <div class="invoicetext1">Event Name :</div>
        &nbsp;&nbsp;
        <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>
        &nbsp;&nbsp;
        <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。

也就是说,

  1. 避免将逻辑放入 getter 和 setter 中;
  2. 避免将非 setter 的方法调用为 setter( setStatesetStatus ...);
  3. 始终将您的属性设为私有(private);
  4. 尝试为变量命名:事件状态和公司状态的状态和状态确实令人困惑;那么用“state”代替“name”怎么样(在jsp和DB中是“name”);
  5. 考虑加载信息,例如 prepare() 中的选择框内容方法,因此在出现错误时它们也可用;
  6. 您没有关闭连接(顺便说一句,最好使用更先进的东西,例如 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;
    }

}

这是一个启动示例,但它应该可以工作。

接下来的步骤是:

  1. 创建一个带有 ID 和描述的 POJO,在选择框中显示描述,但发送 ID
  2. 使用 header 值(“请选择一个事件”...)并在操作条件 WHERE 中进行处理(仅公司、仅事件、两者)
  3. 分页

祝你好运

关于java - 如何使用struts2从动态创建的下拉列表中选择值后调用操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37291791/

相关文章:

java - 数据格式自动转换为父子格式

java - 如何从 j2me 应用程序调用 native 浏览器

java - 未知错误: call function result missing 'value' Appium Hybrid App

ajax - 使用Ajax处理表单时,模型addAttribute()无法加载到相应的JSP标签

java - 在 JSP 页面中动态读取应用程序映射的内容。 - 支柱2.0

java - Struts 2 表单标签中的多个提交按钮

java - Netty的SimpleChannelInboundHandler的子类可以共享吗?

mysql - 在 j2ee Web 应用程序中查找函数

struts2 - 使用 struts2 和 freemarker 创建 "yes"和 "no"单选按钮

java - 如何转换 struts2 中不是 SHORT 格式的日期?