使用来自JavaBean的数据在JSP页面中填充复选框

时间:2013-02-13 09:23:16

标签: java jsp servlets jstl javabeans

我有一个JSP页面,其中包含HTML表单中的复选框,如下所示

enter image description here

现在,在编辑用户 Skill 时,我想从表中获取逗号分隔值并填充JSP中的复选框。以下代码从数据库表中提供了CSV技能。

      List<UserDetails> Skills = new ArrayList<UserDetails>();

      pstmt = (PreparedStatement) conn.prepareStatement(strSQL);
      rs    = pstmt.executeQuery();       
      String strSkills = rs.getString("Skills");

      List<String> items = Arrays.asList(strSkills.split("\\s*,\\s*"));

      objUserDetails.setSkills(items.toArray(new String[0]));

      Skills.add(objUserDetails);

      return Skills;

现在我需要填充JSP中的复选框,并选中相应的技能。我使用了Request getAttribute()方法,我将传递给JSP,如下所示

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{
   dbUtil objdbUtil     = new dbUtil();
   List<UserDetails> Skills = objdbUtil.getSkills();

   request.setAttribute("arrSkills", Skills);
   RequestDispatcher rqst = request.getRequestDispatcher("Skills.jsp");
   rqst.forward(request, response);
}

如何使用我在arrSkills数组中获得的技能并填充复选框。我尝试使用

<c:forEach var="account" items="${arrUsersList}">
    <input type="checkbox" name="chkSkills" id="chkPHP" value="PHP"/>PHP
    <input type="checkbox" name="chkSkills" id="chkJava" value="Java"/>Java
    <input type="checkbox" name="chkSkills" id="chkMySQL" value="MySQL"/>MySQL
    <input type="checkbox" name="chkSkills" id="chkJavascript" value="Javascript"/>Javascript
    <input type="checkbox" name="chkSkills" id="chkJQuery" value="JQuery"/>JQuery
    <input type="checkbox" name="chkSkills" id="chkNode" value="Node"/>Node Js
</c:forEach>

但我确信这不是使用它的正确方法。

1 个答案:

答案 0 :(得分:13)

检查你的例子,这里有一些注释。

1)与技能变量相关 在Java中,按惯例的变量,实例变量和类变量是用CamelCase 编写的,首字母小写

阅读Java naming conventions的维基百科文章 另请参阅第9章关于Code Conventions for the Java™ Programming Language的命名约定。

所以这会更好:

List<UserDetails> skills = new ArrayList<UserDetails>();

2)再次与你的技能变量相关 您将其命名为技能,但从您的代码中可以清楚地看出,技能只是一个 UserDetails 对象的属性。我正在做一个假设,但 UserDetails 类只关于用户技能?如果,那么最好以某种方式在类名中反映出来,比如 UserSkills 。 否则,如果技能只是用户详细信息之一,那么这样的事情会更好:

List<UserDetails> userDetailsList = new ArrayList<UserDetails>();

同样,强烈建议使用有意义的变量名称。阅读上面的命名约定

3)调用Connection.prepareStatement()方法时,您不需要转换为 PreparedStatement ,因为它已经返回 PreparedStatement 对象。所以就这样做:

pstmt = conn.prepareStatement(strSQL); 

作为对您的问题的回答,当然您可以使用JSTL中的<c:forLoop>,例如来迭代所有用户的列表并输出每个用户的相关详细信息。这是一种常见的做法。

你的问题不太清楚,但让我猜一下 在您的示例中,您只有有限的技能列表,我的意思是只有PHP,Java,MySQL,JavaScript,jQuery,Node.js,并且对于每个用户,您希望检查相关的复选框如果用户具有相应的技能。

如果上述假设是正确的,那么就是可能的解决方案之一


设置包含数组的属性或所需技能的列表。

考虑到列表仅限于预定义值,您可以将该列表存储在ServletContext中,以便整个应用程序可以使用它。最好在实现ServletContextListener的类中设置此类全局对象。

示例: AppContextListener.java

