Spring boot app is deployed on websphere 9.0.5.2. The application is not able to resolve the html page from templates folder but it displays the name of the page in string format when changing @Controller to @RestController or using using @ResponseBody in method declaration.
My application.properties is set as follows
spring.thymeleaf.enabled=true
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=/templates
spring.thymeleaf.suffix=.html
my pom.xml has dependency for thymeleaf added
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>client</groupId>
<artifactId>abc</artifactId>
<version>1.0.0</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-version>5.1.3.RELEASE</spring-version>
<spring-boot-version>2.1.2.RELEASE</spring-boot-version>
<failOnMissingWebXml>false</failOnMissingWebXml>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ssZ</maven.build.timestamp.format>
</properties>
<artifactId>abcWeb</artifactId>
<packaging>war</packaging>
<name>abcWebApp</name>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot-version}</version>
<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-web-services</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot-version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxrpc-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>abcWeb</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Version>${version} - ${maven.build.timestamp}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
My Controller class
@Controller
@RequestMapping("/")
public class AbcController {
@GetMapping("/login")
public String login() {
return "login";
}
}
I have src/main/resources/templates folder which contains login.html and error.html files
Initially after trying this I was getting error
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Feb 21 14:21:20 EST 2020
There was an unexpected error (type=Internal Server Error, status=500).
Circular view path [login]: would dispatch back to the current handler URL [/abcWeb/login] again. Check your ViewResolver setup!
To configure it manually , I also tried to add the following configurations
package client.abc.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
But then I got other error as it couldn't find org.thymeleaf.ITemplateEngine in classpath it seems. Caused by: java.lang.ClassNotFoundException: org.thymeleaf.ITemplateEngine
Comment From: wilkinsona
Circular view path [login]: would dispatch back to the current handler URL [/abcWeb/login] again. Check your ViewResolver setup!
This sounds like a problem with your Security configuration. It would happen if you login page was secured and Spring Security was then redirecting to your login page so that the user could log in.
I can't be certain that this is the case as you haven't shared enough information about your application. Please review your Spring Security configuration and check that access to your login page isn't restricted. If that doesn't help and you would like us to spend some more time investigating, please provide a complete and minimal sample that reproduces the behaviour you have described.
Comment From: pankajpandey013
Hi wilkinsona, Please see the SecurityConfiguration which permits all request matching /login*
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomAuthenticationProvider.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Autowired
CustomAuthenticationProvider authenticationProvider;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated() // every user must be authenticated
.and()
.formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll()
.loginProcessingUrl("/doLogin")
.successForwardUrl("/postLogin")
.failureUrl("/loginFailed");
httpSecurity.csrf().disable();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
}
Comment From: mbhave
@pankajpandey013 We can't do much with snippets of code. As Andy mentioned above, please provide a complete and minimal sample that we can run and use to reproduce the issue you have mentioned.
Comment From: pankajpandey013
https://github.com/pankajpandey013/abc , I have created a git repo with sample code which can be imported and run as maven project
Comment From: pankajpandey013
@mbhave @wilkinsona were you able to reproduce the issue
Comment From: wilkinsona
But then I got other error as it couldn't find org.thymeleaf.ITemplateEngine in classpath it seems. Caused by: java.lang.ClassNotFoundException: org.thymeleaf.ITemplateEngine
I've reproduced this problem.
It is occurring because you have a mixture of Thymeleaf 2 and Thymeleaf 3 on the classpath. That's happening because you are not using Spring Boot's dependency management and you are using an old version of thymeleaf-extras-java8time
which pulls in Thymeleaf 2.
It can be fixed by using spring-boot-starter-parent
:
diff --git a/pom.xml b/pom.xml
index cb247aa..6393956 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,6 +2,12 @@
<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.1.2.RELEASE</version>
+ <relativePath/>
+ </parent>
<groupId>client</groupId>
<artifactId>abc</artifactId>
<version>1.0.0</version>
And removing the use of explicit versions where they are not needed:
diff --git a/abcWeb/pom.xml b/abcWeb/pom.xml
index c937167..fc9bb41 100644
--- a/abcWeb/pom.xml
+++ b/abcWeb/pom.xml
@@ -28,18 +28,15 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
- <version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
- <version>${spring-boot-version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -51,7 +48,6 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
- <version>${spring-boot-version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -63,14 +59,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
- <version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
- <version>${spring-boot-version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
@@ -78,19 +72,16 @@
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
- <version>${spring-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
- <version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
- <version>4.3.3</version>
</dependency>
<dependency>
@@ -108,7 +99,6 @@
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
- <version>2.1.0.RELEASE</version>
</dependency>
@@ -120,7 +110,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -130,7 +119,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
- <version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
I then made a couple of changes to allow me to run the application locally (rather than deploying it to WebSphere):
diff --git a/abcWeb/pom.xml b/abcWeb/pom.xml
index fc9bb41..22d35a2 100644
--- a/abcWeb/pom.xml
+++ b/abcWeb/pom.xml
@@ -37,25 +37,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- </exclusion>
- </exclusions>
</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>
+ <artifactId>spring-boot-starter-tomcat</artifactId>
+ <scope>provided</scope>
</dependency>
-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
With these changes in place I can access the login page where I'm presented with a form to submit the username and password. Doing so results in your CustomAuthenticationProvider
being called.
I can't see any evidence of a bug in Spring Boot here so I am going to close this issue. If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.