Spring MVC Thymeleaf binding List with check boxes - spring

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>

Related

How to pass individual variables to view in thymeleaf?

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

Web.servlet.PageNotFound - No mapping for GET

I'm learnig how Spring boot + MVC works. I can display a message on the screen, but I can not modifying the style. The js e css file don't map with Spring.
2020-04-17 14:38:29.169 WARN 9552 --- [nio-8080-exec-3] o.s.web.servlet.PageNotFound : No mapping for GET /js/main.js
2020-04-17 14:38:29.169 WARN 9552 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for GET /css/main.css
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class HelloController {
#GetMapping("/")
public String index() {
return "index";
}
#PostMapping("/hello")
public String sayhello(#RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello";
}
#GetMapping({"/helloworld", "/helloname"})
public String hello(Model model, #RequestParam(value="name", required=false, defaultValue="WORLD") String name) {
model.addAttribute("name", name);
return "helloname";
}
}
I've tryied to modify the path in the application.properties, but it didn't change anything.
spring.mvc.view.prefix = /WEB-INF/view/
spring.mvc.view.suffix = .jsp
spring.mvc.static-path-pattern = /resources/**
This is my jsp page. When I run this page , I get the error message, that I've posted before
<!DOCTYPE html>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css"
href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
<c:url value="/css/main.css" var="jstlCss" />
<link href="${jstlCss}" rel="stylesheet" />
</head>
<body>
<div class="container">
<header>
<h1>Spring MVC + JSP + JPA + Spring Boot 2</h1>
</header>
<div class="starter-template">
<h1>Users List</h1>
<table
class="table table-striped table-hover table-condensed table-bordered">
<tr>
<th>Date</th>
<th>Device</th>
<!-- <th>Amount</th>
<th>OEE</th> -->
</tr>
<c:forEach items="${OEE}" var="oee">
<tr>
<!-- <td>${oee.oeeID.date}</td>
<td>${oee.oeeID.device}</td> -->
<td>${oee.amount}</td>
<td>${oee.oee}</td>
</tr>
</c:forEach>
</table>
</div>
</div>
<script type="text/javascript"
src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
use this
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}

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?

Request method 'POST' not supported | SPRING BOOT

I'm trying to mount a simple start menu and I get an error in the POST method when I press the submit button.
My controller with the post method called by the submit in html with value "login"
#Controller
#RequestMapping("usuario")
public class UsuarioControlador {
#Autowired
private UsuarioServicio usuarios;
#RequestMapping(method=RequestMethod.GET )
public String index(ModelMap modelMap){
modelMap.put("usuario",new Usuario());
return "usuario/index";
}
//#PostMapping("/login")
#RequestMapping(value="login",method=RequestMethod.POST)
public String login(#ModelAttribute("usuario")Usuario usuario,HttpSession session,ModelMap modelMap){
if(usuarios.findByUserId(usuario.getIdUsuario())!=null){
session.setAttribute("informacion", usuario.getInformacion());
return "usuario/welcome";
}else{
modelMap.put("error", "Usuario no valido");
return "usuario/index";
}
}
}
My index.html with the submit call "login"
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form th:action="#{/usuario/login}"
th:objects="${usuario}" method="post">
<table cellpading="2" cellspacing="2">
<tr>
<td>Usuario</td>
<td><input type="text" th:field="*{idUsuario}" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="login" /></td>
</tr>
</table>
<br/>
<span th:text="${error}"></span>
</form>
</body>
</html>
You have to configure the #RequestMapping tag, to match with the form action /usuario/login, the slash sign its missing.
Replace
#RequestMapping("usuario")
with
#RequestMapping("/usuario")
And Replace
#RequestMapping(value="login",method=RequestMethod.POST)
with
#RequestMapping(value="/login",method=RequestMethod.POST)

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