why Thymeleaf's th:text not working in my Spring project? - java

I have included Thymeleaf for my Spring project for the first time and want to create a simple project(display one word using th:text). But I get nothing in my html page. Why?
Greeting.java
package com.supermegaproject.Main;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class Greeting
{
#GetMapping("/")
public String getMessage(Model model)
{
model.addAttribute("name", "John");
return "mainPage";
}
}
mainPage.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title>
</head>
<body>
<h1>Main Page</h1> // DOES APPEAR
<h1 th:text="${name}"></h1> // DOESN'T APPEAR AT ALL
</body>
</html>
At first I thought it may be because of build.gradle. But after checking it looks ok, thymeleaf included, so I don't know why then.
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
Thank you in advance.

I solved it. All you had to do - is to delete Mustache dependency.

Related

How can I make an HTML page (not JSP) communicate with a Servlet?

With the below servlet code,
package com.example.tutorial;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletExample extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getParameter("firstname") == null || request.getParameter("lastname") == null){
this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
return;
}
this.getServletContext().getRequestDispatcher("/output.jsp").forward(request, response);
}
}
I first receive the request parameters using index.jsp as shown below:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<form action="servletexample" method="post" >
<table border="0">
<tr>
<td>First Name:</td> <td><input type="text" name="firstname" /></td>
</tr>
<tr>
<td>Last Name:</td> <td><input type="text" name="lastname" /></td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
and then the servlet communicate with output.jsp using requestdispatcher, as shown below:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<h1>Your first and last name is: </h1>
<%
String firstName = request.getParameter("firstname");
String lastName = request.getParameter("lastname");
out.print(firstName + " " + lastName);
%>
</body>
</html>
In the above output.jsp code, request.getParameter method is used to retrieve the forwarded parameters from servlet.
Now, instead of output.jsp, I would like to use only html file[with javascript(if required)],
What should be the content of html body?
Note: Going further, Intention is to just use html/javascrip/css as front end and java based web frameworks(like Spring) as back end. My current learning about servlets/jsp is to have smooth transition to Spring framework(backend) that can work with html/javascrip/css
From your comment:
I want, Javascript actions that communicate with the server and change the display. Basically I want to see html/JavaSript/css as frontend and servlet(only) as backend
Then it will be better to use ajax requests instead and use JSON to write the response rather than forward. Then, your front end may be pure HTML or another technology like a mobile app.
Note that if the only intend for you to use Servlets is to create RESTful services, then you will be better to use a REST approach rather than writing servlets on your own. For instance, you hace two options:
Use JAX-RS. You can choose an implementation like jersey or resteasy
Use Spring. This framework offers many capabitilies (many people will say they are benefits, it will depend on your point of view, though), and one of them is creating RESTful services. Here's a tutorial for creating the services using Spring Boot: https://spring.io/guides/gs/rest-service/.
If you're new to Java at all, I would recomment you to use JAX-RS. If you already have some experience with Java and Spring, then I recommend you using Spring, using Spring Boot it's an option, it will depend on your specific case.
First java is compiler based language and html is interpreter based language.so you cannot write java code inside the html file.it can be written in jsp.
If you want to use html with out writing java code in it you can.
create html file output.html
by using this code.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Your first and last name is: </h1>
</body>
</html>
and after this just replace the statement of RequestDispatcher forward statement by this
this.getServletContext().getRequestDispatcher("/output.html").forward(request, response);

Unable to get value from value stack in struts2 using <s:action>

