Thymeleaf decorator is not working - spring-boot

I created a new Spring-boot project and wanted to use Thymeleaf with the LayoutDialect.
My pom.xml has following dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</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>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.3.11</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angular-ui-router</artifactId>
<version>0.2.13</version>
</dependency>
</dependencies>
I also have a #Configuration class where I add the dialact. And do the view resolving.
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/projects").setViewName(
"project/listProjects");
registry.addViewController("/").setViewName(
"project/listProjects::content");
registry.addViewController("/create").setViewName(
"project/createProject::content");
}
#Bean
public LayoutDialect layoutDialect() {
return new LayoutDialect();
}
}
I have one layout HTML which looks like
<!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>
</head>
<body>
<div>header</div>
<div layout:fragment="content">
<h1>Static content for prototyping purposes only</h1>
<p>This is the layout of the site. The actual content will come
from individual views making use of this layout</p>
</div>
</body>
</html>
and an other HTML wich calls decorator on the layout html...
<!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" layout:decorator="layout/layout">
<head></head>
<body>
<div th:fragment="content">
<div>list....</div>
</div>
</body>
</html>
when i run it as spring boot app I just see the content "list..."
The paths to the htmls are correct.
Can you please tell me what I'm doing wrong? I also recognized, that when I used bootstrap stylesheets from the webjar the weren't loaded.
Thank you very much.

see two errors here. first you need and space in the thymeleaf xmlns like so.
<!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>
</head>
<body>
<div>header</div>
<div layout:fragment="content">
<h1>Static content for prototyping purposes only</h1>
<p>This is the layout of the site. The actual content will come
from individual views making use of this layout</p>
</div>
</body>
</html>
the second one has an error in
<div th:fragment="content">
<div>list....</div>
</div>
it should be
<div layout:fragment="content">
<div>list....</div>
</div>

Related

Javax #Valid annotation doesn't work as expected

I have a for with object creation. When I trying to create it and validate - I receiving an error, but not on the UI side, as expected. Don't understand why.
Here is my html code:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.thymeleaf.org"
lang="en"
layout:decorate="~{layout/layout}">
<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 http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Добавить Объект</title>
</head>
<body>
<main class="content-wrapper">
<div class="container-fluid">
<form method="POST" th:action="#{/admin/objects/add}" th:object="${objectForm}">
<p class="h4 text-left">Добавить объект</p>
<div class="form-group col-md-3 offset-md-0"
th:classappend="${#fields.hasErrors('name')}? 'has-error':''">
<label for="exampleInputName"></label>
<input name="username" type="text" class="form-control" id="exampleInputName" required="required"
placeholder="Название(ручной ввод)"
th:field="*{name}"/>
<br/>
<p class="alert alert-danger"
th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Validation error</p>
</div>
<div class="form-group col-md-1 offset-md-0">
<button type="submit" class="btn btn-success offset-md-0 btn-sm active">Создать</button>
</div>
</form>
</div>
</main>
</body>
</html>
ObjectController:
#Controller
#Validated
#RequestMapping("/admin/objects")
public class ObjectController {
private static final Logger log = LogManager.getLogger(ObjectController.class);
private final ObjectsService objectsService;
private Pageable pageable;
#Autowired
public ObjectController(ObjectsService objectsService) {
this.objectsService = objectsService;
}
#GetMapping("/add")
public String printAddObject(Model model) {
model.addAttribute("objectForm",
new Object()
);
return "objects_add";
}
#PostMapping("/add")
public String addNewObject(#ModelAttribute("objectForm") #Valid Object objectForm,
Model model,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
System.out.println("ERROR: " + bindingResult.getAllErrors().toString());
return "objects_add";
}
if (!objectsService.create(objectForm)) {
bindingResult.addError(new FieldError("objectForm",
"name",
"Объект с таким именем уже существует"
));
return "objects_add";
}
return "redirect:/admin/objects";
}
Object class:
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
#Entity(name = "objects")
public #Data class Object {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name = "object_id")
private Long objectId;
#NotNull
#Size(min = 2)
#Column(name = "name")
private String name;
}
When I'm clicking on submit Button and inputing one symbol, I am expecting that UI will show me an error message, but all I can see:
Browser error
Console error
What I am doing wrong?
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 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.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ru.eco.products.waste</groupId>
<artifactId>waste-web</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>products-waste-web-client</name>
<description>Eco-Waste-Products Project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</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-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.18</version>
<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>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I found what was wrong:
Binging Result must be right after the Object that is marked #Valid
#Validated annotation shall no be used.

