
Продолжаем работу по совмещению ajax и сервлетов (Java). В первой части мы уже начали изучать, что можно сделать с get методом на примере одной строки. Там при нажатии на кнопку в jsp-странице выводили на экран нужные данные, которые уже после загрузки документа запрашивали у сервлета.
Сегодня время заняться списками. Начнём со списка строк, а потом уже будет подтягивать список объектов из базы данных.
Структура проекта.
Если вам лень перечитывать первую часть этого цикла, то вкратце напомню, как выглядит проект и на каком примере я вообще всё происходящее показываю. Я работаю с системой уведомлений. Есть у меня класс NotificationsDAOImpl, который взаимодействует с базой данных. Сервлет Notifications, который обитает по адресу /notifications, и страничка notificationstest.jsp, на которой мы щёлкаем на кнопку и получаем дополнительные данные с бэк-энда:
@WebServlet("/notifications")
public class Notifications extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (action == null) {
request.getRequestDispatcher(path + "notificationtest.jsp").forward(request, response);
}
if (action!= null && action.equalsIgnoreCase("test")) {
User user = getCurrentUserFromSession();
Long count = NotificationsDAOImpl.countByUser(user);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(count.toString());
}
}
}
В прошлой части статьи я вывел на экран число уведомлений для текущего юзера, который прошёл авторизацию. При открытии странички /notifications пользователь видел форму с кнопкой, а при нажатии на неё /notifications?action=test возвращал нужную информацию в виде текста. Теперь двигаемся дальше.
Возвращаем из сервлета список строк List<String> в виде Json.
Что должен делать наш сервлет, если мы хотим получить список строк? Логично, что сначала нужно создать этот список и наполнить его тестовыми строками. В моём случае это три строки. После этого преобразуем данные в формат Json и записываем их в response.
List<String> list = new ArrayList<>();
list.add("notification1");
list.add("notification2");
list.add("notification3");
String json = new Gson().toJson(list);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
Чтобы всё работало, в ваш pom.xml нужно добавить зависимость:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>compile</scope>
</dependency>
Подробнее об этом инструменте можно почитать у разработчиков: github. Там и примеры использования есть.
Обратите внимание, что на этот раз мы устанавливаем тип контента application/json, а не text/plain, как было раньше – в первой части статьи.
Теперь notificationstest.jsp будет выглядеть следующим образом:
<!DOCTYPE html>
<head>
<title>Уведомления (тест)</title>
<script>
$(document).on("click", "#testbutton", function() {
$.get("notifications?action=test", function(responseJson) {
var $ul = $("<ul>").appendTo($("#testdiv"));
$.each(responseJson, function(index, item) {
$("<li>").text(item).appendTo($ul);
});
});
});
</script>
</head>
<body>
<div class="container">
<h1>Тест уведомлений</h1>
<button id="testbutton">Жми</button>
<div id="testdiv">Эта строка должна замениться на список строк</div>
</div>
</body>
</html>
Поменялся здесь только небольшой скрипт. При нажатии на кнопку мы просим responseJson, с которым далее и работаем: добавляем маркированный список, где каждый элемент нашего списка будет отображаться на новой строчке (элемент <li> ). Ну и в этом примере мы используем appendTo, так что при каждом клике по кнопке страница будет дополняться тремя элементами списка.
Возвращаем объекты в виде Json
Мы поработали со строками во всех видах, но теперь пришло время решить более жизненную задачу и вместо строк доставать из базы данных целые объекты. В моём проекте пока такой надобности нет, но из любопытства я попробую и этим заняться. Для начала посвящу вас, с каким объектом я буду работать. Раз уж начал с системой уведомлений, то речь пойдёт как раз об уведомлениях – класс Notifications.
@Entity
@Table(name = "notifications", schema = "work")
public class Notifications {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="date")
private Date date;
@ManyToOne
@JoinColumn (name = "sender")
private User sender;
@ManyToOne
@JoinColumn (name = "receiver")
private User receiver;
@Column(name="message")
private String message;
@Column(name="is_read")
private int isRead;
}
Ничего необычного: ключ, дата, получатель, отправитель, само сообщение и флаг о прочтении. Ну и чтобы получить список всех уведомлений для конкретного юзера, в NotificationsDAOImpl есть метод List<Notifications> getByUser(User reciever). На входе юзер, на выходе – список его уведомлений.
User user = getCurrentUserFromSession();
List<Notifications> notifications = NotificationsDAOImpl.getByUser(user);
String json = new Gson().toJson(notifications);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
А вот и происходящее в сервлете. Сначала получаем залогиненного юзера из метода getCurrentUserFromSession(), который я уже упоминал в прошлой статье. Потом получаем список уведомлений для этого юзера и преобразуем их в Json. Ну и уже записываем в ответ, чтобы обработать на jsp-странице.
<!DOCTYPE html>
<head>
<title>Уведомления (тест)</title>
<script>
$(document).on("click", "#testbutton", function() {
$.get("notifications?action=test", function(responseJson) {
var $table = $("<table>").appendTo($("#testdiv"));
$.each(responseJson, function (index, notification) {
var receiverName = notification.receiver.userName;
var senderName = notification.sender.userName;
$("<tr>").appendTo($table)
.append($("<td>").text(notification.id))
.append($("<td>").text(notification.date))
.append($("<td>").text(receiverName))
.append($("<td>").text(senderName))
.append($("<td>").text(notification.message));
});
});
});
</script>
</head>
<body>
<div class="container">
<h1>Тест уведомлений</h1>
<button id="testbutton">Жми</button>
<div id="testdiv">Эта строка должна замениться на таблицу с уведомлениями</div>
</div>
</body>
</html>
Обработка крайне простая: после нажатия на кнопку просто приписываем в нужный div табличку по кусочкам. Обращаемся ко всем полям объекта по очереди. Ну и так как поля получатель и отправитель (receiver и sender) это тоже объекты, то, чтобы не получить вывод [Object object] или что-нибудь в этом роде, выводим поле userName, в котором хранится имя пользователя.
На сегодня всё – потом дополню эти две статьи туториалом по методу post. А с get-ом вроде разобрались.