HTTP Status 404 the requested ressource is not available / Spring boot - maven

I wanted to test the code in
http://spring.io/guides/gs/handling-form-submission/ but when i run the application , i have http status 404, the requested ressource is not available
I don't know why , could you help ?
package controller;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HelloController implements ErrorController{
private static final String PATH = "/error";
#RequestMapping(value = PATH)
public String error() {
return "Error";
}
#Override
public String getErrorPath() {
return PATH;
}
#RequestMapping(value="/greeting", method=RequestMethod.GET)
public String greetingForm(Model model) {
model.addAttribute("greeting", new Greeting());
return "greeting";
}
#RequestMapping(value="/greeting", method=RequestMethod.POST)
public String greetingSubmit(#ModelAttribute Greeting greeting, Model model) {
model.addAttribute("greeting", greeting);
return "result";
}
}
package controller;
public class Greeting {
private long id;
private String content;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration;
#EnableAutoConfiguration(exclude=ErrorMvcAutoConfiguration.class)
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="#{/greeting}" th:object="${greeting}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
Submit another message
</body>
</html>
<?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>org.test</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.TestApplication</start-class>
<java.version>1.7</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-jdbc</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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
![The architecture of the application ![\]\[1\]][1]
[1]: http://i.stack.imgur.com/bgSzx.png

Related

Passing tokens through microservices using oauth2 authentication through GitHub

For this assignment we are to implement oauth2 using OAuth Apps in GitHub. We have two microservices UMS (UserManagmentService) and Messaging service. I am following the tutorial https://spring.io/guides/tutorials/spring-boot-oauth2/, as recommended - and it is working fine. I now have to extract the token and save it to a database with an expiry of 15 minutes in order to pass it to the other microservice (? I believe there is better ways to implement this). I would rather use JWT but do not understand the process to do so after using oauth2 through GitHub. My main questions are:
How to extract the token and store it to a database
How to set an expiry to the token
If possible, how to use a JWT instead and do the above.
I have limited knowledge of this as it is a new concept, any help would be appreciated.
INDEX.HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Tweeter</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width"/>
<base href="/"/>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/webjars/js-cookie/js.cookie.js"></script>
</head>
<body>
<h1>Welcome to Tweeter!</h1>
<div class="container unauthenticated">
Log In With GitHub
</div>
<div class="container authenticated" style="display:none">
Logged in as: <span id="user"></span>
</div>
<div>
<button onClick="logout()" class="btn btn-primary">Logout</button>
</div>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
var logout = function() {
$.post("/logout", function() {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
})
return true;
}
$.ajaxSetup({
beforeSend : function(xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT'
|| settings.type == 'DELETE') {
if (!(/^http:.*/.test(settings.url) || /^https:.*/
.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-XSRF-TOKEN",
Cookies.get('XSRF-TOKEN'));
}
}
}
});
</script>
</body>
</html>
WEBSECURITY
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
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;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(auth -> auth
.antMatchers("/", "/error", "/webjars/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exc -> exc
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.csrf(c -> c
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
)
.logout(l -> l
.logoutSuccessUrl("/").permitAll()
)
.oauth2Login()
;
}
}
OAUTH2 CONTROLLER
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.net.http.HttpHeaders;
import java.util.Collections;
import java.util.Map;
#RestController
public class oauth2Controller {
#Autowired
private OAuth2AuthorizedClientService authorizedClientService;
#GetMapping(value="/user")
public Map<String, Object> username(#AuthenticationPrincipal OAuth2User principal) {
return Collections.singletonMap("name", principal.getAttribute("name"));
}
#GetMapping(value="/getAuthentication", produces="application/json")
public String getAuthentication(OAuth2AuthenticationToken auth) {
return auth.toString();
}
#GetMapping(value = "/getToken", produces = "application/json")
public String getEmails(OAuth2AuthenticationToken authentication) {
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(
authentication.getAuthorizedClientRegistrationId(),
authentication.getPrincipal().getName());
String token = client.getAccessToken().getTokenValue();
return token;
}
}
APPLICATION.YAML
## Server
server:
port: 8080
## MySQL
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://0.0.0.0:3306/ums?serverTimezone=UTC&useLegacyDatetimeCode=false
username: root
password: passw
#GitHub
security:
oauth2:
client:
registration:
github:
clientId: ***********
clientSecret: ************
scope: read:user, user:name
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.7.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.cst8277.gibbons.caitlyn</groupId>
<artifactId>ums</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ums</name>
<description>ums</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</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>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Added after creation-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>3.0.0</version>
</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>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>js-cookie</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