thymeleaf sec:authorize not working in spring boot

I have a Spring MVC project with Thymeleaf and in memory authentication.
In my html I want to display the current user that is logged in and diplay the logout button only when somebody is logged in.
Here is a simple html that should display the username, but is always displays Bob and a text that should only be displayed when somebody is logged in, but it's always displayed.
Any idea what I'm doing wrong?
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/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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>info.climbinggyms</groupId>
<artifactId>main</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>main</name>
<description>website with an overview of the existing climbing gyms</description>
<properties>
<java.version>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-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>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</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-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
My html:
<!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"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
layout:decorator="layout/root_layout"
lang="en">
<head>
<title>My Climbing Gyms</title>
</head>
<body>
<div layout:fragment="page-content">
<div class="container">
<section>
<br>
<br>
<br>
<h1>My Climbing Gyms</h1>
<p>Welcome to my climbing gyms</p>
<p>This is still under construction, this site only contains dummy data</p>
<div sec:authorize="isAuthenticated()">
This content is only shown to authenticated users.
</div>
<span sec:authentication="name">Bob</span>
</section>
</div>
</div>
</body>
</html>
and my security configuration:
package info.climbinggyms.main;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasAnyRole("ADMIN","USER")
.and()
.csrf().disable().headers().frameOptions().disable()
.and()
.formLogin()
.and()
.logout();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("bleau83").password("{noop}bleau83").roles("ADMIN")
.and()
.withUser("user").password("{noop}user").roles("USER");
}
}
I updated my thymeleaf security to springsecurity5 and now it is working
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
I've had similar problem, my implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' was missing from build.gradle altogether.
Yes, You need update to springsecurity5
thymeleaf-extras-springsecurity5

spring boot 2.1.0 war file cannot config 'context-path' or else 'include' in jsp not working

