Make EL work with tomcat 7 embedded (using spring MVC)

embedded-tomcat-7, spring-mvc, tomcat

Solution

Try to add:

<%@ page isELIgnored="false" %>

to the header of your jsp page. For example:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Home</title>
</head>
<body>
<h1>
    Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

EDIT:

Inspired by your comment:

If you want to programmatically enable EL expressions in JSP without loading/definition of a web.xml file you have to add the ContextConfig LifecycleListener:

rootContext.addLifecycleListener(new ContextConfig());

a full workin example (Tomcat embedded 7.0.50 with JDK 1.7):

public static void main(String[] args) throws LifecycleException
{
  // setup server
  final Tomcat tomcat = new Tomcat();
  tomcat.setBaseDir("."); // location where temp dir is created
  tomcat.setPort(8080);

  // configure context
  final File applicationPath = new File("./webapp"); // todo: change to your location
  Context rootContext = tomcat.addContext("/", applicationPath.getAbsolutePath());
  rootContext.addLifecycleListener(new ContextConfig());

  // JSP and Default Servlet setup, mime type mapping and welcome files
  Tomcat.initWebappDefaults(rootContext);

  // start server
  tomcat.start();
  tomcat.getServer().await();
}

with this solution you don't need to explicitly state page directives in your JSP files.

HINT: dont forget to delete your "work" (=temporary tomcat directory) after makin changes and before restarting your server. Compiled JSP's are chached there and you may get old results!

HTH,

Problem

I made an example, available on github, that uses tomcat embedded to boot a simple spring MVC application. The application boot with apparently no problem, but in the rendered jsp, el expression is not processed. Here is my pom.xml : ``` <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.example</groupId> <artifactId>springtomcatembedded</artifactId> <name>SpringMVCTomcatEmbedded</name> <packaging>war</packaging> <version>1.0.0-BUILD-SNAPSHOT</version> <properties> <java-version>1.6</java-version> <org.springframework-version>3.1.1.RELEASE</org.springframework-version> <org.aspectj-version>1.6.10</org.aspectj-version> <org.slf4j-version>1.6.6</org.slf4j-version> <tomcat.version>7.0.50</tomcat.version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> <exclusions> <!-- Exclude Commons Logging in favor of SLF4j --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> </exclusions> <scope>runtime</scope> </dependency> <!-- @Inject --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>provided</scope> </dependency> <!-- Embedded tomcat --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-el-api</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>${tomcat.version}</version> </dependency> <!-- Test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <additionalProjectnatures> <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> </additionalProjectnatures> <additionalBuildcommands> <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> </additionalBuildcommands> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.6</source> <target>1.6</target> <compilerArgument>-Xlint:all</compilerArgument> <showWarnings>true</showWarnings> <showDeprecation>true</showDeprecation> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <mainClass>org.test.int1.Main</mainClass> </configuration> </plugin> </plugins> </build> </project> ``` And here is my main spring controller wich contains also my main method : ``` package com.example.springtomcatembedded; import java.io.File; import java.text.DateFormat; import java.util.Date; import java.util.Locale; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.Wrapper; import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.startup.Tomcat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.DispatcherServlet; /** * Handles requests for the application home page. */ @Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate ); return "home"; } public static void main(String[] args) throws LifecycleException { Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); Context ctx = tomcat.addContext("/", new File("src/main/webapp/").getAbsolutePath()); ApplicationParameter rootContextConfiguration = new ApplicationParameter(); rootContextConfiguration.setName("contextConfigLocation"); rootContextConfiguration.setValue("/WEB-INF/spring/root-context.xml"); ctx.addApplicationParameter(rootContextConfiguration); ApplicationListener springApplicationListener = new ApplicationListener("org.springframework.web.context.ContextLoaderListener", false); ctx.addApplicationListener(springApplicationListener); // Configure dispatcher servlet Wrapper wrapper = ctx.createWrapper(); String servletName = "appServlet"; wrapper.setName(servletName); wrapper.setLoadOnStartup(1); wrapper.setServletClass(DispatcherServlet.class.getName()); wrapper.addInitParameter("contextConfigLocation", "/WEB-INF/spring/appServlet/servlet-context.xml"); wrapper.setLoadOnStartup(1); // Define JspServlet. Wrapper jspServlet = ctx.createWrapper(); jspServlet.setName("jsp"); jspServlet.setServletClass("org.apache.jasper.servlet.JspServlet"); jspServlet.addInitParameter("fork", "false"); jspServlet.addInitParameter("xpoweredBy", "false"); jspServlet.setLoadOnStartup(2); ctx.addChild(jspServlet); ctx.addServletMapping("*.jsp", "jsp"); ctx.addChild(wrapper); ctx.addServletMapping("/", servletName); tomcat.setSilent(false); tomcat.start(); tomcat.getServer().await(); } } ``` My jsp page : ``` <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" %> <html> <head> <title>Home</title> </head> <body> <h1> Hello world! </h1> <P> The time on the server is ${serverTime}. </P> </body> </html> ``` And finally, my spring mvc configuration : ``` <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <context:component-scan base-package="com.example.springtomcatembedded" /> </beans:beans> ``` As I said, it is working, but my jsp pages cannot use el to access model data :S Anyone can see why ? For instance, it will print ${serverTime} instead of the actual server time pushed in the model.

Original source