How do you reference a Java class using Thymeleaf? I'm trying to display the result of my Java class on a website. When I use Spring Boot to display the output of the Java class it works, and when I use Spring Boot to display a Thymeleaf HTML template it also works, but I'm stuck now on how to call the java class from within the Thymeleaf HTML code.
Spring Boot Application File
package net.javavatutorial.tutorials;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootExampleApplication.class, args);
}
}
Controller File
package net.javavatutorial.tutorials;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#Controller
#RequestMapping("/")
class MainController
{
#RequestMapping(method = RequestMethod.GET)
ModelAndView
index()
{
ModelAndView mav = new ModelAndView("index");
mav.addObject("version", "0.1");
return mav;
}
}
Filewalk.java that takes in a directory path and outputs the files contained in that directory
package net.javavatutorial.tutorials;
import java.io.File;
public class Filewalk {
public static String filewalk(String s) {
String result = "";
// creates a file object
File file = new File(s);
// returns an array of all files
String[] fileList = file.list();
for (String str : fileList) {
result += str + "\n";
}
return result;
}
}
Index.HTML file where I want to display the Filewalk.java output String
<!DOCTYPE html>
<html>
<head>
<meta charset = "ISO-8859-1" />
<link href = "css/styles.css" rel = "stylesheet"/>
<title>Spring Boot Application</title>
</head>
<body>
<h4>Thymeleaf Spring Boot web application</h4>
</body>
</html>
The way you do this should be something like this:
Controller:
#RequestMapping(method = RequestMethod.GET)
public ModelAndView index() {
ModelAndView mav = new ModelAndView("index");
mav.addObject("version", "0.1");
mav.addObject("filewalk_results", Filewalk.filewalk("directory"));
return mav;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset = "ISO-8859-1" />
<link href = "css/styles.css" rel = "stylesheet"/>
<title>Spring Boot Application</title>
</head>
<body>
<h4>Filewalk results:</h4>
<pre th:text="${filewalk_results}" />
</body>
</html>
You do all the actual calculation and create objects/information to put on your model, then output it in the HTML.
Related
In my Spring Boot Application, I have a HTML Thymeleaf form in which I grab a String Value from the user. I want to pass this value from my Controller Class, to my Service Class and finally in Repo Class. The latter has an #Query and the purpose of this whole implementation is to give users the ability to choose contents from my database based on their input. For example, I have records that vary in different dates. I want user to choose the date that their want and the proper records get displayed from my database.
I have trouble in my controller class in which I need somehow to connect my model and pass it as parameter in my service class. Then the latter should communicate with the Repo Class to execute the query in the #Query and return my results. Until now, all I am getting is null values.
What am I doing wrong???
CONTROLLER CLASS
package com.andrekreou.covid.gov.controller;
import com.andrekreou.covid.gov.model.Covid;
import com.andrekreou.covid.gov.service.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
#Controller
public class WelcomePageController {
private final Service service;
#Autowired
public WelcomePageController(Service service) {
this.service = service;
}
#Value("${welcome.message}")
private String message;
#GetMapping("/")
public String main(Model model){
model.addAttribute("message", message);
return "welcome";
}
#GetMapping("/login")
public String getLoginView() {
return "login";
}
#GetMapping("/date/insert")
public String getDateInsertView() {
return "date-insert";
}
#GetMapping("/show-contents")
public String showAllRates(HttpServletRequest request){
request.setAttribute("covidcases", service.showAllCases());
return "databasecontents";
}
#RequestMapping(value = "/dateInsertion", method = RequestMethod.POST)
public String submit(#ModelAttribute("covid") Covid covid,
ModelMap model,
HttpServletRequest request) {
model.addAttribute("referencedate", covid.getReferencedate());
request.setAttribute("covidcases", service.showCases("referencedate"));
return "databasecontents";
}
}
SERVICE CLASS
package com.andrekreou.covid.gov.service;
import com.andrekreou.covid.gov.model.Covid;
import com.andrekreou.covid.gov.repository.CovidRepo;
import org.springframework.beans.factory.annotation.Autowired;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
#org.springframework.stereotype.Service
#Transactional
public class Service {
private final CovidRepo covidRepo;
#Autowired
public Service(CovidRepo covidRepo) {
this.covidRepo = covidRepo;
}
public List<Covid> showAllCases(){
return new ArrayList<>(covidRepo.findAll());
}
public List<Covid> showCases(String referencedate){
return new ArrayList<>(covidRepo.findByReferencedate(referencedate));
}
}
REPO CLASS
package com.andrekreou.covid.gov.repository;
import com.andrekreou.covid.gov.model.Covid;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface CovidRepo
extends JpaRepository<Covid,Integer> {
#Query("select e from #{#entityName} e where e.referencedate = ?1")
List<Covid> findByReferencedate(#Param("referencedate") String referencedate);
}
THYMELEAF VIEW
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>login</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous">
<style>
body {
background-color: #3e3e3e;
color: white;
}
</style>
</head>
<body>
<div class="container">
<form class="form-signin" method="post" action="/dateInsertion" th:object="${covid}">
<h2 class="form-signin-heading">Please Choose The Date</h2>
<p>
<label for="referencedate" class="sr-only">Username</label>
<input type="text" id="referencedate" name="referencedate" class="form-control" placeholder="referencedate" required=""
autofocus="">
</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">Set Date</button>
</form>
</div>
</body>
</html>
Thymeleaf is a rendering engine so it has no functionality it performs when you post something to your controller. which means basic form posting applies which in your case would be 1 field named referencedate
Asuming your covid entity has this as variable with valid setter method the error would be in this request.setAttribute("covidcases", service.showCases("referencedate")); line where it should be request.setAttribute("covidcases", service.showCases(covid.getReferencedate()));
If your covid entity does not include this parameter you have to either add it or seperatly add it to your controller function as a #RequestParam String referencedate
I am learning spring boot. I created this super simple project, but I keep getting a 404 Whitelabel error page when I try to return an HTML page with the #GetMapping annotation.
Here is my only controller:
package com.example.springplay;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class MainController {
#GetMapping(value = "/")
public String hello(){
return "hello";
}
}
Here is the spring application:
package com.example.springplay;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringplayApplication {
public static void main(String[] args) {
SpringApplication.run(SpringplayApplication.class, args);
}
}
Here is the directory
Here is the hello.html page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello world</h1>
</body>
</html>
The hello.html page is in the resources/templates folder, I don't know what's going on.
I copied this part which has the exact same structure from another working project, yet mine just gives me this Whitelabel error page.
Move hello.html to static folder in resource and change controller like this:
#GetMapping(value = "/")
public String hello(){
return "hello.html";
}
or like this:
#GetMapping(value = "/")
public ModelAndView hello(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("hello.html");
return modelAndView;
}
Remplace here
#GetMapping(value = "/")
public String hello(){
return "hello";
}
or like this
#RequestMapping(path = "/", produces = MediaType.TEXT_HTML_VALUE)
public String welcomepage() {
return "hello";
}
I have a Spring MVC application with thymeleaf.
Depending on a condition tested in the controller method I want to show or hide an html element from the view (input, span, div, button...).
How to do that? For instance, in asp.net you can do myButton.Visible = false (or true) if you want or don't want to display it.
Anything like that available in thymeleaf with spring? Thanks.
You can achieve it by passing the attribute via
org.springframework.ui.Model and use Thymeleaf's th:if attribute
Demo:
package com.example.demo.controllers;
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 MealController {
#GetMapping("/order")
public String getCondition(#RequestParam(required = false) String myMeal, Model model) {
model.addAttribute("meal", myMeal);
return "meal/meal-site";
}
}
resources/templates/meal-site.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hot Dog?</title>
</head>
<body>
<div th:if="'hotdog' == ${meal}">A hotdog! ðŸŒ</div>
<div th:if="'hotdog' != ${meal}">Not a hotdog 😢</div>
</body>
</html>
I am learning Spring Framework. I added home.html in resources/templates/home.html. But it is not visible when I visit http://localhost:8080. I have the following structure:
taco-cloud\src\main\java\tacos\TacoCloudApplication.java
package tacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class TacoCloudApplication {
public static void main(String[] args) {
SpringApplication.run(TacoCloudApplication.class, args);
}
}
taco-cloud\src\main\java\tacos\HomeController.java
package tacos;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class HomeController
{
#GetMapping("/")
public String home()
{
return "home.html";
}
}
taco-cloud\src\main\resources\static\home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
</head>
<body>
<h1>Welcome to...</h1>
<img th:src="#{/images/TacoCloud.png}"/>
</body>
</html>
Output
Whitelable error page
localhost:8080/home.html
show home.html
You have to change the location of your home page to be in the static folder :
resources/static/home.html
^^^^^^
instead of
resources/templates/home.html
and specify the extension in your controller :
return "home.html";
^^^^^
else you have to create a view resolver to avoid using extensions and to specify the other locations of your pages take a look at Configure ViewResolver with Spring Boot and annotations gives No mapping found for HTTP request with URI error
You can try this.
#GetMapping("/")
public String home()
{
return "templates/home.html";
}
Check more details
Below are few different ways you can place html files in your project.(Note it is from highest to lowest precedence)
src/main/resources/resources/home.html
src/main/resources/static/home.html
src/main/resources/public/home.html
Go through this to get an idea about spring mvc project structure
I have a problem on validating a simple "NumberValidate" Object
Here you see the JSP file:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Vul een nummer in:</h1>
<form:form action="form" modelAttribute="number" method="POST">
<form:input path="number"/>
<form:errors path="number"/>
<input type="submit" value="submit"/>
</form:form>
</body>
</html>
Controller:
package controller;
import domain.NumberValidate;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class ValidationController {
#RequestMapping(value = {"form"}, method = RequestMethod.GET)
public String showHomePage(Model model){
model.addAttribute("number", new NumberValidate());
return "validation";
}
#RequestMapping(value = {"form"}, method = RequestMethod.POST)
public String showHomePage(#Valid #ModelAttribute NumberValidate number, BindingResult result){
if(result.hasErrors())
return "validation";
return "success";
}
}
The "NumberValidate" Class:
package domain;
import javax.validation.constraints.Min;
public class NumberValidate {
#Min(50)
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
When i run the application it starts normal with the textbox etc.
When I type a number less then 40 it gives the error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'number' available as request attribute
Can somebody help me with this problem?
In showHomePage method, change to #ModelAttribute("number") and:
if(result.hasErrors()) {
return "validation";
}
return "success";
if validation has error then you need to add number attribute in model when returning to validation view. Code snippet is below :
#RequestMapping(value = {"form"}, method = RequestMethod.POST)
public String showHomePage(#Valid #ModelAttribute NumberValidate number, BindingResult result){
if(result.hasErrors()){
model.addAttribute("number", number);
return "validation";
}
return "success";
}