Thymeleaf views not found with springboot - gradle

I am trying to follow this tutorial for adding thymeleaf to a springboot app but I can't seem to get it to work.
Tutorial: http://spr.com/part-2-adding-views-using-thymeleaf-and-jsp-if-you-want/
I was able to get springboot to work fine when I started the app using #RestController in LoginController but when I changed #RestController to #Controller I'm getting an error page saying:
There was an unexpected error (type=Not Found, status=404).
No message available
I set a breakpoint in the controller and confirmed that it is hitting the index method in LoginController. I feel like this has to do with how I've added Thymeleaf since I haven't done much else to the application but everything I've tried so far results in the same error page.
my build.gradle
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'GazeFest'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.thymeleaf:thymeleaf-spring4:3.0.0.RELEASE")
}
task wrapper(type: Wrapper) {
gradleVersion = '3.0'
}
my Application.java
package gazefest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
my LoginController.java
package gazefest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#Controller
public class LoginController {
#RequestMapping("/")
public String index(Model model) {
model.addAttribute("message", "HELLO!");
return "index";
}
}
my index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<meta charset="UTF-8" />
<title>HELLO</title>
</head>
<body>
<p th:text="${message}"></p>
</body>
</html>
my file structure
Thanks for taking a look!

I don't think you should be using the thymeleaf-spring4 dependency, but you should be using the Spring boot starter for Thymeleaf.
For Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
For Gradle:
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
I suggest using the Spring Initializr to set up your project. This allows you to select any Spring boot starter and add it to your Gradle/Maven descriptor so you won't make any mistakes by picking a dependency.

Related

How to map JSP file in Spring boot?

This is my first spring boot application. I want to load home.jsp file in 8080 port.
When I run port 8080/home I can see home.jsp file is download. How I run that home.jsp
Bellow you can see my HomeController.Java file
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class HomeController {
#RequestMapping("home")
public String Home()
{
System.out.print("Hello");
return "home.jsp";
}
}
Bellow you can see my home.jsp file
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
I love Java
</body>
</html>
Bellow you can see my gradle.build file
plugins {
id 'org.springframework.boot' version '2.6.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
classpath('se.transmode.gradle:gradle-docker:1.2')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.apache.tomcat:tomcat-jasper:9.0.55'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
Here I added tomcat dependency
application.yml
server.port=8080
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
try adding the followings in gradle then update gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
runtime('com.h2database:h2')
runtime('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
ohh and add
'/' in front of the requestmapping
#Controller
public class HomeController {
#RequestMapping("/home")
public String Home()
{
System.out.print("Hello");
return "home.jsp";
}
}

Spring boot cannot resolve view page issue in mustache

package springboot.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class IndexController {
#GetMapping("/")
public String index() {
return "index";
}
}
index.html
<!DOCTYPE HTML>
<html>
<head>
<title>start</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>start</h1>
</body>
</html>
build.gradle
buildscript {
ext {
springBootVersion = '2.1.9.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group 'com.jojoldu.book'
version '1.0.4-SNAPSHOT-'+new Date().format("yyyyMMddHHmmss")
sourceCompatibility = 11
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.projectlombok:lombok')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-mustache')
compile('com.h2database:h2')
compile('org.springframework.boot:spring-boot-starter-oauth2-client')
compile('org.springframework.session:spring-session-jdbc')
compile("org.mariadb.jdbc:mariadb-java-client")
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile("org.springframework.security:spring-security-test")
}
I am using intellij and spring boot and use mustache to use templates. I installed mustache plugin and changed to .mustache instead of .html, but a can not resolve Mvc view error occurs in the controller and a 404 error occurs when I run it. What is the cause? ?
I put the same html file in the static folder and tried to /index.html in the view resolver but couldn't find it.

I am trying to load a jsp using spring boot with gradle but I am only getting internal server error

I am new to spring boot and trying to load a jsp page but even after trying a lot and searching on internet I couldn't find any solution of it. I am unable to get the error causing part in this complete process.
To build this all I used command 'gradle build' on command prompt.
To start the server I used command :- java -jar build\libs\one-0.0.1-SNAPSHOT.war
then I on browser I typed :- http://localhost:8080/helloWorld
Here is my build.gradle
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
id 'war'
}
group = 'com.tm'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'javax.servlet:jstl'
providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
This is my java code of controller HelloJSPController.java, it is in this folder structure: \src\main\java\com\tm\one
package com.tm.one;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class HelloJSPController
{
#GetMapping("/helloWorld")
public String helloWorld()
{
return "helloWorld";
}
}
This is WebMvcConfig.java configuration file
package com.tm.one.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
#Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
OR I tried this two lines in application.propertes also instead of above configuration file
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
This is JSP file helloWorld.jsp in folder structure :-- \one\src\main\webapp\WEB-INF\jsp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h2>Hello everyone I am AD</h2>
</body>
</html>
This is error I am getting on browser
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jan 13 16:53:14 IST 2020
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template [helloWorld], template might not exist or might not be accessible by any of the configured Template Resolvers
This is OneApplication.java
package com.tm.one;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class OneApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(OneApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(OneApplication.class);
}
}
Had the same issue as you, and I believe it's not due to the java code. The only solution I found was switching to maven. Absolutely no other change in the java code, only build.gradle -> pom.xml.

