How to pass individual variables to view in thymeleaf? - spring

Hi I'm building a skeleton of a car renting webapp and I'm trying to create a view that shows some details like location name, car name etc.
View code- car-list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Vehicle List</title>
<h2 th:text="${location1}">Locations</h2>
<table class="table table-stripped">
<thead>
<td th:text="${vehicle1Name}">Vehicle Name</td>
</tr>
</thead>
<td th:text="${vehicle2Name}">Vehicle Name</td>
</tr>
</table>
</head>
<body>
</body>
</html>
And heres my controller
package com.project.CS4125.controller;
import com.project.CS4125.model.*;
import com.project.CS4125.service.UserService;
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 java.util.ArrayList;
import java.util.List;
#Controller
#RequestMapping("/car-list")
public class VehicleController {
#GetMapping("/car-list")
public String carList(Model model){
Vehicle VWGolf = new BasicCar();
Vehicle Duster = new SUVDecorator(new BasicCar());
Location limerick= new Location("Limerick");
model.addAttribute("location1", limerick.getLocationName());
model.addAttribute("vehicle1Name", "Volkswagen Golf");
model.addAttribute("vehicle2Name", "Dacia Duster");
return "index";
}
}
My problem is the view comes up completely empty, any help appreciated.
EDIT
Before this page I have a register and login page
index.html (register page
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<form action="#" th:action="#{/register}" th:object="${user}"
method="post">
<p>User Name <input type="text" name="name"></p>
<p>Password <input type="password" name="password"></p>
<button type="submit">Register</button>
</form>
<button>Login Here</button>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="#" th:action="#{/login}" th:object="${user}"
method="post">
<p>User Name <input type="text" name="name"></p>
<p>Password <input type="password" name="password"></p>
<button type="submit">Login</button>
</form>
<button>Register Here</button>
</body>
</html>
And heres the controller for these
#Controller
#RequestMapping("/")
public class IndexController {
#Autowired
private UserService userService;
#Autowired
private CustomerFactory userFactory;
#PostMapping("/register")
public String registerUser(#ModelAttribute User user){
User u = userFactory.createUser(user.getName(), user.getPassword());
userService.saveUser(u);
return "login";
}
#GetMapping("/login")
public String login(){
return "login";
}
#PostMapping("/login")
public String loginUser(#ModelAttribute User user){
User authenticatedUser = userService.authenticate(user.getName(), user.getPassword());
System.out.println(authenticatedUser.toString());
return "car-list";
}
}
Even after adding the code from the answer below I'm still getting an empty page, after submitting the login form moving to the car list page its still empty.
I also noticed in the answer the URL is http://localhost:8080/car-list but when I try it its http://localhost:8080/login

I've just tested your code and you have two problems.
The first one is at your:
#Controller
#RequestMapping("/car-list")
public class VehicleController {
#GetMapping("/car-list")
In this GetMapping you're saying that you want to access your template at /car-list/car-list.
The seccond one is with your template name. You're returning "index" when you should return "car-list", at this you're returning the template name.
So, editting your code like this:
#Controller
#RequestMapping("/car-list")
public class VehicleController {
#GetMapping
public String carList(Model model){
model.addAttribute("location1", "Answer");
model.addAttribute("vehicle1Name", "Volkswagen Golf");
model.addAttribute("vehicle2Name", "Dacia Duster");
return "car-list";
}
}
I got:
Template working and returning

Related

I can't show an html page

I have to develop a project for college using Spring. I started watching some tutorials and I can't show an html page. I do the same but it returns only one string.
I'm using visual studio code.
Controller:
package com.example.springteste.controllers;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProductController {
#GetMapping("/formulario")
public String formulario()
{
return "form";
}
}
My view is just inside templates
View:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<main>
<section id="sectionProduct">
<div>
<div id="sectionProduct-title">
<h1>
Título
</h1>
</div>
<div id="sectionProduct-form">
<form action="">
<div class="sectionProduct-form-inputLabel">
<input type="text" id="title" name="title">
<label for="title">
Título
</label>
</div>
</form>
</div>
</div>
</section>
</main>
</body>
</html>
I believe something is missing. I am a beginner in java and spring
If you want to return a view name from the controller method handler - you have to use #Controller annotation. Also make sure you put your views into the correct directory, according to your view resolver configuration.
About #RestController - as the name suggests, it shall be used in case of REST style controllers i.e. handler methods shall return the JSON/XML response directly to the client rather using view resolvers.
In your case the handler method will return "form" to the client.

use Thymleaf and spring met org.springframework.web.method.annotation.MethodArgumentTypeMismatchException

I am running a springboot demo,integrated with Thymleaf.But it keep throwing the following exeption:
WARN 25302 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved
[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:
Failed to convert value of type 'java.lang.String' to required type
'java.lang.Long'; nested exception is java.lang.NumberFormatException:
For input string: "form.html"]**
controller:
#RestController
#RequestMapping("/users")
public class UserController {
#Autowired
private UserRepository userRepository;
private List<User> getUserlist() {
return userRepository.listUser();
}
#GetMapping
public ModelAndView list(Model model) {
model.addAttribute("userList", getUserlist());
model.addAttribute("title", "user management");
return new ModelAndView("users/list", "userModel", model);
}
#GetMapping("/form")
public ModelAndView createForm(Model model) {
User user=new User();
user=userRepository.saveOrUpateUser(user);
model.addAttribute("user", user);
model.addAttribute("title", "create user");
return new ModelAndView("users/form", "userModel", model);
}
list.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title th:text="${userModel.title}">welcome</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}">...</div>
<h3 th:text="${userModel.title}">Welcome to baidu.com</h3>
<div>
create user
</div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>Age</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">no user info!!</td>
</tr>
<tr th:each="user : ${userModel.userList}">
<td th:text="${user.id}">1</td>
<td th:text="${user.age}">11</td>
<td><a href="view.html" th:href="#{'/users/' + ${user.id}}"
th:text="${user.name}">waylau</a></td>
</tr>
</tbody>
</table>
<div th:replace="~{fragments/footer :: footer}">...</div>
</body>
</html>
form.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title th:text="${userModel.title}">users : View</title>
</head>s
<body>
<div th:replace="~{fragments/header :: header}">...</div>
<h3 th:text="${userModel.title}">Welcome to baidu.com</h3>
<div>
back to home
</div>
<form action="/users" method="POST" th:object="${userModel.user}">
<input type="hidden" name="id" th:value="*{id}">
名称:<br>
<input type="text" name="name" th:value="*{name}">
<br>
年龄:<br>
<input type="text" name="age" th:value="*{age}">
<input type="submit" value="提交">
</form>
<div th:replace="~{fragments/footer :: footer}">...</div>
</body>
</html>
User.java
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement // mediatype 转为xml
public class User {
private long id; // 用户的唯一标识
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
....getter and setter
}
on the home page,everything goes fine,except the create user anchor which should return a form to fill.
any idea?

Property [id] not found on type [java.util.Optional]

I am trying to perform crud operation with spring boot and i am new to it. I have successfully performed delete and create part. The problem i am having when i am trying to edit my fields. I am using MYSQL as my database. I am having error mentioned in question title. Any help to resolve it and please check my logic i think my logic is wrong in /showUpdate method. When i press edit button then it is not taking me to edit page and throwing me this error.
My controller class is pasted below:
Snapshot of Actual error i am having
package com.bilal.location.controllers;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.bilal.location.entities.Location;
import com.bilal.location.service.LocationService;
#Controller
public class LocationController {
#Autowired
LocationService service;
#RequestMapping("/showCreate")
public String showCreate() {
return "createLocation";
}
#RequestMapping("/savLoc")
public String saveLocation(#ModelAttribute("location") Location location,ModelMap modelMap) {
Location locationSaved = service.saveLocation(location);
String msg = "Location saved with id: " + locationSaved.getId();
modelMap.addAttribute("msg", msg);
return "createLocation";
}
#RequestMapping("/displayLocations")
public String displayLocations(ModelMap modelMap) {
List<Location> locations = service.getAllLocations();
modelMap.addAttribute("locations", locations);
return "displayLocations";
}
#RequestMapping("/deleteLocation")
public String deleteLocation(#RequestParam("id")int id,ModelMap modelMap) {
Location location = new Location();
location.setId(id);
service.deleteLocation(location);
List<Location> locations = service.getAllLocations();
modelMap.addAttribute("locations", locations);
return "displayLocations";
}
#RequestMapping("/showUpdate")
public String showUpdate(#RequestParam("id")int id,ModelMap modelMap) {
Optional<Location> location = service.getLocationById(id);
modelMap.addAttribute("location", location);
return "updateLocation";
}
#RequestMapping("/updateLoc")
public String updateLocation(#ModelAttribute("location") Location location,ModelMap modelMap) {
service.updateLocation(location);
List<Location> locations = service.getAllLocations();
modelMap.addAttribute("locations", locations);
return "displayLocations";
}
}
Display Location JSP Page:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Display Locations</title>
</head>
<body>
<h2>Locations:</h2>
<%--Table Starting from here --%>
<table>
<tr>
<th>id</th>
<th>code</th>
<th>name</th>
<th>type</th>
</tr>
<c:forEach items = "${locations}" var="location" >
<tr>
<td>${location.id}</td>
<td>${location.code}</td>
<td>${location.name}</td>
<td>${location.type}</td>
<td>delete</td>
<td>edit</td>
</tr>
</c:forEach>
</table>
<%--Table Ending here --%>
Add Location
</body>
</html>
Update Location JSP Page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Create Location</title>
</head>
<body>
<form action="updateLoc" method="post">
<pre>
id: <input type="text" name="id" value = "${location.id}" readonly/>
code: <input type="text" name="code" value = "${location.code}"/>
name: <input type="text" name="name" value = "${location.name}"/>
type: rural <input type ="radio" name="type" value ="RURAL" ${location.type=='URBAN'?'checked':'' }/>
Urban <input type ="radio" name="type" value= "URBAN" ${location.type=='RURAL'?'checked':'' }/>
<input type="submit" name="save"/>
</pre>
</form>
</body>
</html>
Read the error message carefully. It says you are trying to acces .id, but not on your Location, but on an Optional instead - which doesn't have that property.
Check your code:
#RequestMapping("/showUpdate")
public String showUpdate(#RequestParam("id")int id,ModelMap modelMap) {
Optional<Location> location = service.getLocationById(id);
modelMap.addAttribute("location", location);
return "updateLocation";
}
You are not adding the location, but an Optional that might contain the location.
You can check whether an Optional holds a value by calling ìsPresent(), e.g.
if (location.isPresent()) {
modelMap.addAttribute("location", location.get());
} else {
// ERROR?
}
More on Optional, if you are not familiar: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
In my case it was solve by
In controller
ModelAndView modelAndView = new ModelAndView();
Optional<Employee> employee = employeeRepository.findById( employeeDto.getId());
if (employee.isPresent()) {
modelAndView.addObject("employeeDto", employee.get());
System.out.println(employee);
} else {
System.out.println("Error Found"); // error message
}
In views

Spring MVC Thymeleaf binding List with check boxes

I am trying to create a form using thymeleaf that contains a series of checkboxes. The object source that I am passing through to the thymeleaf template contains a String and a List.
package com.controller;
import java.util.List;
public class Source {
private String sourceName;
private List<String> testList;
public String getSourceName()
{
return sourceName;
}
public void setSourceName(String name)
{
this.sourceName = name;
}
public List<String> getTestList()
{
return testList;
}
public void setTestList(List<String> list)
{
this.testList = list;
}
}
I pass an object of type source into the template using this MVC controller.
package com.controller;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import org.springframework.web.servlet.View;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import com.web_application.AllEnvironmentsFromFile;
import com.web_application.AllTestsAndPaths;
import com.web_application.RunDao;
import com.web_application.TestAndPath;
#RestController
public class ManualTestController {
#Autowired
private ThymeleafViewResolver resolver;
#Autowired
RunDao rDao;
#Autowired
AllEnvironmentsFromFile environments;
#RequestMapping(value="/manualTest", method=RequestMethod.GET)
public View greetingForm(Model model) throws Exception {
AllTestsAndPaths a = new AllTestsAndPaths();
List<TestAndPath> testList = a.testsAndPaths();
String[] environmentList = new String[environments.getEnvironments().size()];
for(int i = 0; i < environments.getEnvironments().size(); i++)
{
environmentList[i] = environments.getEnvironments().get(i).getName();
}
model.addAttribute("testList", testList);
model.addAttribute("source", new Source());
model.addAttribute("environmentList", environmentList);
return resolver.resolveViewName("manualTest", Locale.US); }
#RequestMapping(value="/manualTest", method=RequestMethod.POST)
public String greetingSubmit(#ModelAttribute Source source, Model model) {
System.out.println(source.getSourceName());
for(String hello : source.getTestList())
{
System.out.println(hello);
}
model.addAttribute("source", source);
return "result";
}
}
The manualTest template looks like this
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="#" th:action="#{/manualTest}" th:object="${source}" method="post">
<p>Source: <input type="text" th:field="*{sourceName}" /></p>
<table border="1">
<tr>
<td>Test Name</td>
<td th:each="environment : ${environmentList}"
th:text="${environment}">Tests</td>
</tr>
<th:block th:each="test : ${testList}">
<tr>
<td th:text="${test.name}">A Test'</td>
<th:block th:each="enviro : ${environmentList}">
<td><input type="checkbox" path="${testList}" value="hello" /></td>
</th:block>
</tr>
</th:block>
</table>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
My problem is that the values of the checkbox are not being stored in the array. When i run this code and click submit i get a null pointer exception because the list in the source object is empty. The sourceName works perfectly but the checkboxes are not actually adding anything.
THis code ended up working, You need to pass in an object containing an arrayList. Also it helped that I combined two variables into one string and i later separated them by -.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="#" th:action="#{/manualTest}" th:object="${source}" method="post">
<table border="1">
<tr>
<td>Test Name</td>
<td th:each="environment : ${environmentList}"
th:text="${environment}">Tests</td>
</tr>
<th:block th:each="test : ${testList}">
<tr>
<td th:text="${test.name}">A Test'</td>
<th:block th:each="enviro : ${environmentList}">
<td><input type="checkbox" th:field="*{testList}" th:value="|${test.name}-${enviro}|" /></td>
</th:block>
</tr>
</th:block>
</table>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>

How to pass variable value from jstl to controller

I have name and password in jsp/jstl
i tried to pass name and password to controller.
this is my controller class
package com.simple.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/welcome")
public class HelloController {
private String name;
private String password;
private String user;
#RequestMapping(method = RequestMethod.POST)
public String printWelcome(ModelMap model) {
System.out.println(user);
model.addAttribute(name);
model.addAttribute(password);
model.addAttribute("message", "Spring 3 MVC Hello World");
return "hello";
}
}
this is index.jsp with form tag and c tag libraries
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Registration Page</title>
</head>
<body bgcolor="#999966">
<p> </p>
<form method="POST" action="welcome">
<p><font color="#800000" size="5">
UserName:</font><input type="text" name="name" size="20"></p>
<c:set var="user" value="{param.name}" scope="request">
</c:set>
<p><font color="#800000" size="5">
password:</font><input type="text" name="password" size="20"></p>
<p><input type="submit" value="Submit" name="B1"></p>
</form>
</body>
</html>
i am trying to pass the variable user( the value is taken from the name variable) from this form to controller.
<c:set var="user" value="{param.name}" scope="request">
</c:set>
can any body help me how to do this with c tags..
i have done with using commandName="registereduser" where user is the object of class RegisteredUser.
But i am trying with just passing the variable (with c tags)
I am getting null value for user in sysout
is there any way to do with c tags with the set
thank you..
In your controller:
#Controller
#RequestMapping("/welcome")
public class HelloController {
#RequestMapping(method = RequestMethod.POST)
public String printWelcome(ModelMap model, #RequestParam String name, #RequestParam String password) {
// do something with name & password
model.addAttribute(name);
model.addAttribute(password);
model.addAttribute("message", "Spring 3 MVC Hello World");
return "hello";
}
}
and in your JSP (you have to use a regular HTML form):
<form method="POST" action="welcome">
<table>
<tr>
<td>User Name :</td>
<td><input type="text" id="name" name="name"/></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="password" id="password" name="password"/></td>
</tr>
</table>
<tr>
<td colspan="2"><input type="submit"></td>
</tr>
</table>
</form>
EDIT TO QUESTION (user variable added):
You need to pass user to controller with an input hidden and add another #RequestParam to controller method:
JSP:
<input type="hidden" id="user" name="user" value="${name}"/>
Controller method:
public String printWelcome(ModelMap model, #RequestParam String name,
#RequestParam String password, #RequestParam String user) {
...
I think you can't send user value to server with c tags, you need to submit data (form) to controller.

Resources