What I want: I want to retrieve the value from List collection.
I’m practicing/learning struts 2 framework. But, I am confused about OGNL behavior.
These are my files:
Index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<hr>
<s:action name="one" />
<s:property value="list_fruits[0]" />
</body>
</html>
MyAction.java
package abc;
import java.util.*;
import org.apache.struts2.dispatcher.RequestMap;
import com.opensymphony.xwork2.*;
public class MyAction extends ActionSupport {
private List list_fruits;
public List getList_fruits() {
return list_fruits;
}
public void setList_fruits(List list_fruits) {
this.list_fruits = list_fruits;
}
public String doOne() {
list_fruits = new ArrayList();
list_fruits.add("banana");
list_fruits.add("apple");
list_fruits.add("mango");
/*RequestMap rm = (RequestMap) ActionContext.getContext().get("request");
rm.put("req_scope", list_fruits);*/
return "sendToOne";
}
}
one.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>ONE.JSP</h1>
<br>
<s:property value="list_fruits[0]" />
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="devMode" value="true" />
<package name="vns" extends="struts-default">
<action name="one" class="abc.MyAction" method="doOne">
<result name="sendToOne">/one.jsp</result>
</action>
</package>
</struts>
I am experiencing following behaviors:
Case1: When I put this (below) code in index.jsp, I get NO value printed.
<s:action name="one"/>
<s:property value="list_fruits[0]"/>
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Case2: When I put this (below) code in index.jsp, the value gets printed from one.jsp because in this scene I included attribute executeResult=”true”
<s:action name="one" executeResult="true"/>
<s:property value="list_fruits[0]"/> <!-- still NOT printed here, but gets printed from one.jsp -->
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Case3: When I put this (below) code in MyAction.java and index.jsp, then the value get printed on screen (index.jsp).
MyAction.java
RequestMap rm=(RequestMap)ActionContext.getContext().get("request");
rm.put("req_scope", list_fruits);
index.jsp
<s:action name="one"/> <!-- removed executeResult="true" -->
<s:property value="#request.req_scope[0]"/>
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
in Case2 value gets printed due to one.jsp and not due to index.jsp
I want to know why I am NOT getting any value printed in Case1 whereas in Case2 and Case3, there is no such problem. Why is it so? Can anyone guide me?
AleksandrM already answered you, but since you said
still not clear. :( please explain.
You can use it for :
calling an Action and use executeResult="true" to get the result;
calling an Action and push it on the main page ValueStack with var attribute, then reference it with # :
<s:action name="one" var="instance" />
<s:property value="#instance.list_fruits[0]"/>
calling an Action that sets something in request / session scope, and then retrieve those values by using #attr or #session;
calling an Action that does something (e.g. persists into the database the timestamp of when the page has been opened).
But you can do any of this single things server side, and BETTER.
This is why you shouldn't use the <s:action/> tag: it breaks most of the S2 framework conventions and mechanisms and it is a bad practice (or at least it isn't a good one).

struts2 mysql conection error in eclipse

I am connecting to MySQL using JDBC to the JSP, but it shows error classNotFoundException in eclipse in struts JSP page.
validate.java:
package com.demo;
import java.sql.*;
public class LoginValidate {
public boolean validateLogin(){
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/inspioqj_appointment");
return true;
}
}
Same code using in same project jsp file its working what is problem i am not understanding.
index.jsp:
<%# page language="java" import="java.sql.*" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<p> There is home page.</p>
<hr/>
login|
logout|
profile
<%
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/inspioqj_appointment");
%>
</body>
</html>
I have included MySQL java connector on lib folder in eclipse struts project, but it is not working in action controller validate.java but it is working in index.jsp page.
What is problem? I could not understand.
Its a pretty simple ClassNotFoundException. Make sure that the mySQL jar is present in the class-path of the project as well. You can do this by right-clicking the project, configure class-path and from there you can add the particular jar

(Eclipse) The value for the useBean class attribute is invalid

