I am getting parsing error when I try to load localhost:8080/.
I can't find any errors in my template, so why have I this mistake?
The file static has folder css and picture with jQuery, js and bootstrap
Error : This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed May 22 13:02:18 CEST 2019
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/RHAjouterDeve.html]")
Code layout index.html:
<!DOCTYPE html>
<html lang="fr" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial- scale=1">
<link th:href="/webjars/bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet" />
<link rel="icon" th:href="(images/favicon.ico)" type="image/ico" />
<title>Projet Pfa Spring BOOT </title>
<link rel="stylesheet" th:href="{build/css/bootstrap.min.css}" />
</head>
<body class="nav-md">
<div class="container body">
<div class="main_container">
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
</div>
<div class="clearfix"></div>
<div class="profile clearfix">
<div class="profile_pic">
</div>
</div>
<br />
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
<div class="menu_section">
<br/>
<br/>
<br/>
<br/>
<br/>
<h3>Menu</h3>
<!-- <ul class="nav side-menu"> -->
<!-- <li><a><i class="fa fa-home"></i> Formation <span class="fa fa-chevron-down"></span></a> -->
<!-- <ul class="nav child_menu"> -->
<!-- <li>Demande Formation</li> -->
<!-- <li>Formation Traité</li> -->
<!-- <li>Formation Accepter</li> -->
<!-- <li>Formation En Cours</li> -->
<!-- <li>Formation Finis</li> -->
<!-- </ul> -->
<!-- </li> -->
<!-- <ul class="nav side-menu"> -->
<!-- <li><a><i class="fa fa-home"></i> Devellopeur <span class="fa fa-chevron-down"></span></a> -->
<!-- <ul class="nav child_menu"> -->
<!-- <li>La Liste Devellopeur</li> -->
<!-- </ul> -->
<!-- </li> -->
<!-- </ul>-->
</div>
</div>
</div>
</div>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<nav>
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li class="">
<a href="javascript:;" class="user-profile dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<img th:src="(images/img.jpg)" alt="">
<span class=" fa fa-angle-down"></span>
</a>
<ul class="dropdown-menu dropdown-usermenu pull-right">
<li>
</li>
<li><i class="fa fa-sign-out pull-right"></i> Log Out</li>
</ul>
</li>
<li role="presentation" class="dropdown">
<ul id="menu1" class="dropdown-menu list-unstyled msg_list" role="menu">
<li>
<a>
<span class="image"><img th:src="(images/img.jpg)" alt="Profile Image" /></span>
</a>
</li>
<li>
<a>
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
</a>
</li>
<li>
<a>
</a>
</li>
<li>
<a>
</a>
</li>
<li>
<div class="text-center">
</div>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main">
<!-- <div class="row tile_count"> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Formation en cours</span> -->
<!-- <div class="count">2500</div> -->
<!-- </div> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Formation Traité </span> -->
<!-- <div class="count">123.50</div> -->
<!-- <span class="count_bottom"><i class="green"> </i></span> -->
<!-- </div> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Total Finis</span> -->
<!-- <div class="count green">2,500</div> -->
<!-- <span class="count_bottom"><i class="green"></i> </i></span> -->
<!-- </div> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Total Formateur</span> -->
<!-- <div class="count">4,567</div> -->
<!-- <span class="count_bottom"><i class="red"></i> </i> </span> -->
<!-- </div> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Total Employé</span> -->
<!-- <div class="count">2,315</div> -->
<!-- <span class="count_bottom"><i class="green"> </span> -->
<!-- </div> -->
<!-- <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count"> -->
<!-- <span class="count_top"><i class="fa fa-user"></i> Total Chef Projet</span> -->
<!-- <div class="count">7,325</div> -->
<!-- <span class="count_bottom"><i class="green"> </span> -->
<!-- </div> -->
<!-- </div> -->
<section layout:fragment="content" class="container">
</section>
<!-- start of weather widget -->
<!-- end of weather widget -->
</div>
</div>
</div>
<!-- /page content -->
<!-- footer content -->
<!-- /footer content -->
<!-- Custom Theme Scripts -->
<script src="build/js/custom.min.js"></script>
<script src="/webjars/jquery/3.4.1/jquery.js"></script> <script src="/webjars/bootstrap/4.3.1/js/bootstrap.js">
</script>
</body>
</html>
</strike>
Fichier rhajouterdeve.html
<strike><!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout/default">
<body>
<section layout:fragment="content">
hello
</section>
</body>
</html>
</strike>
le code du controller :
package com.projetpfa.gestionrh.gestionrh.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/Devellopeur")
public class DeveControllers {
//#Autowired
//DeveService dvserv;
#GetMapping("/")
public String AllDeve( )
{
return"RHAjouterDeve";
}
}
mon fichier 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.projet.pfa</groupId>
<artifactId>projetpfa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>projetpfa</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Error in logs:
____org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/RHAjouterDeve.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) [thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) [thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362) [thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189) [thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) [spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.17.jar:9.0.17]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17] _ __ _ _
have a Spring Boot for serving images. My Model is included in my ImageController.java. ImageService contains findPage method.
When running my Spring Boot Application I am getting an error.
I want to see me template DASHBOARD to begin my project
How can localhost:8585/Devellopeur find template with static file and layout view with no error,
First of all, you can not access localhost:8080/ because you do not have the right controller. You can access http://localhost:8090/Devellopeur/
package com.projetpfa.gestionrh.gestionrh.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/Devellopeur")
public class DeveControllers {
//#Autowired
//DeveService dvserv;
#GetMapping("/")
public String AllDeve( )
{
return"RHAjouterDeve";
}
}
In order to access http://localhost:8090/Devellopeur/ without no thymeleaf parsing errors, you have to create the web page default declared in your rhajouterdeve.html. In general, this file (default.html) is used to to reuse header and footer on all Thymeleaf templates.
<html xmlns:th="http://thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout/default">
Create it in templates package and declare it as follow:
<html xmlns:th="http://thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
At last, you should delete the <strike> in your rhajouterdeve.html
Here an example of default page that you can use.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<header>
<div class="container">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">Jeutroll</a>
</div>
<div>
<ul class="nav navbar-nav">
<li class="active"><a th:href="#{/index}">Home</a></li>
</ul>
</div>
</nav>
</div>
</header>
<section layout:fragment="content"></section>
<footer>
<div class="navabar-fixed-bottom">
<small>adress</small>
</div>
</footer>
</body>
</html>
Related
I making the header of my website for an assignment and I wanted to be able to disply different things depending if they are logged in or not. Problem is sec:authorize is not working with no errors or warnings to indicate why.
Here is my header file where I am trying to dispaly login & register if they are not logged in and logout if they are. But all of them appear no matter what.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<header class="masthead mb-auto" th:fragment="header">
<div class="cover-container d-flex h-100 p-3 mx-auto flex-column">
<div class="inner">
<div class="Lucida_Handwriting">
<a class="Lg" href=".." >
<h3 class="logo-brand" id="Logo">Divorce app</h3>
</a>
</div>
<nav class="nav nav-masthead justify-content-center">
<a class="nav-link active" href="/" th:href="#{/}">Home</a>
<a sec:authorize="!isAuthenticated()" class="nav-link" href="/login" th:href="#{/login}">Login</a>
<a sec:authorize="isAuthenticated()" class="nav-link fw-bold py-1 px-0" href="/logout" th:href="#{/logout}">Logout</a>
<a sec:authorize="!isAuthenticated()" class="nav-link fw-bold py-1 px-0" href="/register" th:href="#{/register}">Register</a>
<a class="nav-link" href="/contact">Contact</a>
</nav>
</div>
</div>
</header>
</body>
</html>
Here are my dependecies among others. Version of spring-boot-starter-security & spring-boot-starter-thymeleaf is 3.0.1
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Also noticed that it gets passed in the html altho I think it should not do that
<a sec:authorize="!isAuthenticated()" class="nav-link" href="/login">Login</a>
<a sec:authorize="isAuthenticated()" class="nav-link fw-bold py-1 px-0" href="/logout">Logout</a>
<a sec:authorize="!isAuthenticated()" class="nav-link fw-bold py-1 px-0" href="/register">Register</a>
Tried using thymeleaf-extras-springsecurity4 but it didnt work.
Tried using older versions of thymeleaf-extras-springsecurity5 but that didnt work either.
Tried replacing xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5" with xmlns:sec="http://www.thymeleaf.org/extras/spring-security" but it didnt work.
EDIT: Added the html code instead of an image
I've been looking through almost every post that is related to my problem and tried every solution that i've found and this problem keeps appearing.
I'm developing a web application and i have almost all the pages that will include, but when i try to connect the Controllers with any JSP this messages appears every time, so i created a new project with only one table and a couple pages, and still get the same "error" but only with pages that load some information, i've tried with one very simple page and it works
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Not Found, status=404).
No message available
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>mjsl.gineco</groupId>
<artifactId>GinecObstWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>GinecObstWeb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.asm</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.jpql</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<version>2.5.2</version>
<scope>provided</scope>
</dependency>
<!-- standard.jar -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:mysql://localhost:13366/ginecoweb?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=gineco
spring.datasource.password=Gineco-94.Aguila
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.generate-ddl=false
spring.jpa.properties.hibernate.hbm2ddl.auto=none
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
Entity
Clientes.java
package mjsl.gineco.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.Data;
#Data
#Entity
#Table(name = "clientes")
public class Clientes implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "CLAVCLI")
private Integer clavCli;
#Size(max = 100)
#Column(name = "NOMBCLI")
private String nombCli;
#Size(max = 100)
#Column(name = "DIRECLI")
private String direCli;
#Size(max = 50)
#Column(name = "COLOCLI")
private String coloCli;
#Size(max = 50)
#Column(name = "POBLCLI")
private String poblCli;
#Size(max = 30)
#Column(name = "TELCLI")
private String telCli;
// #Max(value=?) #Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
#Column(name = "ESTACLI")
private Double estaCli;
#Size(max = 100)
#Column(name = "OCUPCLI")
private String ocupCli;
#Size(max = 100)
#Column(name = "NOCOCLI")
private String nocoCli;
#Size(max = 100)
#Column(name = "OCCOCLI")
private String occoCli;
#Lob
#Column(name = "EXPECLI")
private byte[] expeCli;
#Column(name = "FECHANACCli")
#Temporal(TemporalType.DATE)
private Date fechanacCli;
#Size(max = 5)
#Column(name = "GYRH")
private String gyrhCli;
#Column(name = "EMBARAZO")
private Boolean embarazoCli;
#Size(max = 50)
#Column(name = "SEGUROCli")
private String seguroCli;
#Column(name = "NOSI")
private Boolean nosiCli;
#Size(max = 500)
#Column(name = "FOTO")
private String fotoCli;
// #Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
#Size(max = 200)
#Column(name = "EMAIL")
private String emailCli;
}
ClientesController
package mjsl.gineco.controller;
import java.util.List;
import mjsl.gineco.entity.Clientes;
import mjsl.gineco.service.ClientesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class ClientesController {
#Autowired
ClientesService ctesService;
#RequestMapping("")
public String inicio() {
return "inicio";
}
#RequestMapping("listcte")
public String listaCtes(Model model) {
List<Clientes> clientes = ctesService.getAllCtes();
model.addAttribute("clientList", clientes);
return "indexpac";
}
#RequestMapping("newcte")
public String nuevoCte(Model model) {
Clientes clientes = new Clientes();
model.addAttribute("clienteNuevo", clientes);
return "nuevopac";
}
}
ClientesRepository
package mjsl.gineco.repository;
import mjsl.gineco.entity.Clientes;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ClientesRepository extends JpaRepository<Clientes, Integer> {
}
ClientesService
package mjsl.gineco.service;
import java.util.List;
import java.util.Optional;
import mjsl.gineco.entity.Clientes;
public interface ClientesService {
void saveCte(Clientes clientes);
List<Clientes> getAllCtes();
Optional<Clientes> getCte(Integer clavCli);
void deleteCte(Integer clavCli);
}
ClientesServiceImpl
package mjsl.gineco.service;
import java.util.List;
import java.util.Optional;
import mjsl.gineco.entity.Clientes;
import mjsl.gineco.repository.ClientesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class ClientesServiceImpl implements ClientesService {
#Autowired
ClientesRepository ctesRepo;
#Override
public void saveCte(Clientes clientes) {
ctesRepo.save(clientes);
}
#Override
public List<Clientes> getAllCtes() {
return ctesRepo.findAll();
}
#Override
public Optional<Clientes> getCte(Integer clavCli) {
return ctesRepo.findById(clavCli);
}
#Override
public void deleteCte(Integer clavCli) {
ctesRepo.deleteById(clavCli);
}
}
indexpac.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GinecoObstetricia Avanzada - Pacientes</title>
</head>
<body>
<p><%# include file="/WEB-INF/views/jspf/menu.jspf"%></p>
<p></p>
<div class="container-fluid">
<div class="row-fluid">
<div class="col-md-12">
<h4 class="text-center">Listado de Pacientes</h4>
<hr>
<i class="glyphicon glyphicon-edit"></i> Nuevo(a) Paciente
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Buscar">
<div class="input-group-append">
<button class="btn btn-primary" type="submit">Ir</button>
</div>
</div>
<p/>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Nombre</th>
<th>Teléfono</th>
<th>Ver</th>
<th>Expediente</th>
<!-- <th>Eliminar</th>-->
</tr>
</thead>
<tbody>
<c:forEach var="clients"
items="${clientList}">
<c:url var="updateCteLink" value="/clientes/editapac">
<c:param name="clavCli" value="${clients.clavCli}"/>
</c:url>
<c:url var="openCteLink" value="/clientes/datospac">
<c:param name="clavCli" value="${clients.clavCli}"/>
</c:url>
<tr>
<td>${clients.clavCli}</td>
<td>${clients.nombCli}</td>
<td>${clients.telCli}</td>
<td>
<a href="${updateCteLink}">
<span class="fa-stack">
<i class="far fa-edit" style="color:blue"> </i>
</span>
</a>
</td>
<td><a href="${openCteLink}">
<span class="fa-stack">
<i class="far fa-folder-open"> </i>
</span>
</a>
</td>
<!-- <td>><a href="${pageContext.request.contextPath}/product/delete/${clients.clavCli}">
<span class="fa-stack">
<i class="far fa-trash-alt"> </i>
</span>
</a>
</td>-->
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</html>
menu.jspf
<%# page pageEncoding="UTF-8" %>
<%!
public String getPath(){
String path = getServletContext().getContextPath();
return path;
}
%>
<nav class="navbar navbar-default navbar-fixed-top navbar-expand-md bg-light navbar-light">
<div class="container-fluid">
<!-- -->
<div class="navbar-header">
<a class="navbar-brand" href="#">GinecoObstetricia</a>
</div>
<!-- -->
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="<%=getPath()%>/index.jsp">Inicio <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<%=getPath()%>/login.jsp">Iniciar Sesión</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Pacientes
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<!-- <a class="dropdown-item" href="<%response.sendRedirect("indexpac");%>">Inicio</a>-->
<a class="dropdown-item" href="<%=getPath()%>/indexpac.jsp">Inicio</a>
<a class="dropdown-item" href="<%=getPath()%>/nuevopac.jsp">Agregar</a>
<a class="dropdown-item" href="<%=getPath()%>/datospac.jsp">Expediente Médico</a>
<a class="dropdown-item" href="<%=getPath()%>/datoscons.jsp">Consulta</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Estudios
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="<%=getPath()%>/listadoest.jsp">Listado</a>
<a class="dropdown-item" href="<%=getPath()%>/nuevoest.jsp">Nuevo</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Agenda
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="<%=getPath()%>/index.jsp">Listado</a>
<a class="dropdown-item" href="<%=getPath()%>/index.jsp">Nueva</a>
</div>
</li>
</ul>
</div>
</div>
</nav>
nuevopac.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="mvc" %>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GinecoObstetricia Avanzada - Pacientes</title>
</head>
<body>
<p><%# include file="/WEB-INF/views/jspf/menu.jspf"%></p>
<p></p>
<div class="col-md-10 order-md-1">
<mvc:form modelAttribute="clienteNuevo" action="createCte">
<mvc:hidden path="clavCli" />
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Nombre</span>
</div>
<mvc:input path="nombCli" type="text" class="form-control"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Fecha de Nacimiento</span>
</div>
<mvc:input path="fechanacCli" type="date" class="form-control btn btn-outline-secondary col-md-3"/>
<div class="input-group-prepend">
<span class="input-group-text">Ocupación</span>
</div>
<mvc:input path="ocupCli" type="text" class="form-control col-md-3"/>
<div class="input-group-prepend">
<span class="input-group-text">GyRH</span>
</div>
<mvc:input path="gyrhCli" type="text" aria-labelledby="GyRH-ariaLabel" class="form-control col-md-3"/>
<div class="input-group-prepend">
<span class="input-group-text">Estatura</span>
</div>
<mvc:input path="estaCli" type="text" class="form-control col-md-3"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Domicilio</span>
</div>
<mvc:input path="direCli" type="text" class="form-control" placeholder="Calle y Número"/>
<mvc:input path="coloCli" type="text" class="form-control" placeholder="Colonia o Fraccionamiento"/>
<mvc:input path="poblCli" type="text" class="form-control" placeholder="Población"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Teléfono</span>
</div>
<mvc:input path="telCli" type="text" class="form-control col-md-6"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Conyuge</span>
</div>
<mvc:input path="nocoCli" type="text" placeholder="Nombre" class="form-control col-md-3"/>
<mvc:input path="occoCli" type="text" placeholder="Ocupación" class="form-control col-md-3"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Compañía de Seguros</span>
</div>
<mvc:input path="seguroCli" type="text" placeholder="Nombre de la Compañía de Seguros" class="form-control col-md-6"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">E-mail</span>
</div>
<mvc:input path="emailCli" type="text" placeholder="Correo Electrónico" class="form-control col-md-6"/>
</div>
<div class="form-check-inline mb-3">
<label class="form-check-label">
<mvc:checkbox path="nosiCli" class="form-check-input" value=""/>Recomendada
</label>
</div>
<div class="input-group mb-3">
<input type="submit" value="Guardar" class="btn btn-success">
<button type="button" class="btn btn-danger">Cancelar</button>
</div>
</mvc:form>
</div>
<!--<p style="text-align: center"><img src="Resources/logo_mrysi.png" align="bottom"/></p>-->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Project Map
Based on your Controller mapping when you hit
localhost:8080/ => inicio page will load
localhost:8080/listcte => indexpac page will load
localhost:8080/newcte => nuevopac page will load
Now let's see what you were trying
localhost:8080/listado => will throw error page as no mapping is found for this URL in Controller class.
localhost:8080/newcte => should load nuevopac page. Check console for error and please add nuevopac code. May be JSP throwing some error.
Replace in your Controller Client class #Controller for #RestController
I am struggling with making Thymeleaf load prepared Template fragments in Spring Boot into target webpage.
The index.html file doesn't load the template through decorate, even although I can include them directly via th:replace. I was following a tutorial but wasn't able to find a solution. I believe that the default template location should be resources/templates, which I am using. The html code is following:
index.html
<th:block layout:decorate="layout/layout" layout:fragment="content">
<!-- PAGE CONTENT -->
<div class="container" id="homePage">
<div>
<h1>Headline</h1>
bla <br />
<!--<span th:text="${article.title}" /><br />
<span th:text="${article.title}" /><br />-->
</div>
<div class="row">
<div class="col-lg-12">
<h2>This is Home Page</h2>
<div class="well">
I am inside a bootstrap well.
</div>
</div>
</div>
</div>
<!-- /.container -->
</th:block>
layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<th:block th:replace="layout/fragments/head"></th:block>
</head>
<body>
<th:block th:replace="layout/fragments/nav"></th:block>
<!-- Page Content -->
<div layout:fragment="content" />
<!-- /.container -->
<th:block th:replace="layout/fragments/footer"></th:block>
</body>
</html>
head.html
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Spring Thymeleaf Dialect Configuration</title>
<!-- Bootstrap Core CSS -->
<link th:href="#{/resources/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom CSS -->
<link th:href="#{/resources/css/logo-nav.css}" rel="stylesheet">
<script th:inline="javascript"> var contextRoot = /*[[#{/}]]*/ ''; </script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
Folder Structure:
Maven project structure
Here are Maven dependencies:
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.faire</groupId>
<artifactId>thyme2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>thyme2</name>
<description>Demo project for Spring Boot Thyme</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Bootstrap -->
<!-- https://mvnrepository.com/artifact/org.webjars/bootstrap -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars.bower/jquery -->
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<!--<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
HTML output of index.html:
<!-- PAGE CONTENT -->
<div class="container" id="homePage">
<div>
<h1>Headline</h1>
bla <br />
<!--<span th:text="${article.title}" /><br />
<span th:text="${article.title}" /><br />-->
</div>
<div class="row">
<div class="col-lg-12">
<h2>This is Home Page</h2>
<div class="well">
I am inside a bootstrap well.
</div>
</div>
</div>
</div>
<!-- /.container -->
What am I missing?
Adding Layout Dialect resolved the problem:
<dependency>
<groupId> nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
I believed it is a part of spring-boot-starter-thymeleaf, but it seems the other way around.
The html output after including dependency:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Spring Thymeleaf Dialect Configuration</title>
<!-- Bootstrap Core CSS -->
<link href="/resources/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="/resources/css/logo-nav.css" rel="stylesheet">
<script> var contextRoot = "\/"; </script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- navigation --> <!-- inverse = white on black color schema, fixed top = always on the top (sticky would unhide when
scrolling down -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<!-- data-toggle - collapses target -->
<button type="button" class="navbar-toggle" data-toggle="collapse" date-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
Spring ThymeLeaf
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>
Demo Page 1
</li>
<li>
Demo Page 2
</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<!-- PAGE CONTENT -->
<div class="container" id="homePage">
<div>
<h1>This is headline!</h1>
bla <br />
<!--<span th:text="${article.title}" /><br />
<span th:text="${article.title}" /><br />-->
</div>
<div class="row">
<div class="col-lg-12">
<h2>This is Home Page</h2>
<div class="well">
I am inside a bootstrap well.
</div>
</div>
</div>
</div>
<!-- /.container -->
<!-- /.container -->
<div>
© 2018 Faire
<!-- jQuery -->
<script src="/resources/js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/resources/js/bootstrap.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/resources/js/custom.js"></script>
</div>
</body>
</html>
<div>
© 2018 Faire
<!-- jQuery -->
<script src="/resources/js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/resources/js/bootstrap.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/resources/js/custom.js"></script>
</div>
I have been asked to upgrade an application that was using Spring 3 (3.1.4.RELEASE and 3.2.5.RELEASE in POM) and have gone to (4.2.2.RELEASE and 4.3.8.RELEASE) respectively (for numerous dependencies. The application used to render correctly, show the JSP but now using any of the existing form:checkbox/form:radiobutton/form:input/form:errors work as the page is just blank, no errors. When I re-write the code and use input type="checkbox”/input type="radio" etc the page now shows ok.
I have looked around loads of examples/forums but nothing I have tried has helped. Am I missing some configuration change elsewhere that is needed? The server is WildFly too, but the application worked fine on this using Spring 3 dependencies.
Example of the JSP (with form:radiobutton/form:checkbox commented out and the other code below it that displays ok), called manageUser.jsp :-
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%# taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%>
<div class="contentWrapper">
<fieldset>
<c:if test="${infoFlag}">
<div id="pageMessage">
<p><spring:message code="${infoMessage}"/></p>
</div>
</c:if>
<c:if test="${successFlag !=null && successFlag}">
<div class='message glbMsg success ajaxMsg'>
<span class="infoicon"> </span><p><spring:message code="${successMessage}"/></p>
</div>
</c:if>
<div>
<h3>Manage Users</h3>
<p id="pageIntro">
This section allows you to manage or create users and assign users to roles.
</p>
<div class="col">
<div id="user-tab-container" class="user-tab-container manage-user-page">
<ul class='etabs'>
<li class='usertab'>Manage User</li>
<li class='usertab'>Create User</li>
<li class='usertab' style="display:none;">User Search</li>
</ul>
<div class='panel-container'>
<div id="manage-user">
<form:form id="searchUser" class="singleColForm" method="POST" action="${pageContext.request.contextPath}/admin/searchUser.do" modelAttribute="user">
<div class="col mrgTop10">
<div class="col w2">
<div class="frmFld">
<label for="lastName">Last Name</label>
<input id="lastName" name="lastName" type="text" class="alphanumeric" maxlength="45" value="${user.lastName}" />
</div>
<div class="frmFld">
<label for="firstName">First Name</label>
<input id="firstName" name="firstName" type="text" class="alphanumeric" maxlength="45" value="${user.firstName}" />
</div>
<div class="frmFld">
<label for="eMail">E-mail</label>
<input id="eMail" name="eMail" type="text" class="email" maxlength="100" value="${user.eMail}" />
</div>
<div class="frmFld multiRadio">
<label>Status</label>
<div class="scrollableUserGroup">
<span class="radio">
<input id="userStatus[All]" name="userStatus" type="radio" value="-1" checked/>
<label for="userStatus[All]">All</label>
</span>
<!-- Original that doesn't work now -->
<%-- <c:forEach var="entry" items="${userStatusList}"> --%>
<%-- <span class="radio"> <form:radiobutton --%>
<%-- id="userStatus[${entry.name}]" name="userStatus" --%>
<%-- path="userStatus" value="${entry.id}" /> <label --%>
<%-- for="userStatus[${entry.name}]"><c:out value="${entry.name}"/></label> --%>
<!-- </span> -->
<%-- </c:forEach> --%>
<c:forEach var="entry" items="${userStatusList}">
<span class="radio">
<input type="radio" id="userStatus[${entry.name}]" name="userStatus" value="${entry.id}">
<label for="userStatus[${entry.name}]"><c:out value="${entry.name}"/></label>
</span>
</c:forEach>
</div>
</div>
</div>
<div class="col w2">
<label>User Groups</label>
<div class="frmFld">
<div class="scrollableUserGroup scrollableUserGroups">
<!-- Original that doesn't work now -->
<%-- <c:forEach items="${userGroup}" var="group"> --%>
<!-- <div class="userCB"> -->
<!-- <span class="customCB checkbox"> -->
<%-- <form:checkbox path="userGroups" value="${group.id}" /> --%>
<!-- <span class="box"> -->
<!-- <span class="tick"> </span> -->
<!-- </span> -->
<!-- </span> -->
<%-- <label class="breakword" style="margin-left: 20px;"><c:out value="${group.name}"/></label> --%>
<!-- </div> -->
<%-- </c:forEach> --%>
<c:forEach items="${userGroup}" var="group">
<div class="userCB">
<span class="customCB checkbox">
<input type="checkbox" value="${group.id}" name="userGroups" id="${lstPermission.id}">
<span class="box">
<span class="tick"> </span>
</span>
</span>
<label class="breakword" style="margin-left: 20px;"><c:out value="${group.name}"/></label>
</div>
</c:forEach>
</div>
</div>
</div>
</div>
<div class="buttons">
<a class="btn Big searchUser" href="${pageContext.request.contextPath}/admin/searchUser.do">Search user <span> </span></a>
<span class="hidden"> </span>
</div>
</form:form>
</div>
<div id="create-user">
<!-- Create user -->
</div>
<div id="search-user">
<!-- search user -->
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
In another file called tiles-definition.xml it has the JSP filename:-
<definition name="manageUser" template="/WEB-INF/tiles/layout/user/manageUser.jsp" />
In the Controller, it has (with irrelevant other parts removed):
#Controller
#RequestMapping("/admin")
public class UserControllerImpl extends AbstractCommonController implements UserController {
Below is used in JSP
#ModelAttribute("userStatusList")
public Set<UserStatus> populateUserStatus(){
return userHelper.getUserStatusCollection();
}
#ModelAttribute("userGroup")
public Set<UserGroup> populateUserGroup(){
return userHelper.getUserGroupCollection();
}
…
#RequestMapping("/manageUser.do")
public String manageUser(Map<String, Object> model, HttpServletRequest request){
model.put("user", new UserTo());
return "manageUser";
}
…
}
dispatcher-servlet.xml (has the below in it along with some other parts that are needed):-
…
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="1"/>
</bean>
POM.xml has (old version commented out, new added in) :-
…
<!-- Spring web dependency -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<!-- <version>3.1.4.RELEASE</version> -->
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<!-- <version>3.1.4.RELEASE</version> -->
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<!-- <version>3.1.4.RELEASE</version> -->
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<!-- <version>3.1.4.RELEASE</version> -->
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<!-- <version>3.2.5.RELEASE</version> -->
<version>4.3.8.RELEASE</version>
</dependency>
Any help is much appreciated as I have been thrown in the deep end not knowing too much about Spring and would like to understand and get the original form:radiobutton/form:checkbox/etc working (displaying) and not use the re-written style. Is anything else required for suggestions?
I am trying to create a Spring Boot-based application with Thymeleaf. I am using the PetClinic sample as a starting point.
My application can't find some of the templates.
My project is set up in the standard way:
/src
/main
/java
/com.example
MyWebApplication.java
HomeController.java
/resources
/static
/css
/templates
/fragments
layout.html
home.html
application.properties
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
MyWebApplication.java
#SpringBootApplication
public class MyWebApplication {
public static void main(String[] args) {
SpringApplication.run(MyWebApplication.class, args);
}
}
HomeController.java
#Controller
public class HomeController {
#RequestMapping("/")
public String home() {
return "home";
}
}
home.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
th:replace="~{fragments/layout :: layout (~{::body},'home')}">
<body>
<h2 th:text="#{welcome}">Welcome</h2>
<div class="row">
</div>
</body>
</html>
layout.html
<!DOCTYPE html>
<!--
The main layout fragment that defines the overall layout
Sets up the navigation bar
The page contents are replaced in the main div
-->
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
th:fragment="layout (template, menu)">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link rel="shortcut icon" type="image/x-icon" th:href="#{/images/favicon.png}"> -->
<title>Web Interface</title>
<link rel="stylesheet" th:href="#{/css/bootstrap.min.css}" />
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand glyphicon glyphicon-home" th:href="#{/}"></a>
<!-- Collapse the menu bar on small windows -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- The Navbar items -->
<div class="navbar-collapse collapse" id="main-navbar">
<ul class="nav navbar-nav navbar-right">
<!-- Define a fragment for each menu item -->
<li th:fragment="menuItem (path, active, title, glyph, text)" th:class="${active==menu ? 'active' : ''}">
<a th:href="#{__${path}__}" th:title=${title}>
<span th:class="'glyphicon glyphicon-'+${glyph}" class="glyphicon glyphicon-home" aria-hidden="true"></span>
<span th:text="${text}">Template</span>
</a>
</li>
<!-- Replace with the fragment -->
<li th:replace="::menuItem ('/', 'home', 'home page', 'home', 'Home')">
<span class="glyphicon glyphicon-home" aria-hidden="true"></span>
<span> Home</span>
</li>
</ul>
</div>
</div>
</nav>
<!-- Main body -->
<div class="container-fluid">
<div class="container xd-container">
<div th:replace="${template}"></div>
</div>
</div>
<script th:src="#{/js/bootstrap.min.js}" type="text/javascript"></script>
</body>
</html>
application.properties is empty.
When I navigate to http://localhost:8080 I get the error:
Error resolving template "~{fragments/layout", template might not
exist or might not be accessible by any of the configured Template
Resolvers (home:5)
If I remove the 'th:replace' attribute from home.html, it will display the welcome message.
Browsing similar questions (e.g. this one), I see other people create ThymeleafViewResolver bean.
Questions:
Why can't it find my templates?
Do I need to create a template resolver? If so, how come the pet clinic sample doesn't? Where does its template resolver come from?
As far as I can see it's set up the same way as the pet clinic sample, so what's the difference?
Spring boot does some internal works automagically for you, but to do that automagical work you need to configure it properly. This is the answer for your question 2, spring automagically provides the view resolver if configuration is right. Ok, now lets move to question 1.
If you compare your pom.xml with that of petclinic, You'll see some key differences.
At first, According to spring official doc http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html#using-boot-maven, Maven users can inherit from the spring-boot-starter-parent project to obtain sensible defaults. The parent project provides some features. To configure your project to inherit from the spring-boot-starter-parent simply set the parent in your pom.xml.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
With that setup, you can also override individual dependencies by overriding a property in your own project. For instance, in petclinic pom.xml, they specified the thymeleaf version which is missing in yours.
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
Now to properly setup Thymeleaf and Thymeleaf layout dialect version with compatibility between them you need to exclude thymeleaf-layout-dialect from spring-boot-starter-thymeleaf, bcz of setting thymeleaf version to 3.0.2.RELEASE version.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<exclusions>
<exclusion>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</exclusion>
</exclusions>
</dependency>