How to predict data in an input field with spring boot as user type?

Can anyone please help me out on this issue?
I would like to predict words from a database into an input field using spring boot. Example if I type « I am searching for a book called snowfall » in the input field, the title snowfall should be predicted in this field when the user starts to type the word if it exists in the database.
Many thanks in advance for your answers.
Please see below the content of my html file, and java files:
index.html:
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Books</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body class="text-center">
<div>
<img th:src="#{/images/index.PNG}"/>
</div>
<div class="container-fluid">
<div class="h-100 row align-items-center">
<div class="col-sm-4"></div>
<div class="col-sm-4">
<h2>Find a Book</h2>
<form method="post">
<div class="form-group" id="owner">
</div>
<div class="form-group">
Books List
</div>
<div class="text-center">
</div>
<div class="form-group">
<input type="submit" value = "Search">
</div>
</form>
</div>
</div>
</div>
<div>
</div>
<div id='owner1' style='margin:0 auto;width:100%;'></div>
<div>
<table class="table">
<thead>
<tr>
<th scope="col">Book Name</th>
<th scope="col">Author</th>
<th scope="col">Book Reference</th>
</tr>
</thead>
<tbody>
<tr >
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<!--<script th:src="#{/search/js/source1.js}"></script>-->
<script src="source1.js"></script>
<script>
var owner = document.getElementById('owner');
var p = completely(owner, {
fontSize:'32px',
promptInnerHTML:''
});
p.input.style.borderTop = '2px solid #999';
p.input.style.borderBottom = '2px solid #999';
p.onChange = function (text) {
p.startFrom = text.lastIndexOf(' ')+1;
p.repaint();
};
p.options = ["snowvfall","Romeo & Juliet","C++"];
p.input.maxLength = 50; // limit the max number of characters in the input text
</script>
<script>
var selectedOptionText = $('#owner').find(":selected").text();
$("p").text(selectedOptionText);
</script>
</body>
</html>
Books.java:
package com.progweb.Progweb.Models;
import javax.persistence.*;
#Entity
#Table(name = "books")
public class Books {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name="bookName", length=100, nullable=false, unique=false)
private String bookName;
#Column(name="bookRef", length=100, nullable=false, unique=false)
private String bookRef;
#Column(name="bookAuthor", length=100, nullable=false, unique=false)
private String bookAuthor;
}
BookController.java:
package com.progweb.Progweb.Controllers;
import com.progweb.Progweb.Models.Books;
import com.progweb.Progweb.Repository.BooksRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.ArrayList;
import java.util.List;
#Controller
#RequestMapping(path="/books")
public clas`enter code here`s BookController {
#Autowired
private BooksRepository booksRepository;
#GetMa`enter code here`pping("/index")
public String index () {
return "index";
}
//Affichage de la page books
#GetMapping("/showPage_Books")
public String ShowPage_Books(Model model, RedirectAttributes attributes){
List<Books> books = new ArrayList<Books>();`enter code here`
books = booksRepository.allBooks();
attributes.addFlashAttribute("books",books);
//model.addAttribute("books", books);
return "Page_Books";
}
}
BooksRepository.java:
package com.progweb.Progweb.Repository;
import com.progweb.Progweb.Models.Books;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface BooksRepository extends CrudRepository<Books, Integer> {
#Query(value = "select * from books",nativeQuery = true)
public List<Books> allBooks();
}
my pom.xmlfile:
<?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>com.progweb</groupId>
<artifactId>Progweb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Progweb</name>
<description>School project</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-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</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-webflux</artifactId>
</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>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
if im following your requirement , when the UI user inserts for example "a" you would like to show a list of all books starting (or containing a), this is called a LIKE query - using the #Query annotation you are already using in your repo you should do this (this will return everything that contains 'a'):
#Query("SELECT b FROM books b WHERE b.bookName LIKE %:title%")
List<Book> searchByTitleLike(#Param("title") String title);
for everything starting with 'a':
#Query("SELECT b FROM books b WHERE b.bookName LIKE :title%")
List<Book> searchByTitleLike(#Param("title") String title);
this is an altered example taken from this article: https://www.baeldung.com/spring-jpa-like-queries

Spring boot WAR file Runs successfully on Eclipse IDE and by terminal but not running on external Tomcat 9.0

I have created a SpringBoot application with thymeleaf template, This application running successfully on Eclipse IDE and Running War file by MAC terminal command:
java -jar ./SpringBootTestMe.war
But problem is that it is not running on external tomcat-9.0, Giving below ERROR:
Sun Jan 26 09:01:37 IST 2020 There was an unexpected error
(type=Internal Server Error, status=500). Error during execution of
processor
'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'
(template: "index" - line 13, col 28)
My source code are
File pom.xml
<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.spboot</groupId>
<artifactId>SpringBootTestMe</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootTest</name>
<packaging>war</packaging>
<!-- lookup parent from repository -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.spboot.web.TestApp</start-class>
</properties>
<dependencies>
<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-thymeleaf</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-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>SpringBootTestMe</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringBootMainClass
package com.spboot.web;
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 TestApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
System.out.println("--------AppStarted--------");
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(TestApp.class);
}
}
HomeController
#Controller
#RequestMapping("SpringBootTestMe")
public class HomeController {
#RequestMapping(value={"", "login"})
public String login(UserRecord userRecord) {
System.out.println("HomeController Called...");
return "index";
}
}
ModalClass
public class UserRecord implements Serializable {
private Long id;
private String username;
private String email;
//Setters and getters
}
index.html
<!DOCTYPE html>
<html xmlns:th="https://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<div>
<form action="#" th:action="#{/login}" th:object="${userRecord}" method="post">
<table>
<tr>
<td><label for="username">User Name</label></td>
<td><input type="text" th:field="*{username}" /></td>
<td th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username Error</td>
</tr>
<tr>
<td><label for="email">Email</label></td>
<td><input type="text" th:field="*{email}"></input></td>
<td th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Name Error</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"></input></td>
</tr>
</table>
</form>
</div>
</body>
</html>
It's giving error on username text field, tomcat not recognising the th:field
Can anybody help me please.
Thanks