package com.example.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        String[] skills = {"PHP", "Java", "MySQL", "JavaScript", "jQuery", "Node.js"};
        event.getServletContext().setAttribute("skills", skills);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {

    }
} 

NB!为了接收这些通知事件(contextInitialized,contextDestroyed),实现类必须在Web应用程序的部署描述符中声明,使用WebListener注释,或者通过以下方式之一注册: ServletContext上定义的addListener方法。在这里,我使用了@WebListener注释。

我没有时间深入了解架构细节,但对于此示例,我假设有一个类 User ,其中包含用户相关信息。其中包含以Map<String, Boolean>实现的属性技能。它有getter和setter(如public Map<String, Boolean> getSkills()public void setSkills(Map<String, Boolean> skills))。

示例: User.java

package com.example.model;

import java.util.Date;
import java.util.Map;

public class User {

    private String fisrtName;
    private String lastName;
    private Date birthday;
    ...
    private Map<Sting, Boolean> skills;

    // getters and setters here
}


在某个地方,在一个servlet中处理通过doPost()方法提交的数据提交的数据,您可以填充用户技能和其他详细信息。像这样的东西(简化例子):

User user = new User();
// set the user related data like first name or something like that
...
// get the list of available skills from ServletContext
String[] skills = (String[]) getServletContext().getAttribute("skills");
Map<String, Boolean> userSkills = new HashMap<String, Boolean>();

// Set the appropriate skills
for (String skill: skills) {
    if (request.getParameter(skill) != null) {
        userSkills.put(skill, true);
    } else {
        userSkills.put(skill, false);
    }
}

...
// Set user skills
user.setSkills(userSkills);
...

这样你就不会对技能的名称进行硬编码,否则你可以这样做:

...
Map<String, Boolean> userSkills = new HashMap<String, Boolean>();
if (request.getParameter("PHP") != null) {
    userSkills.put("PHP", true);
} else {
    userSkills.put("PHP", false);
}
// the same way for Java, MySQL and others
...


现在在一些servlet中,将所有用户作为例如List<User> users,在请求范围中设置一个属性,如request.setAttribute("users", users)来存储用户列表并转发到某个视图(JSP页面)将输出与所有用户相关的数据。

输出用户相关数据的JSP页面的简单示例: users.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
    <title>Test Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <%-- We iterate thru all the users --%>
    <c:forEach items="${users}" var="user">
        <!-- Outputting different user related data -->
        ...
        <!-- Now outputting the user skills -->
        <h3>User skills</h3>
        <%-- In the inside loop, we iterate thru all the available skills, stored in the ServletContext --%>
        <c:forEach items="${skills}" var="skill">
            <c:choose>
                <%-- If the user has the appropriate skill, the related checkbox will be checked. Otherwise unchecked. --%>
                <%-- Note: using skill as a key in the map of user skills --%>
                <c:when test="${user.skills[skill] == true}">
                    <input type="checkbox" name="chkSkills" value="${skill}" checked="checked">${skill}&nbsp;
                </c:when>
                <c:otherwise>
                    <input type="checkbox" name="chkSkills" value="${skill}">${skill}&nbsp;
                </c:otherwise>
            </c:choose>
        </c:forEach>
    </c:forEach>
</body>
</html>

或使用<c:if>代码的更紧凑的变体 users.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
    <title>Test Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <c:forEach items="${users}" var="user">
        ...
        <h3>User skills</h3>
        <c:forEach items="${skills}" var="skill">
            <%-- Note: here <c:if> tag is used right inside <input> tag --%>
            <input type="checkbox" name="chkSkills" value="${skill}" <c:if test="${user.skills[skill]}">checked="checked"</c:if>>${skill}&nbsp;
        </c:forEach>
    </c:forEach>
</body>
</html>

注意
在JSP中注释JSP特定的代码部分,更好地以
<%-- Some comment --%>的形式使用 JSP注释。与HTML注释(以<!-- Some comment -->的形式)不同,JSP注释将不会在将发送给客户端的结果页面中显示。


希望这会对你有所帮助并提供一些有用的想法。