I'm using Spring Boot 2.1.0 to develop a web application. I package the codes into a WAR file with maven.
I configured server.servlet.context-path=/marpt in application.properties file so that application can not access by ip+port directly.
Then I run the WAR using java -jar marpt.war command, and it is successed start.
Then I open the running web application in Chrome, there're some problems throw out:
1. The index login page shows corrcetly;
2. After login, jsp include not working, both of two types of inclue command, <jsp:include page="${ctx}/home/sidebar" /> and <%#include file="../../pages/share/partial/header.jsp" %> and any other references.
I use javascript to alert the ${ctx} which I defined in another jsp file, and include it in top of homepage by <%# include file="../../pages/common/taglibs.jsp" %>, it's very strange, the taglibs.jsp can be included. In it I set <c:set var="ctx" value="${pageContext.request.contextPath}" />. In home page I do this: alert('${pageContext.request.contextPath}'), the result is /marpt.
I'm confused where is wrong.
I try to package the jar file, it's also start correctly, but pages cannot open in browser at all.
Below are main configuration files:
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>
<groupId>com.test</groupId>
<artifactId>ma-rpt</artifactId>
<version>1.5.0</version>
<packaging>war</packaging>
<name>ma-rpt</name>
<description>Spring Boot</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-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- Shiro ehCache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</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-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- jstl支持 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>marpt</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application.properties</include>
<include>properties/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
</resource>
<resource>
<directory>src/main/webapp</directory>
</resource>
</resources>
</build>
</project>
application.properties
# Spring Public
server.port =8096
server.servlet.context-path =/marpt
# Cache
spring.cache.type =ehcache
# Db
spring.datasource.driver-class-name =oracle.jdbc.driver.OracleDriver
spring.datasource.url =jdbc:oracle:thin:#192.168.0.1:1521:marpt
spring.datasource.username =admin
spring.datasource.password =123456
# MyBatis
mybatis.config-location =classpath:/configs/mybatis/mybatis.cfg.xml
mybatis.mapper-locations =classpath*:/mybatis/**/*Mapper.xml
# Log
spring.output.ansi.enabled =DETECT
logging.path =/data/home/www/marpt/logs
logging.file =ma-rpt
logging.level.* =DEBUG
#debug=false
rpt.project.name =ma-rpt
rpt.project.develop =true
SpringBootConfig.java
#SpringBootConfiguration
public class SpringBootConfig implements WebMvcConfigurer {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
configurer.setUseRegisteredSuffixPatternMatch(true);
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true)
.favorParameter(true)
.parameterName("format")
.ignoreAcceptHeader(true)
.defaultContentType(MediaType.TEXT_HTML)
.mediaType("html", MediaType.TEXT_HTML)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xls", MediaType.valueOf("application/vnd.ms-excel"))
.mediaType("xlsx", MediaType.valueOf("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
Set<String> modelKeys=new HashSet<>();
modelKeys.add("list");
modelKeys.add("table");
registry.jsp("/views/", ".jsp");
registry.enableContentNegotiation(new MappingJackson2JsonView());
XlsView xlsView=new XlsView();
xlsView.setModelKeys(modelKeys);
registry.enableContentNegotiation(xlsView);
XlsxView xlsxView=new XlsxView();
xlsxView.setModelKeys(modelKeys);
registry.enableContentNegotiation(xlsxView);
}
}
Main of homepage.jsp
<%# page language="java" pageEncoding="UTF-8" errorPage="../error/error.jsp" %>
<%# include file="../../pages/common/taglibs.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
<title>Home</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="${ctx}/assets/global/plugin/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="${ctx}/assets/global/plugin/jquery/jquery.min.js" type="text/javascript"></script>
</head>
<body >
<div class="page-wrapper">
<%#include file="../../pages/share/partial/header.jsp" %>
<div id="pageContainer" class="page-container">
<jsp:include page="${ctx}/home/sidebar" />
<jsp:include page="${ctx}/home/content" />
</div>
</div>
<script src="${ctx}/assets/global/plugin/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script>
$(function() {
alert('${ctx}'); // result is '/marpt'
alert('${pageContext.request.contextPath}'); // result is '/marpt' too
});
</script>
</body>
</html>
The application structure:
application structure
So, if I define the server.servlet.context-path=/marpt configure, how can I make <%#include... or <jsp:include... working in jsp file in Spring Boot? Thanks very much!
======================== supply ===========================
I tried to downgrade too 1.5.18, modified properties to server.context-path=/marpt, the problem is still exist, not relate to the version of spring boot.
The include files are some html tags, js, and some bind model attributes(such as ${param.dt}..), JSP files which are NOT mapping to servlet. If I configure them in a static resources' path, also failure.
======================== figure out ===========================
see JB Nizet's comment
Add the following spring tag in order to get property value "server.servlet.context-path" using #environment.getProperty('some.property') should work.
<spring:eval expression="#environment.getProperty('server.servlet.context-path')" var="ctx" />
<link href="${ctx}/assets/global/plugin/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

Bootstrap not working with spring-boot?

