Продолжаем писать простое джава веб приложение и сегодня пришло время рассмотреть, как работать с jstl тегами и как очень удобно отобразить информацию на jsp странице с их помощью. На повестке дня:
- подключение библиотеки jstl к проекту;
- использование тега forEach для вывода списка объектов;
- использование out для вывода объекта.
Начнем…
С JSP и JSTl мы уже частично знакомы из предыдущих статей. Теперь, давайте используем уже имеющиеся знания, дополним их и попробуем применить их в нашем простом сайте, который мы пишем уже несколько месяцев.
Для тех, кто тут впервые: мы пишем простое java веб приложение, с целью ознакомиться с основами веб программирования на джава. Весь цикл статей Вы сможете найти в разделе java web.
Прежде всего, чтобы отобразить информацию ее нужно добавить. Я вручную добавил несколько записей в нашу базу данных. В кого ничего не сохранилось вот вам дамп моей базы. Просто создайте файл с расширением sql вставьте содержимое и импортируйте в MySql. Для ленивых, в конце статьи будет ссылка на код гитхаб и в корне каталога будет дамп, который можно будет скачать. Для особенно ленивых, можно попробовать вставить как текст в консоль MySql (не гарантирую, что все заработает):
--
-- Host: localhost Database: simpleapp
-- ------------------------------------------------------
-- Server version 5.7.19-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `article`
--
DROP TABLE IF EXISTS `article`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `article` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(45) NOT NULL,
`body` varchar(3000) DEFAULT NULL,
`category_id` int(11) NOT NULL,
`users_id` int(11) NOT NULL,
PRIMARY KEY (`id`,`category_id`,`users_id`),
KEY `fk_article_category_idx` (`category_id`),
KEY `fk_article_users1_idx` (`users_id`),
CONSTRAINT `fk_article_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_article_users1` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `article`
--
LOCK TABLES `article` WRITE;
/*!40000 ALTER TABLE `article` DISABLE KEYS */;
INSERT INTO `article` VALUES (1,'First java program','My future content about java programming',1,1),(2,'SQL - helpful operations','My future content about SQL',2,1),(3,'Javascript as good frontend solution','My future content about javascript programming',3,1);
/*!40000 ALTER TABLE `article` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `category`
--
DROP TABLE IF EXISTS `category`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `category`
--
LOCK TABLES `category` WRITE;
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
INSERT INTO `category` VALUES (1,'java'),(2,'sql'),(3,'javascript');
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `role`
--
DROP TABLE IF EXISTS `role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (1,'admin'),(2,'user');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(45) NOT NULL,
`password` varchar(50) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_users_role1_idx` (`role_id`),
CONSTRAINT `fk_users_role1` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users`
--
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (1,'admin',NULL,NULL,1);
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-10-15 16:29:50
Базу данных наполнили, теперь можно приступить к слою представления. Как помним слой доступа к базе данных мы уже написали в статье: Работа с базой данных MySql в Java и договорились, что в этом проекте мы пропустим слой сервисом, а будем работать непосредственно через слой DAO.
Предлагаю вывести на главную страницу сайта все статьи, которые есть в базе. Для этого переходим в наш сервлет и создаем объект ArticleDao, который отвечает за работу с сущностью статьи. private ArticleDao articleDao = new ArticleDaoImpl().
Далее нужно выбрать в список все статьи и передать их на jsp. Делается это очень просто. Нужно поместить атрибут в HttpServletRequest request переменную.
Полный вид класса HomeServlet:
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.javamaster.dao.ArticleDao;
import com.javamaster.dao.impl.ArticleDaoImpl;
import com.javamaster.entity.Article;
import com.javamaster.entity.Category;
/**
* Servlet implementation class HomeServlet
*/
public class HomeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ArticleDao articleDao = new ArticleDaoImpl();
/**
* @see HttpServlet#HttpServlet()
*/
public HomeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getServletPath();
if (path.equals("/")){
List<Article> articles = articleDao.getAllArticles();
request.setAttribute("title", "Title of our application");
request.setAttribute("articles", articles);
request.getRequestDispatcher("/WEB-INF/view/index.jsp").forward(request, response);
}
else if (path.equals("/welcome")){
request.getRequestDispatcher("/WEB-INF/view/welcome.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Как видно из кода выше, используя метод setAttribute() можно поместить как объект, так и список объектов.
Теперь стоит задача получить наши атрибуты на странице jsp. В данном случае нам отлично поможет библиотека jstl тегов, в которой есть все необходимое для работы с объектами. В крайнем случае, Вы всегда можете написать свой собственный тег. Я обязательно напишу статью, как создавать собственные теги, но уверяю, jstl библиотеки вполне хватает для стандартных ситуаций.
Для того, чтобы использовать библиотеку ее нужно подключить к нашему проекту.
Да, это очевидные вещи, но практика показывает, что лучше все таки об этом упомянуть. Вводим в гугле фразу jstl maven и первая ссылка будет весть на репозиторий нашей библиотеки. Или можете просто скопировать код ниже.
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
Полный код pom.xml:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javamaster</groupId>
<artifactId>simplewebapp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>simplewebapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
</dependencies>
<build>
<finalName>simplewebapp</finalName>
</build>
</project>
Далее подключаем библиотеку jstl непосредственно на нашей странице: <%@ taglib prefix=“c“ uri=“http://java.sun.com/jsp/jstl/core“ %>
Чтобы вывести значение атрибута title можно воспользоваться тегом out: <c:out value=”${attribute}”>
В нашем случае: <title><c:out value=”${title}”></title>. Данный атрибут можно заменить на ${attribute} – выражение.
Для вывода списка объектов воспользуемся тегом forEach:
<c:forEach var="variable" items="${variableList}" > <tr><td><c:out value="${variable.parameter}"></td></tr> </c:forEach>
Строку <c:out value=“${variable.parameter}”> можно заменить на ${variable.parameter}
Пример с нашего проекта. Весь код index.jsp очень большой (никак не приведу его в порядок), так что выложу только часть. Весь код будет по ссылке в конце статьи.
<c:forEach items="${articles}" var="article">
<div class="row">
<article class="col-xs-12">
<h2>${article.title}</h2>
<p>${article.body}</p>
<p><button class="btn btn-default">Read More</button></p>
<p class="pull-right"><span class="label label-default">keyword</span> <span class="label label-default">tag</span> <span class="label label-default">post</span></p>
<ul class="list-inline">
<li><a href="#">Today</a></li>
<li><a href="#"><span class="glyphicon glyphicon-comment"></span> 2 Comments</a></li>
<li><a href="#"><span class="glyphicon glyphicon-share"></span> 8 Shares</a></li>
</ul>
</article>
</div>
</c:forEach>
Обратите внимание: мы в атрибут var поместили просто переменную. Мы можем называть ее по собственному желанию. Потом мы используем эту переменную в выражении типа ${}. В атрибут items мы поместили то название атрибута, которое мы создали и поместили в метод setAttribute. Будьте внимательны, когда меняете названия атрибутов в сервлете. Тогда его придется поменять и в jsp.
Давайте запустим наше приложение и посмотрим, что вышло в итоге.
На этом и закончим нашу статью. Практически ничего нового мы тут не узнали. Просто хотелось показать, как использовать jstl теги на практике. На самом деле мы сейчас рассматривали теги JSTL core. Есть еще и другие: fmt, sql, xml для работы с соответственными технологиями. Я разделил эту статью на две часть и во второй часть мы рассмотрим больше тегов JSTL core и немного fmt отдельно от контекста нашего веб приложения.
Код на гит как и обещал: https://github.com/caligula95/simplewebapp-part6
И как принято, записал видео: