Pokud si necháme vygenerovat projekt pomocí mavenu: File -> New -> Maven project -> maven-archetype-webapp (verze 1.0) -> … a pokud tento projekt nasadíme na Tomcat, zobrazí se očekávaný výstup – jednoduchá stránka s textem „Hello World!“. Problém nastane v okamžiku, kdy začneme používat jsp.
Když původní jednoduchou stránku
<html> <body> <h2>Hello World!</h2> </body> </html>
nahradíme například tímto:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ prefix="c" taglib uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login</title> </head> <body> <c:set var="message" value="Hello World"/> <c:set var="otherMessage" value="This is other message."/> <c:set var="display" value="${true}"/> <c:if test="${display}"> <c:out value="${message}"></c:out> </c:if> <c:out value="${otherMessage}"></c:out> </body> </html>
dostaneme tuto chybu:
SEVERE: Servlet.service() for servlet [jsp] in context with path [/maven-webapp03] threw exception [/index.jsp (line: [3], column: [4]) Invalid directive] with root cause org.apache.jasper.JasperException: /index.jsp (line: [3], column: [4]) Invalid directive
To je pochopitelné. Chceme použí tagy JSTL (Java Server Pages Standard Tag Library), ale nemáme v projektu dané knihovny. Jelikož se jedná o Maven projekt, stačí přidat závislosti do pom.xml.
<dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-spec</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> </dependency>
Updatujeme projekt (Alt + F5) a restartujeme Tomcat. Chyba zmizela a z prohlížeče na nás kouká stránka s textem ${otherMessage} . Pokud se koukneme do zdrojového kódu (Ctrl + U), zjistíme toto:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login</title> </head> <body> ${otherMessage} </body> </html>
Zvláštní, očekával bych dva texty („Hello World“ a „This is other message.“). Chyba je v tom, že JSTL výrazy, což je ta konstrukce „${cosi}“ se nevydnotily. Řešením je přidat do stránky direktivu <%@ page isELIgnored="false" %>
. Po restartu Tomcata dostaneme konečně to, co chceme:
Hello World This is other message.
Pokud se ale nad výše uvedeným řešením zamyslíte, určitě vám bude vrtat hlavou otázka, proč bych měl danou direktivu přidávat do každé stránky a proč to neumí by defaut. Velmi dobrá úvaha. Chyba je totiž někde jinde. Odstranili jsme následek, ale příčina zůstala a tou je web.xml. Že jste ani nevěděli, že je v projektu? Ano, je. Maven jej vygeneroval tam kam patří. Do složky WEB-INF.
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app>
Potud je vše v nejlepším pořádku. Tedy až na tu drobnost, že se jedná o starý typ deklarace. Pro JSTL je potřeba minimálně servlet verze 2.4. Pokud si tedy upravíte web.xml například následovně
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> </web-app>
můžete klidně z jsp souboru odstranit direktivu <%@ page isELIgnored="false" %>
. Vše bude fungovat jak má.
Svítí vám ve IDE varování? To je způsobeno tím, že při compilaci projektu nejsou k dispozici všechny knihovny. Jak je možné, že to ale na serveru funguje? Jednoduše proto, že na serveru tyto knihovny k dispozici jsou. Řešením je třeba přidat knihovny (celé runtime), které má server, do projektu. v Eclipse je řešení následující: pravým na projekt -> Properties -> Project Facets -> na pravé straně záložka Runtimes -> zakliknout potřebné runtime – to je pouze v případě, že v Eclipse máte server přidaný).
Řešením v případě Maven projektu je přidat knihovnu do závislosti pouze pro kompilaci.
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>