sec:authorize always returning same view in browser for both isAuthenticated() and isAnonymous() in thymeleaf view

home Controller
package com.book.controller;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.book.entity.User;
import com.book.security.entity.PasswordResetToken;
import com.book.security.entity.Role;
import com.book.security.entity.UserRole;
import com.book.security.impl.MailConstructor;
import com.book.security.impl.SecurityUtility;
import com.book.security.impl.UserSecurityService;
import com.book.security.repo.UserService;
#Controller
public class HomeController {
#Autowired
private JavaMailSender mailSender;
#Autowired
private MailConstructor mailConstructor;
#Autowired
private UserService userService;
#Autowired
private UserSecurityService userSecurityService;
#RequestMapping("/")
public String index() {
return "index";
}
#RequestMapping("/login")
public String login(Model model) {
model.addAttribute("classActiveLogin", true);
return "myAccount";
}
#RequestMapping("/forgetPassword")
public String forgetPassword(HttpServletRequest request, #ModelAttribute("email") String email, Model model) {
model.addAttribute("classActiveForgetPassword", true);
User user = userService.findByEmail(email);
if (user == null) {
model.addAttribute("emailNotExist", true);
return "myAccount";
}
String password = SecurityUtility.randomPassword();
String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
user.setPassword(encryptedPassword);
userService.save(user);
String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
SimpleMailMessage emails = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user,
password);
mailSender.send(emails);
model.addAttribute("emailSent", "true");
return "myAccount";
}
#RequestMapping(value = "/newUser", method = RequestMethod.POST)
public String newUserPost(HttpServletRequest request, #ModelAttribute("email") String userEmail,
#ModelAttribute("username") String username, Model model) throws Exception {
model.addAttribute("classActiveNewAccount", true);
model.addAttribute("email", userEmail);
model.addAttribute("username", username);
if (userService.findByUsername(username) != null) {
model.addAttribute("usernameExists", true);
return "myAccount";
}
if (userService.findByEmail(userEmail) != null) {
model.addAttribute("emailExists", true);
return "myAccount";
}
User user = new User();
user.setUsername(username);
user.setEmail(userEmail);
String password = SecurityUtility.randomPassword();
String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
user.setPassword(encryptedPassword);
Role role = new Role();
role.setRoleId(1);
role.setName("ROLE_USER");
Set<UserRole> userRoles = new HashSet<>();
userRoles.add(new UserRole(user, role));
userService.createUser(user, userRoles);
String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
SimpleMailMessage email = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user,
password);
mailSender.send(email);
model.addAttribute("emailSent", "true");
return "myAccount";
}
#RequestMapping("/newUser")
public String newUser(Locale locale, #RequestParam("token") String token, Model model) {
PasswordResetToken passToken = userService.getPasswordResetToken(token);
if (passToken == null) {
String message = "Invalid Token.";
model.addAttribute("message", message);
return "redirect:/badRequest";
} else {
User user = passToken.getUser();
String username = user.getUsername();
UserDetails userDetails = userSecurityService.loadUserByUsername(username);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails,
userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
model.addAttribute("user", user);
model.addAttribute("classActiveEdit", true);
return "myProfile";
}
}
}
Header.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head th:fragment="common-header">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Le's Bookstore</title>
<!-- Bootstrap core CSS -->
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<link href="/css/non-responsive.css" rel="stylesheet" />
<!-- Custom styles for this template -->
<link href="/css/style.css" rel="stylesheet" />
<link rel="icon" href="/image/applie-touch-icon.png" />
</head>
<body>
<div th:fragment="navbar">
<div class="page-top"
style="width: 100%; height: 20px; background-color: #f46b42;"></div>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">LE'S BOOKSTORE</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav navbar-left">
<li class="dropdown"><a href="#" class="dropdown-toggle"
data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">BOOKS <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Browse the bookshelf</li>
<li>Store hours & Directions</li>
<li>FAQ</li>
</ul></li>
<form class="navbar-form" role="search">
<div class="form-group">
<input type="text" name="keyword" class="form-control"
placeholder="Book title" />
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>SHOPPING CART</li>
<li sec:authorize="isAnonymous()"><a th:href="#{/login}">MY ACCOUNT</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="#{/myProfile}">MY ACCOUNT</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="#{/logout}">LOGOUT</a></li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
<!--/.container-fluid -->
</nav>
</div>
<div th:fragment="body-bottom-scripts">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</div>
</body>
</html>
SecurityConfig
package com.book.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.book.security.impl.SecurityUtility;
import com.book.security.impl.UserSecurityService;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/image/**",
"/",
"/newUser",
"/forgetPassword",
"/login",
"/fonts/**"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable().cors().disable()
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
.and()
.rememberMe();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
}
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>com.rakib.springboot</groupId>
<artifactId>book-shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>book-shop</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-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-jdbc</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-complete</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Problem:
sec:authorize returning true for both isAuthenticated() and isAnonymous() in thymeleaf view. i try to hide my_Profile, Log in when user log in and when log out then show only Log in.
BUT ITS not working ....
enter image description here
not working in both condition. please help me sir to continue the project.
SHOPPING CART
MY ACCOUNT
MY ACCOUNT
LOGOUT
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
When you upgrade your security version 5 and it will be fixed.
Try changing this
<li sec:authorize="isAnonymous()"><a th:href="#{/login}">MY ACCOUNT</a></li>
For this
<li sec:authorize="!isAuthenticated()"><a th:href="#{/login}">MY ACCOUNT</a></li>

Controller class cannot find html template

My directory
I'm trying to create spring boot application for school that lists books to a html page from database with a controller.
Personally, i think that the problem is that the controller cannot find the template for some reason. Because when i navigate to the wanted template through chrome, it just shows "booklist" on the page, nothing else.
I've tried creating totally new project and copying the code from my other files to the new files with no results.
My controller class:
#Controller
#ResponseBody
public class BookController {
#Autowired
BookRepository bookRepository;
#RequestMapping(value = "/books", method = RequestMethod.GET)
public String getBooks(Model model) {
List<Book> books = (List<Book>) bookRepository.findAll();
model.addAttribute("books", books);
return "booklist";
}
My html template:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Book List</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Books</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Year</th>
<th>Isbn</th>
<th>Price</th>
</tr>
<tr th:each="book : ${books}">
<td th:text="${book.id}">id</td>
<td th:text="${book.title}">title</td>
<td th:text="${book.year}">year</td>
<td th:text="${book.isbn}">isbn</td>
<td th:text="${book.price}">price</td>
</tr>
</table>
</body>
</html>
pom.xml 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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>hh.swd20</groupId>
<artifactId>Bookstore</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Bookstore</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties file:
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
Remove the annotation #ResponseBody from your controller class, because:
The #ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.
Then the returned String booklist will be used by Spring-MVC to resolve the named HTML template file.
The template file (e.g. booklist.html) will be looked for by default within default template directory is src/main/resources/templates.
Otherwise make sure to have configured the ViewResolver properly.
For Thymeleaf you have to add dependency to your Maven POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
See also this Spring-Boot & Thymeleaf tutorial
You can try this .
Hit : localhost://yourportnumber/api/books
//#Controller
#RestController
//#ResponseBody
#RequestMapping("/api")
public class BookController {
#Autowired
BookRepository bookRepository;
#GetMapping(value = "/books", method = RequestMethod.GET)
public ModelAndView getBooks(Model model) {
List<Book> books = (List<Book>) bookRepository.findAll();
model.addAttribute("books", books);
ModelAndView mav = new ModelAndView("booklist");
return mav;
}

Resources