Можно ли вернуть ResultSet для работы в JSTL?

можно ли вернуть переменную ResultSet в тег JSTL foreach? Я получаю ошибку с нулевой точкой, и по неправильной причине он говорит, что класс db2.MyServ не существует, хотя он здесь. кто-нибудь знает, что я делаю неправильно и как перебрать мой ResultSet rs на jstl?

Класс 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();
    }

person code511788465541441    schedule 26.11.2010    source источник
comment
См. также: stackoverflow.com/questions/2280034 / и stackoverflow.com/questions/1727603 /   -  person BalusC    schedule 26.11.2010
comment
Пожалуйста, не сохраняйте свой bean-компонент в сервлете: одновременные вызовы сервлета перезапишут ваши значения!. Используйте request.setAttribute(name, bean); в сервлете и получить к нему доступ через EL в JSP...   -  person Tomas Narros    schedule 26.11.2010
comment
@Том. Я не понимаю. Не могли бы вы написать пример, пожалуйста.   -  person code511788465541441    schedule 26.11.2010
comment
Отредактировал мой ответ. Взгляните на него, чтобы узнать, как отправить значение в запрос. Как вы увидите, в классе servvet нет свойства myBean, а создается новый экземпляр каждый раз, когда он вам нужен.   -  person Tomas Narros    schedule 26.11.2010
comment
Хотел бы ответить, но там слишком много не так с кодом, что надо все переделывать. Посмотрите ссылки, которые я предоставил, чтобы понять, как это сделать правильно. Прежде всего не передавайте строку запроса SQL в качестве параметра запроса! Это открывает широко двери для атак с внедрением SQL.   -  person BalusC    schedule 26.11.2010
comment
@ user521180, BalusC дал вам 2 важные ссылки, на которые вы могли бы сослаться. Отредактированный пост — это очень плохая практика.   -  person Buhake Sindi    schedule 26.11.2010
comment
@BalusC: хорошая мысль. Я пропустил это.   -  person Tomas Narros    schedule 26.11.2010
comment
Я собирался представить Шаблон DAO в качестве справочного руководства, но воздержусь от него.   -  person Buhake Sindi    schedule 26.11.2010
comment
@Tom, как мне теперь получить доступ к bean-компоненту со страницы jsp? @BalusC @Elite У меня ужасное программирование, я только начал. но я буду больше читать о правильном способе ведения дел, начиная с предложенных ссылок. Благодарность   -  person code511788465541441    schedule 26.11.2010
comment
@ user521180: отредактировал мой ответ.   -  person Tomas Narros    schedule 26.11.2010
comment
Спасибо вам обоим. На выходных постараюсь лучше понять.   -  person code511788465541441    schedule 26.11.2010


Ответы (2)


Это не очень хорошая идея. Нисколько.

Где вы закрываете набор результатов? А Связь? Вы должны предоставить надежный способ освобождения этих ресурсов, иначе это может вызвать серьезные проблемы в вашем приложении.

Более того, установка соединения в качестве значения экземпляра в HttpServlet обычно считается плохой практикой, потому что вы должны поддерживать его в рабочем состоянии на протяжении всего сервлета. Кроме того, если есть проблемы со связью, вам нужно будет перезапустить приложение, чтобы ваш сервлет снова подключился. Не говоря уже о сохранении набора результатов на уровне экземпляра serlvet и обо всех проблемах параллелизма, которые это может вызвать.

Отображение ваших строк rs в JavaBean для использования в JSP не будет таким сложным. И попробуйте реорганизовать свой код для правильной обработки подключения к базе данных.

EDIT: В вашем последнем фрагменте кода я вижу, что вы все еще сохраняете данные в экземпляре сервлета. Это может привести к проблемам параллелизма. Проверь это:

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, вы уже можете получить доступ к атрибуту запроса, очень похожему на ваш последний пример JSP, используя имя, установленное в методе setAttribute:

<c:out value="${myBean.name}" /><br></br>
<c:out value="${myBean.surname}" /><br></br>
person Tomas Narros    schedule 26.11.2010

Мой простой ответ - нет по разным причинам:

  • ResultSet не соответствует спецификации JavaBeans (у него нет методов получения/установки и он не сериализуем) .

Скорее заполните свой 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 я сопоставил свою сущность (javabean) с ResultSet.

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.

person Buhake Sindi    schedule 26.11.2010
comment
Однако есть JSTL sql taglib, но его использование не рекомендуется для других целей, кроме быстрого прототипирования/демонстрации. - person BalusC; 26.11.2010
comment
@BalusC, о да! Я забыл про taglib. Спасибо за обновление. - person Buhake Sindi; 26.11.2010
comment
отредактировал оригинальный пост. смотри конец пожалуйста - person code511788465541441; 26.11.2010