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

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?

Related

Call Rest endpoint and display data into Spring MVC table

I have this Endpoint:
#RestController
public class FileImportsController {
private EntityImportRequestsService entityImportRequestsService;
#Autowired
public FileImportsController(EntityImportRequestsService entityImportRequestsService) {
this.entityImportRequestsService = entityImportRequestsService;
}
#GetMapping("/imported_files")
public String viewHomePage(Model model) {
List<EntityImportRequestsTable> listProducts = entityImportRequestsService.findAll();
System.out.println("Size is " + listProducts.size());
model.addAttribute("listProducts", listProducts);
return "index";
}
}
Entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder(toBuilder = true)
#Entity
#Table(name = "EntityImportRequests")
public class EntityImportRequestsTable implements Serializable {
#Id
#Column(name = "requestId")
private String requestId;
}
Web page index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8"/>
<title>Product Manager</title>
</head>
<body>
<div align="center">
<h1>Product List</h1>
<table border="1" cellpadding="10">
<tr>
<th>requestId</th>
</tr>
<tr th:each="product: ${listProducts}">
<td th:text="${product.requestId}" />
<td th:text="${product.name}" />
<td th:text="${product.price}" />
</tr>
</table>
</div>
</body>
</html>
When I open the page data is not displayed. What is the proper way to call endpoint imported_files and display all the data?

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

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)

Error message not showing in view page in JSR303, using Bootstrap in jsp

I am adding server side validation in my project. and somehow the error message from controller is not reaching view page.
I am using :
spring
jpa,
JSR303 for validation, and
bootstrap
Below is code for add.jsp
<!DOCTYPE html>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<style>
.error {
color: #ff0000;
}
.errorblock {
color: #000;
background-color: #ffEEEE;
border: 3px solid #ff0000;
padding: 8px;
margin: 16px;
}
</style>
<title>Add User</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="col-md-4">
<h2>Add User</h2>
<form:form action="user" method="post" role="form"
commandName="user">
<form:errors path="*" cssClass="errorblock" />
<div class="form-group ">
<label for="user">User Name:</label>
<form:input type="text" class="form-control" path="name"
id="name" placeholder="Enter User Name" required="requried"/>
</div>
<div class="form-group">
<label for="email">Email Address:</label>
<form:input type="email" path="emailAddress" class="form-control"
id="email" placeholder="Enter Email Address" required="requried"/>
</div>
<div class="form-group">
<label for="role">Role:</label>
<form:select path="role" class="form-control" id="role" required="requried">
<option disabled selected></option>
<c:forEach var="role" items="${roles}">
<option value="${role.value}">${role.name}</option>
</c:forEach>
</form:select>
</div>
<button type="submit" value="Submit" name="add"
class="btn btn-info active">Submit</button>
Back
</form:form>
</div>
<div class="col-md-4">
<div class="col-md-4"></div>
</div>
</div>
</div>
</div>
</body>
</html>
Below is code for Controller.java
#RequestMapping(value = "/user", params = "add", method = RequestMethod.GET)
public String getAddUser(Model model) {
ArrayList<Role> roles = new ArrayList<Role>();
// From user Add only admin and head of department can be added
roles.add(Role.ADMIN);
roles.add(Role.HEAD_OF_DEPARTMENT);
model.addAttribute("roles", roles);
model.addAttribute("user", new User());
return "user/add";
}
#RequestMapping(value = "/user", params = "add", method = RequestMethod.POST)
public String postAddUser(#ModelAttribute #Valid User user,
BindingResult result) {
if (result.hasErrors()) {
return "redirect:user?add";
} else {
System.out.println("Inside postAddUser");
user = userRepository.save(user);
return "redirect:user?id=" + user.getId();
}
}
Below is code for User.java
package in.ac.jmi.entities;
import in.ac.jmi.constants.Role;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
#Entity
#Table(name="USER")
public class User extends UrlEntity{
#Column(name="NAME", nullable = false)
#NotEmpty(message="Name can not be empty")
private String name;
#Column(name="ROLE", nullable = false)
#NotNull(message="Role can not be left blank")
private Role role;
#Column(name = "EMAIL_ADDRESS", nullable = false)
#NotEmpty(message="email address can not be empty")
private String emailAddress;
public User(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
#Override
public String toString() {
return "\nUser [name=" + name + ", role=" + role + ", emailAddress="
+ emailAddress + "]";
}
}
The reason is you are using return "redirect:user?add";, which cleared the error messages in model, try change it to return "user?add";

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>

Resources