I am attempting to install bootstrap for use in my spring boot project, which uses thymeleaf. I am getting this error with the template (index.html, shown below):
Malformed markup: Attribute "class" appears more than once in element
I assume this is because bootstrap isn't installed properly. Below I have an image of the files also.
I am pretty sure all the dependencies are right.
INDEX HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<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="stylesheet" href="/bootstrap-3.3.7/css/bootstrap.min.css"/>
<script src="/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<!-- <link rel="stylesheet" type="text/css"
th:href="#{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
<link rel="stylesheet" type="text/css" th:href="#{/css/main.css}" />
<script
src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js">
</script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script> -->
<title>Home</title>
<style></style>
</head>
<body>
<div class="navbar navbar-default" role="navigation" id="topnavbar">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" type="button" data-
toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
<ul class="nav navbar-nav">
<li><span class="glyphicon glyphicon-home"></span>Profile</li>
<li>
<a href="/competition">
<span class="glyphicon glyphicon-star"></span> Competitions
</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/logout"> <span class="glyphicon glyphicon-user"></span>
<strong>Log out</strong>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container" class="row">
<div class="page-header" id="banner">
<div class="row">
<div class="col-lg-8 col-md-7 col-sm-6">
<img src="ban.png">
</div>
<div class="col-lg-4 col-md-5 col-sm-6">
<div class="sponsor"></div>
</div>
</div>
</div>
</div>
<div class="container"></div>
</body>
<script th:inline="javascript">
$(document).ready(function () {
var panels = $('.user-infos');
var panelsButton = $('.dropdown-user');
panels.hide();
//Click dropdown
panelsButton.click(function () {
//get data-for attribute
var dataFor = $(this).attr('data-for');
var idFor = $(dataFor);
//current button
var currentButton = $(this);
idFor.slideToggle(400, function () {
//Completed slidetoggle
if (idFor.is(':visible')) {
currentButton.html('<i class="glyphicon glyphicon-
chevron - up
text - muted
"></i>');
}
else {
currentButton.html('<i class="glyphicon glyphicon-
chevron - down
text - muted
"></i>');
}
})
});
$('[data-toggle="tooltip"]').tooltip();
$('button').click(function (e) {
e.preventDefault();
alert("This is a demo.\n :-)");
});
});
</script>
</html>
POM file:
<?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>
<groupId>com.finalYearProject</groupId>
<artifactId>student-life</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>student-life</name>
<description>Jill's Student Life Final Year Project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.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>
<!-- upgrade to thymeleaf version 3 -->
<thymeleaf.version>3.0.8.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-
dialect.version>
<thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-
extras-springsecurity4.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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-datepicker</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency> -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</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.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.2.1</version>
</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-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId1>spring-session</artifactId>
<version>1.2.2.RELEASE</version>
</dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Project structure:
The exception will give the line # in the html where the error is occurring... in any case, the actual problem is here:
<div class="container" class="row">
Thymeleaf won't allow an element to have two attributes with the same name (Attribute "class" appears more than once in element). Just change it to:
<div class="container row">

isAuthenticated and isAnonymous are returning false simultaneously

In my current spring project, I had a view with this html code:
<th:block sec:authorize="isAuthenticated()">
<h2 sec:authentication="name"></h2>
</th:block>
<th:block sec:authorize="isAnonymous()">
<p> <a th:href="#{/loginPage}">Login</a> </p>
<p>
<ul>
<li> <a th:href="#{/homeFacebook}">Connect to Facebook</a> </li>
<li> <a th:href="#{/homeTwitter}">Connect to Twitter</a> </li>
</ul>
</p>
</th:block>
which when I run the application, nothing is being displayed in the page, because the conditionals sec:authorize="isAuthenticated()" and sec:authorize="isAnonymous()" are both returnin false;
My configuration:
At my Application.java class
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect( new SpringSecurityDialect() );
return engine;
}
At my pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
I have other projects whit similar configuration working fine, but in this one i stuck this issue. Someone can see what's wrong here?
update
I change the pom.xml to this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>LATEST</version>
</dependency>
and now instead of show nothing, both blocks are being displayed. (if i remove thymeleaf-spring3 from list of dependencies in the pom.xml file, the page display none of the blocks, like before)
update 2
with this code, the page display nothing:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
with that one display both blocks:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity3</artifactId>
<version>LATEST</version>
</dependency>
but sec:authentication is not processed.

Resources