是否可以返回ResultSet以在JSTL中使用?

时间:2010-11-26 13:11:37

标签: java database jsp jstl

是否可以将ResultSet变量返回到JSTL foreach标记?我得到零点错误,并且由于错误的原因,它说db2.MyServ类不存在,即使它就在那里。任何人都知道我做错了什么以及如何在jstl上对我的ResultSet rs进行迭代?

MyServ2类(省略导入等)

     package db2;

public class MyServ2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       private DBClass db;
       private ResultSet rs;

    public MyServ2() {
        super();
        db = new DBClass();
        db.dbConnect("jdbc:oracle:thin:@elanweb:1510:xxxxx", "xxxxx", "xxx");

    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        rs = db.getResultSet(request.getParameter("query"));
        try {
            while(rs.next()){
                System.out.println(rs.getString(1).toString());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }


    public ResultSet getRs()
    {
        return rs;
    }

}

的index.jsp

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

    <%@ page import="db2.MyServ2" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html>
<head>
</head>
<body>
successful login
<jsp:useBean id="myserv2" class="db2.MyServ2"/>

<c:if test="${myserv2.rs.Next()}">
<c:forEach var="person" items="${myserv2.rs}">
<c:out value="${myserv2.rs.string(1).toString()}"></c:out>
</c:forEach>
</c:if>
</body>
</html>

我已经创建了一个bean并为其保存了字符串。当我从我的MyServ2类调用它们进行调试时,它们工作正常,但当我从我的网页上调用它们为jstl时,它们返回null,就好像bean没有填充一样。一旦我重定向回网页,一切都会重置吗?

<jsp:useBean id="mybean" class="beans.UserBean"></jsp:useBean>

<c:out value="${mybean.name}"></c:out><br></br>

在MyServ类中添加以下内容

rs = db.getResultSet(request.getParameter("query"));
    try {
        while(rs.next()){
            mybean.SetName(rs.getString(1).toString());
            mybean.Setsurname( rs.getString(2).toString());
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

2 个答案:

答案 0 :(得分:4)

这不是一个好主意。完全没有。

你在哪里关闭Resultset?和连接?您应该提供一种可靠的方式来释放这些资源,否则可能会导致您的应用程序出现严重问题。

此外,在HttpServlet中将连接设置为实例值通常被认为是一种不好的做法,因为您必须为所有Servlet实时保持活动状态。此外,如果存在通信问题,则需要重新启动应用程序以使servlet重新连接。不要谈论在serlvet实例级别保存结果集,以及它可能导致的所有并发问题。

在JavaBean上映射要在JSP上使用的rs行不会那么难。并尝试重构代码以进行正确的数据库连接处理。

编辑:在最后一段代码中,我看到您仍然在servlet实例中保存数据。这可能会导致并发问题。 检查一下:

Resultset rs=null; //declare a local variable
try {
    //wrong code get the query from the request parameter! 
    // rs = db.getResultSet(request.getParameter("query"));
    String query="select col from table where a='b'"; // whatever
    rs = db.getResultSet(query);
    //just one value? no need of while
    if(rs.next()){
        MyBean bean=new MyBean();
        bean.setName(rs.getString(1));
        bean.setSurname(rs.getString(2));
        //here is where you put your bean to the request
        request.setAttribute("myBean", bean);
    }
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    //Don't forget closing your Rs
    if(rs!=null) {rs.close();}
}

然后,使用JSTL,您可以使用setAttribute方法设置的名称访问请求attrbitue,与上一个JSP示例非常相似:

<c:out value="${myBean.name}" /><br></br>
<c:out value="${myBean.surname}" /><br></br>

答案 1 :(得分:3)

我的简单答案是否定的,原因有多种:

  • ResultSet不符合JavaBeans规范(它没有getter / setters方法,并且不可序列化)。

而是,将ResultSet填充到bean中,并使用JSTL从bean中检索数据。


对于您编辑过的帖子,我建议将它们全部一起删除(如BalusC评论,它可以导致SQL注入)并遵循JavaBeans的注释。

这是我的意思的一个例子:

JavaBean用户:

public class UserEntity implements Serializable {

 private String firstName;
 private String middleName = "";
 private String lastName;
 private Gender gender;
 private String emailAddress;
 private Date birthDate;
        private boolean searchable = false;

        //Getters and Setters here...

}

MySQLUserDAO开始,我从ResultSet映射了我的实体(javabean)。

protected UserEntity mapEntity(ResultSet rs) throws SQLException {
  // TODO Auto-generated method stub
  UserEntity user = null;

  if (rs != null) {
   user = new UserEntity();

   user.setId(rs.getLong("USER_ID"));
   user.setFirstName(rs.getString("FIRST_NAME"));
   user.setMiddleName(rs.getString("MIDDLE_NAME"));
   user.setLastName(rs.getString("LAST_NAME"));
   user.setEmailAddress(rs.getString("EMAIL_ADDRESS"));

   String gender = rs.getString("GENDER");
   if ("M".equals(gender)) {
    user.setGender(Gender.MALE);
   } else if ("F".equals(gender)) {
    user.setGender(Gender.FEMALE);
   }

   user.setBirthDate(rs.getDate("DOB"));
   user.setCreationDate(rs.getDate("CREATION_DATE"));
                        user.setSearchable(rs.getBoolean("SEARCHABLE"));
  }

  return user;
 }

最后,retrieve()方法(来自MySQLUserDAO)。

public UserEntity retrieve(Long id) throws DAOException {
  // TODO Auto-generated method stub
  PreparedStatement ps = null;
  ResultSet rs = null;
  UserEntity user = null;

  try {
   ps = getConnection().prepareStatement(SQL_RETRIEVE);
   ps.setLong(1, id);
   rs = ps.executeQuery();
   if (rs != null && rs.next()) {
    user = mapEntity(rs);
   }
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   throw new DAOException(e);
  } finally {
   try {
    close(rs, ps);
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    logger.error("Error closing statement or resultset.", e);
   }
  }

  return user;
 }

现在,要将UserEntity用于JSP,我会......

UserEntity user = MySQLUserDAO.retrieve(userId); //Pseudocode....
request.setAttribute("user", user);

使用JSTL,我可以这样做:

<c:out value="${user.firstName}">

其中user是请求中的属性名称(返回UserEntity user)和firstName调用user.getFirstName()(来自UserEntity的方法)。

希望您遵循BalusC的榜样。