Gradle for this Spring Boot project + jsp

Im using Gradle for this Spring boot project and my task is to create another jsp file , for example : index.jsp and do something that Spring boot can generate that index.jsp
My problem is when i create index.jsp in webapp -> WEB_INF -> index.jsp
it only return the message 'index' instead of what is in file index.
Application.java
package edu.msudenver.tsp.website;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
PledgeController.java
package edu.msudenver.tsp.website.controllers;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class PledgeController {
#GetMapping("/hello")
public String getHelloMessage() {
return "index";
}
}
Application.properties
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
build.gradle
buildscript {
ext {
springBootVersion = '1.5.6.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
index.jsp
> <%# page contentType="text/html;charset=UTF-8" language="java" %>
> <html> <head>
> <title>Hello Spring mvc</title> </head> <body>
add dependencies for JSP
compile('javax.servlet:jstl')
compile("org.apache.tomcat.embed:tomcat-embed-jasper")
and index.jsp PATH is webapp/WEB_INF/jsp/index.jsp.
if you want example, https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp.
You have to use #Controller annotation instead of #RestController in your class PledgeController.
#Controller
public class PledgeController {
#GetMapping("/hello")
public String getHelloMessage() {
return "index";
}
}
I had the same issue. It's not about the java code. The only solution I found was switching to maven. The only change was build.gradle -> pom.xml, and nothing else in the controller or jsp file, what you have there is correct.

How to build a SOAP WS with Apache CXF + Spring Boot in Gradle?

The assignment was simple: A SOAP web service implemented with spring boot, JDBC using Gradle.
After some time looking around the discovery was made that "Spring-WS" only works with a contract-first development style.
And we didn't want that, so we dig a little further and found out what we already know, we had to use Apache CXF for a Contract Last development style.
So off we went to search, code and test; but once the data access and facades were done we couldn’t figure out how to wire the Apache CXF WS with the Spring Boot service Façade.
So… how is it done?
This is more of a rhetorical question, because after looking around we could not find an example of Spring Boot & Apache CXF working seamlessly together, so for anyone who may be searching, here is a simple example.
First the dependencies used by the Gradle project
build.gradle file
buildscript {
ext {
springBootVersion = '2.0.1.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
group = 'com.telcel'
version = '0.0.1-RC'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
configurations {
providedRuntime
}
dependencies {
// Apache CXF
compile(group: 'org.apache.cxf', name: 'cxf-spring-boot-starter-jaxws', version: '3.1.15') {
exclude(module: 'spring-boot-starter-tomcat')
}
// JDBC support
compile('org.springframework.boot:spring-boot-starter-jdbc')
// embedded servlet container
compile group: 'org.springframework.boot', name: 'spring-boot-starter-undertow', version: '1.5.4.RELEASE'
runtime group: 'com.ibm.informix', name: 'jdbc', version: '4.10.10.0'
testCompile('org.springframework.boot:spring-boot-starter-test')
testRuntime group: 'com.ibm.informix', name: 'jdbc', version: '4.10.10.0'
}
Then, we need some basic things for the CXF config.
application.properties file:
cxf.path=/service
server.address=0.0.0.0
We needed Spring Boot to create a CXF Endpoint, and we also needed that Endpoint to use our Spring aware Facade... this is where the wiring magic happened.
WebServiceConfig.java
package com.telcel.validaserie;
import com.telcel.validaserie.ui.ValidaSerieEndpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
#Configuration
public class WebServiceConfig {
#Autowired
private Bus bus;
#Autowired
private ValidaSerieEndpoint validaSerieEndpoint;
#Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, validaSerieEndpoint);
endpoint.publish("/");
return endpoint;
}
}
Notice the autowired ValidaSerieEndpoint that goes as a parameter into the EndpointImpl constructor, that's the trick, plain simple.
Finally just a simple web service implementation exposed as a Spring Bean (notice the Spring #Service stereotype)
ValidaSerieEndpoint.class
package com.telcel.validaserie.ui;
import com.telcel.validaserie.servicios.ValidaSeriesFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
#Service
#WebService
public class ValidaSerieEndpoint {
#Autowired
private ValidaSeriesFacade validaSeriesFacade;
#WebMethod
public String validaTelefonoIccid(#WebParam(name = "iccid") String iccid) {
return validaSeriesFacade.validaTelefonoIccid(iccid);
}
#WebMethod
public String validaTelefonoImei(#WebParam(name = "imei") String imei) {
return validaSeriesFacade.validaTelefonoImei(imei);
}
#WebMethod
public int validaFacturaIccid(#WebParam(name = "iccid") String iccid, #WebParam(name = "fuerza-venta") String fuerzaVenta) {
return validaSeriesFacade.validaFacturaIccid(iccid, fuerzaVenta);
}
#WebMethod
public int validaFacturaImei(#WebParam(name = "imei") String imei, #WebParam(name = "fuerza-venta") String fuerzaVenta) {
return validaSeriesFacade.validaFacturaImei(imei, fuerzaVenta);
}
}
And that's it quite simple after you look at it... hope this helps.

Resources