I have been looking for ages now but none of the solutions google offered me helped for my situation.
I wrote a simple JSP-File and only tried to use the "useBean" statement (that's the line where the error occurs):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# page import="package1.TestBean" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="test" class="package1.TestBean" />
</body>
</html>
My JavaBean is an empty class but has an empty constructor without parameters:
package package1;
public class TestBean {
public TestBean() {
}
}
I created the class by right-clicking the project folder and then using New->Class.
So as I already said, the error occurs in the following line:
<jsp:useBean id="test" class="package1.TestBean" />
And the error message is (as already named in the title) "The value for the useBean class attribute package1.TestBean is invalid."
Please help me! :-(
Edit: A friend of mine tried the same, on his computer it works. Now he sent me his project folder, I imported it and it works, too!?!?!?
Solution found: There was a conflict between two Tomcat installations. See comments on Question for more detailed information.
stop Tomcat,go to Project-->Clean ->select the respective project->click clean. start Tomcat again

Thymeleaf templates - Is there a way to decorate a template instead of including a template fragment?

I am working with Thymeleaf for the first time, and I need a clarification about the templates. If I correctly understand the documentation, I can include a template - or just a fragment of it - in my page. So for example, I can write something like that:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head th:include="template/layout :: header">
</head>
<body>
Hello world
<div th:include="template/layout :: footer"></div>
</body>
</html>
But what I want is in fact the opposite way of using the template : instead of including template fragment in the page, I want to include the page inside my template, something like that:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
...
</head>
<body>
<div id="my-template-header">...</div>
<div id="the-content">
<!-- include here the content of the current page visited by the user -->
???
</div>
<div id="my-template-footer">...</div>
</body>
In others words, is there a way to have an equivalent of the Sitemesh decorators tags in Thymeleaf?
Thanks
with Thymeleaf 2.1, you can write something like that:
Create the template (for ex. templates/layout.html), and add the th:fragment="page" information in html tag and define the content area with th:include="this :: content" information:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
th:fragment="page">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>
</head>
<body>
layout page
<div th:include="this :: content"/>
layout footer
</body>
</html>
Now create the page that will include this template adding th:include="templates/layout :: page" in html tag and put your main content inside a div with th:fragment="content"
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
th:include="templates/layout :: page">
<head>
<title></title>
</head>
<body>
<div th:fragment="content">
my page content
</div>
</body>
</html>
In layout page you can use this (th:include="this :: content") or suppress this option (th:include=":: content"). It seems like jsf facelets I think.
Ok, as stated by Sotirios Delimanolis, Thymeleaf does not support that way of using template, or should I say "Hierarchical layouts", as explained by Daniel Fernandez in this thread.
As sitemesh and Thymeleaf are compatible, it seems that I have to use both solutions. Too bad.
Edit: As suggested by DennisJaamann in a comment, I finally used Thymeleaf Layout Dialect, a view dialect that provides the feature I was looking for.
The working code:
First I add the LayoutDialect class:
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
//NB, selecting HTML5 as the template mode.
resolver.setTemplateMode("HTML5");
resolver.setCacheable(false);
return resolver;
}
Then, I create the template (for ex. templates/layout.html), and add the layout:fragment information where I want to put the content of the current page:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
...
</head>
<body>
<div id="my-template-header">...</div>
<div id="the-content" layout:fragment="content">
<!-- include here the content of the current page visited by the user -->
</div>
<div id="my-template-footer">...</div>
</body>
and the page will refers to the template with the attribute layout:decorator:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="templates/layout">
<body>
<div layout:fragment="content">
Hello world
</div>
</body>
</html>
You need
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>1.2.2</version>
</dependency>
and add this to your SpringTemplateEngine:
#Bean
#Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new LayoutDialect());
return templateEngine;
}
If now create a folder named template in your views folder.
views/home.html
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="template/layout">
<body>
<div layout:fragment="content">
Hello world
</div>
</body>
</html>
views/layout/layout.html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
</head>
<body>
<div id="content" layout:fragment="content">
</div>
</body>
</html>
As far as I know, you can't. A possible solution would be to create a ViewResolver that always forwards to your decorator file, but at the same time put Model attributes that would have the actual path to the fragment you want to include.

Categories