Я пытаюсь отобразить некоторые данные из моей базы данных с помощью следующего метода, но он показывает только значения NULL. Я не уверен, что у меня есть правильная реализация метода, поэтому, если что-то мне нужно изменить при вызове метода select (). Спасибо заранее за любую помощь.
// метод SELECT
public Res select(int id) {
Res res = new Res();
Connection connection = null;
PreparedStatement preparedStm = null;
ResultSet resultSet = null;
try {
connection = ConnectionConfiguration.getConnection();
preparedStm = connection.prepareStatement("SELECT * FROM res WHERE id = ?");
preparedStm.setInt(1, id);
resultSet = preparedStm.executeQuery();
while(resultSet.next()) {
res.setId(resultSet.getInt("id"));
res.setDay(resultSet.getString("res"));
res.setNoRooms(resultSet.getString("rooms"));
res.setNoNights(resultSet.getString("nights"));
res.setRoomType(resultSet.getString("room_type"));
res.setUser_email(resultSet.getString("email"));
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStm != null) {
try {
preparedStm.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return res;
}
// Отображение страницы JSP
<h1 align = "center"> Reservation </h1><br>
<% Reservation r = new Reservation();
Res rb = new Res();
r.select(rb.getId());
%>
<table border = "1" width = "50%" align = "center">
<tr><th colspan = "3">Date</th><th>Rooms</th><th>Nights</th><th>Room type</th><th>
Comments</th><th>Status</th></tr>
<tr><td><%= rb.getDay() %><td>
<%=rb.getRooms() %></td><td><%=rb.getNights() %></td><td><%=rb.getRoomType() %></td>
</table>
Res - это еще один класс (класс Bean), у которого есть геттеры и сеттеры резервирования.
Вы получаете null, потому что на странице jsp при объявлении Res rb = new Res()
нет значения для rb.getId()
.
как мне тогда сложить значения? не могли бы вы проинструктировать меня
@Stephanie Хотите динамически получать значение для разных пользователей?
Пожалуйста, опубликуйте этот класс сервлета и страницу резервирования
Во-первых, стоит отметить, что мы больше не используем скриптлеты. Вот некоторая информация, объясняющая почему:
The use of scriptlets (those
<% %>
things) in JSP is indeed highly discouraged since the birth of taglibs (like JSTL) and EL (Expression Language, those${}
things) way back in 2001.The major disadvantages of scriptlets are:
- Reusability: you can't reuse scriptlets.
- Replaceability: you can't make scriptlets abstract.
- OO-ability: you can't make use of inheritance/composition.
- Debuggability: if scriptlet throws an exception halfway, all you get is a blank page.
- Testability: scriptlets are not unit-testable.
- Maintainability: per saldo more time is needed to maintain mingled/cluttered/duplicated code logic.
SunOracle itself also recommends in the JSP coding conventions to avoid use of scriptlets whenever the same functionality is possible by (tag) classes. Here are several cites of relevance:From JSP 1.2 Specification, it is highly recommended that the JSP Standard Tag Library (JSTL) be used in your web application to help reduce the need for JSP scriptlets in your pages. Pages that use JSTL are, in general, easier to read and maintain.
...
Where possible, avoid JSP scriptlets whenever tag libraries provide equivalent functionality. This makes pages easier to read and maintain, helps to separate business logic from presentation logic, and will make your pages easier to evolve into JSP 2.0-style pages (JSP 2.0 Specification supports but deemphasizes the use of scriptlets).
...
In the spirit of adopting the model-view-controller (MVC) design pattern to reduce coupling between the presentation tier from the business logic, JSP scriptlets should not be used for writing business logic. Rather, JSP scriptlets are used if necessary to transform data (also called "value objects") returned from processing the client's requests into a proper client-ready format. Even then, this would be better done with a front controller servlet or a custom tag.
Цитата выше взята из этого замечательного ответа: Как избежать кода Java в файлах JSP?
Хорошо, теперь вы понимаете, почему не следует использовать скриптлеты. Так как еще мы должны делать то, что хотим делать на наших страницах JSP? Здесь на помощь приходят JSTL и EL. Все, что вам нужно сделать, чтобы использовать JSTL в своем проекте (если вы не используете maven), - это загрузить файл JSTL .jar: https://mvnrepository.com/artifact/javax.servlet/jstl/1.2 и включить его в папку lib
(т.е. внутри WEB-INF). Если у вас нет папки, создайте ее и добавьте туда файл .jar. Здесь - отличный ресурс, показывающий все, что вы можете с ним делать.
Затем, чтобы использовать его в своем JSP, просто включите основную библиотеку в верхней части файла JSP:
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
Теперь вернемся к вашему вопросу. Проблема здесь:
Reservation r = new Reservation();
Res rb = new Res();
r.select(rb.getId());
когда вы здесь rb.getId () и вот так, вы получаете null, потому что вы, по сути, делаете это:
SELECT * FROM reservations WHERE id = null
потому что вы создали новый объект прямо перед этой строкой без установки идентификатора (или чего-либо еще)
Res rb = new Res();
Что вам нужно сделать, так это передать объект из вашего сервлета, а затем вы можете его использовать. (без создания нового объекта res)
например, если вы это сделаете, он должен работать:
Reservation r = new Reservation();
Res rb = new Res();
rb.setId(1); //set the id
r.select(rb.getId());
Но опять же, вы не хотите этого делать. Потому что в нем задействованы скриптлеты. И они отстой. Поскольку теперь в вашем проекте есть jstl, вот пример того, как это сделать с JSTL:
ReservationStatus.jsp:
<h1 align = "center"> Reservation </h1><br>
<table border = "1" width = "50%" align = "center">
<tr>
<th colspan = "3">Date</th>
<th>Rooms</th>
<th>Nights</th>
<th>Room type</th>
<th>Comments</th>
<th>Status</th>
</tr>
<tr>
<td>${Reservation.day}</td>
<td>${Reservation.month}</td>
<td>${Reservation.year}</td>
<td>${Reservation.noRooms}</td>
<td>${Reservation.noNights}</td>
<td>${Reservation.roomType}</td>
<td>${Reservation.comments}</td>
<td>${Reservation.status}</td>
</table>
Привет, уборщик, верно? На самом деле вам не нужен JSTL для этого, потому что здесь вы используете только EL.
Но опять же, если вы просто попытаетесь напрямую перейти на страницу jsp, вы ничего не увидите. Вам нужен сервлет для передачи данных в jsp. Что я бы сделал, чтобы вам было легче это проверить, так это изменить doPost на doGet в вашем сервлете RESERVATION. Таким образом, если ввести URL-адрес, отображаемый для этого сервлета в вашем браузере: http: // localhost: 9191 / ReservationServletUrl, он запустит сервлет и перенаправит детали в jsp. (потому что doPost недоступен через url напрямую, только doGet есть)
Надеюсь это поможет. Дайте мне знать, если у вас возникнут проблемы с пониманием чего-либо!
На самом деле я не хочу использовать setId (1); поскольку я должен получить идентификатор автоматически из getId (); метод, так как я «не знаю» идентификатора каждого пользователя, который будет регистрироваться и делать резервирование. Это проблема, с которой я столкнулся, так как я не знаю, как получить идентификатор. Может быть, я могу использовать session.setAttribute (); чтобы передать идентификатор из сервлета на страницу jsp, но теперь я знаю, как сохранить идентификатор, так как я могу получить его только из БД, поэтому должен ли я запускать другой запрос?
Ах я вижу. Но вы не получаете идентификатор автоматически, потому что вы не устанавливаете его нигде после создания нового объекта Res
. Вы можете создать метод, который будет получать последнюю вставленную строку или идентификатор строки, к которой он принадлежит, а затем передавать ее, но все это кажется чрезмерным усложнением. Но да, можно также установить идентификатор в качестве переменной сеанса, что, безусловно, сработает. Если вы передаете данные из сервлета в jsp, ничего из этого делать не нужно. Трудно дать вам лучшее решение, потому что я не понимаю, как вы его настроили. Могли бы помочь вам в teamviewer
Я немного смущен (или даже встревожен, смеется), почему вы создаете таблицу каждый раз, когда вызываете сервлет? ud.createTable();
Без проблем. Трудно понять, как все это связано, не имея на что ссылаться. Я чувствовал то же самое, когда только начинал идти по этому пути, и это было совершенно понятно. Так что я рад помочь.
из любопытства, какой URL отображается, когда вы находитесь на странице, на которой ожидаете увидеть результаты? И как именно вы это инициируете? Отправляете форму? Вход в систему?
Понятно, но вы не можете сделать это таким образом .. out.println
полностью лишает смысла наличие jsp (для просмотра содержимого). И вам нужен jsp, если вы хотите легко стилизовать страницу, добавить такие функции, как кнопки, взаимодействовать с сервлетами ... Я полагаю, вы могли бы сделать все это с помощью сервлета, но это непрактично - никто так не делает.
Какой URL вы видите, когда находитесь на странице, на которой ожидаете увидеть результаты? (если бы я знал это, я мог бы лучше сказать вам, как вы можете решить свою проблему)
Позвольте нам продолжить обсуждение в чате.
Я изменил его и поместил код в сервлет, как показано ниже, и теперь я отображаю данные, используя адрес электронной почты, так как это все упрощает. Я сделал это следующим образом.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession s = request.getSession();
ResBean res = new ResBean();
Connection connection = null;
PreparedStatement preparedStm = null;
ResultSet resultSet = null;
String user_email = String.valueOf(s.getAttribute("uemail"));
PrintWriter out = response.getWriter();
out.println("<html><body><center><h1> Reservation Status</h1></center><br><h4 align=\"center\"> Rezervimi nga perdoruesi me email: " + user_email);
out.println("<table border=\"1\" width=\"50%\" align=\"center\">");
out.println("<tr><th colspan=\"3\">Data</th><th>Numri i dhomave</th><th>Numri i neteve</th>"
+ "<th>LLoji i dhomes</th><th>\r\n" +
"Kerkesa</th><th>Statusi</th></tr>");
try {
connection = ConnectionConfiguration.getConnection();
preparedStm = connection.prepareStatement("SELECT * FROM reservations WHERE user_email = ?");
preparedStm.setString(1, user_email);
resultSet = preparedStm.executeQuery();
while(resultSet.next()) {
res.setDay(resultSet.getString("res_day"));
res.setMonth(resultSet.getString("res_month"));
res.setYear(resultSet.getString("res_year"));
res.setNoRooms(resultSet.getString("no_rooms"));
res.setNoNights(resultSet.getString("no_nights"));
res.setRoomType(resultSet.getString("room_type"));
res.setComments(resultSet.getString("add_comments"));
res.setStatus(resultSet.getString("res_status"));
res.setUser_email(resultSet.getString("user_email"));
out.println("<tr><td>" + res.getDay() +"</td><td>"+ res.getMonth() + "</td><td>" + res.getYear() +"</td><td>"
+ res.getNoRooms() + "</td><td>" + res.getNoNights() + "</td><td>" + res.getRoomType() + "</td><td>" +
res.getComments() + "</td><td>" + res.getStatus() + "</td></tr>");
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStm != null) {
try {
preparedStm.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
out.println("</table></body></html>");
}
}
оу, а как же тогда заставить пользователя взаимодействовать со страницей? разве вы не хотите иметь кнопки и вещи, на которые они могут нажимать? распечатка страницы таким образом не позволит вам делать эти вещи.
Убедитесь, что
resultSet
имеет допустимые значения (распечатав их или используя отладчик). Как определяетсяRes
?