I am new in web app development and I want to create a login page for my web app (using Spring boot + Thymeleaf), but I cannot display the form.html when I make a request for /form.
This is my Entity class:
package com.example.springboot.model;
public class ApplicationUser {
private String username;
private String password;
public ApplicationUser(String username, String password) {
this.username = username;
this.password = password;
}
public ApplicationUser() { }
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My form.html looks like this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Form Submission</title>
</head>
<body>
<h1>User form</h1>
<form action="#" th:action="#{/form}" th:object="${applicationuser}" method="post">
<p>Username: <input type="text" th:field="*{username}"/></p>
<p>Password: <input type="text" th:field="*{password}"/></p>
<p><input type="submit" value="Send"/></p>
</form>
</body>
</html>
And the result.html is
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Result</title>
</head>
<body>
<h1>Result</h1>
<p th:text="'username: ' + ${applicationuser.username}"/>
<p th:text="'password: ' + ${applicationuser.password}"/>
Submit another
</body>
</html>
But applicationuser from th:object="${applicationuser}" is highlighted in red ("cannot resolve "applicationuser"). Can this be a problem? How to resolve it?
My Controller class is
#RestController
public class Test {
#RequestMapping(value = "/form",method = RequestMethod.GET)
public String userForm(Model model){
model.addAttribute("applicationuser",new ApplicationUser());
return "form";
}
#RequestMapping(value = "/form",method = RequestMethod.POST)
public String userSubmit(#ModelAttribute ApplicationUser user,Model model){
model.addAttribute("applicationuser",user);
String info = String.format("User Submission: username = %s, password = %s", user.getUsername(),user.getPassword());
System.out.println(info);
return "result";
}
}
I'm just trying to get input form and display them in console, but no way...
When I make a request in my browser: http://localhost:8080/form I obtain a white page with follow string "form", it doesn't display the textfields and button.
I have in pom.xml the thymeleaf dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Does anyone known what is the problem with my code?
Seems i got your problem. Change this section
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
to
<html xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sf="http://www.w3.org/1999/xhtml" lang="en">
And change your
<p>Username: <input type="text" th:field="*{username}"/></p>
<p>Password: <input type="text" th:field="*{password}"/></p>
to
<p>Username: <input type="text" id="username" name="username"/></p>
<p>Password: <input type="text" id="password" name="password" /></p>
One more thing, Change you #RestController to #Controller
If it works, let me know.
Related
I can't pass a object Project without the object is null.
How do I pass the object to the spring controller from the html?
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<form action="/addproject" method="POST">
<input type="hidden" name="project" th:value="${project}"/>
<input type="submit" value="Save Project" class="submit">
</form>
</body>
</html>
#Controller
public class ProjectController {
#GetMapping("/")
public String indexPage(Model model) {
model.addAttribute("project", new Project("Test", "Test"));
return "index";
}
#PostMapping("/addproject")
public String add(WebRequest webRequest) {
Project p = (Project) webRequest.getAttribute("project", WebRequest.SCOPE_REQUEST);
return "index";
}
}
Please check this article. In short you need to pass required object to ModelAndView, not Model:
#GetMapping("/")
public ModelAndView indexPage(Model model) {
ModelAndView mav = new ModelAndView("index");
mav.addObject("project", new Project("Test", "Test"));
return mav;
}
and access it by name from template:
<b th:text="${project.attribute}">Text ...</b>
I would suggest you to proceed with the document here first.
You don't have a requirement or problem with ModelAndView.
The first time you call the /project page, the project class information will be loaded by #GetMapping, if you want, it will be captured by #PostMapping when you change and submit it.
project.html file:
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Project Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Project Form</h1>
<form method="post" th:action="#{/project}" th:object="${project}">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
</body>
</html>
Project.java file:
public class Project {
private String name;
private String description;
public Project(String name, String description) {
this.name = name;
this.description = description;
}
// getter/setter ...
}
ProjectController.java file:
#Controller
public class ProjectController {
#GetMapping("/project")
public String greetingForm(Model model) {
model.addAttribute("project", new Project("PN1", "PD1"));
return "project";
}
#PostMapping("/project")
public String greetingSubmit(#ModelAttribute Project project, Model model) {
model.addAttribute("project", project);
return "project";
}
}
I am trying send the data through controller to html page but unable data transmission is getting failed. Control is redirecting to the desired page along with labels but form data is not reflecting in the view page.
***HomeController***
package com.example.demo.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.demo.domain.User;
#Controller
public class HomeController {
User user = new User();
#RequestMapping("/")
public String home(Model model) {
model.addAttribute("formData", user);
return "index";
}
#RequestMapping(value="/create", method=RequestMethod.POST)
public String processFormData(User user, RedirectAttributes attr) {
attr.addFlashAttribute("user",user);
return "redirect:display";
}
#RequestMapping(value="/display", method=RequestMethod.GET)
public String displayFormData(User user) {
return "result";
}
}
index.html
<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> Home Page </title>
</head>
<body>
<p> Enter Data Below </p>
<form action="/create" method="post" th:object="${formData}">
<p>Full Name:<input type="text" th:feild="${formData.fullName}"/></p>
<p>Age:<input type="text" th:feild="${formData.age}"/></p>
<p>Employed?<input type="checkbox" th:feild="${formData.employed}" th:value="true"/></p>
<p>Gender:</p>
<p>Male<input type="radio" th:feild="${formData.gender}" th:value="Male"/>
Female<input type="radio" th:feild="${formData.gender}" th:value="Female"/></p>
<p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
</form>
</body>
</html>
result.html
<html xmlns:th="https://thymeleaf.org">
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4 th:text="${user.fullName}"></h4></td>
</tr>
<tr>
<td><h4>Age: </h4></td>
<td><h4 th:text="${user.age}"></h4></td>
</tr>
</table>
</html>
The controller class sends and reads a form view. The User data is passed as a parameter to the processForm() handler. Spring tries to fill the bean with the request data. The data is also automatically available for the Thymeleaf result view. The #Controller annotation allows the implementation classes to be autodetected through the classpath scanning.
#Controller is typically used in combination with a #RequestMapping annotation used on request handling methods. I used the #GetMapping and ##PostMapping` as a shortcut to #RequestMapping(method = RequestMethod.POST)
#Controller
public class HomeController {
//This responds to localhost:8080/
#GetMapping("/")
public String sendForm(User user){
return "index";
}
//This responds to localhost:8080/
#PostMapping("/")
public String processForm(User user){
return "result";
}
User Class. This is the User class. It is automatically filled with data from the form request. The attributes must match the form fields. You should be able to see the matching attribute names in the template views below.
public class User {
private String fullName;
private int age;
private String occupation;
public String getFullName() {
return fullName;
}
public void setFullName(String name) {
this.fullName = name;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
index.html
The th:object refers to the user form bean. This is not a class name, but a Spring bean name; therefore it is in lowercase. With the *{} syntax, we refer to the defined object. In this case its the user object. I noticed that you misspelled th:field, this can also create bugs.
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<p> Enter Data Below </p>
<form th:action="#{/}" th:object="${user}" method="post">
<p>Full Name:<input type="text" th:field="*{fullName}" id="fullName" name="fullname" autofocus="autofocus"></p>
<p>Age:<input type="number" th:field="*{age}" id="age" name="age" autofocus="autofocus" /></p>
<p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
</form>
</body>
</html>
result.html
We identify the form attributes with the ${} syntax.
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4 th:text="${user.fullName}"></h4></td>
</tr>
<tr>
<td><h4>Age: </h4></td>
<td><h4 th:text="${user.age}"></h4></td>
</tr>
</table>
</body>
</html>
I'm trying to create a simple login page using Spring.
I've created a form as described in the tutorial [here][1]
For some reason, when I hit the submit button, the request doesn't go through to the controller. (I've set a breakpoint in the first line of the controllers method)
Does anyone have an idea why?
My code:
Controller:
#RequestMapping(value="/login", method=RequestMethod.POST)
public String login(#ModelAttribute(value="loginModel") LoginModel loginModel) {
if(loginModel.getEmail().equals("null") || loginModel.getPassword().equals("null")) {
return "Wrong user email or password";
}
return "result";
}
Model:
public class LoginModel {
private String email;
private String password;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public LoginModel(String email, String password) {
super();
this.email = email;
this.password = password;
}
}
View:
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="css/login.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<div class="form">
<ul class="tab-group">
<li class="tab active">Sign Up</li>
<li class="tab">Log In</li>
</ul>
<div id="login">
<h1>Welcome Back!</h1>
<form action="#" th:action="#{/login}" th:object="${loginModel}" method="post">
<div class="field-wrap">
<input type="email" required autocomplete="off" th:field="*{email}"/>
</div>
<div class="field-wrap">
<input type="password" required autocomplete="off" th:field="*{password}"/>
</div>
<p class="forgot">
Forgot Password?
</p>
<input type="submit" value="Log in" />
</form>
</div>
</div>
</body>
</html>
UPDATE:
Found the problem...
The LoginModel class MUST have empty constructor
Remove #ModelAttribute and then try again.
I am trying to receive all the request parameters from a form in controller having a modelobj. But the model parameters remains null. I dont want to create all the parameters and their setter/getters of models in my controller class...Plz help
Form :
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="/struts-tags" prefix="s"%>
<!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>Login</title>
</head>
<body>
<div>
<form action="login" method="post">
<label>Email Id</label>
<input type="text" name="emailId">
<label>Password</label>
<input type="password" name="password">
<input type="submit" value="Login">
</form>
</div>
</body>
</html>
Model :
public class UserModel {
String emailId;
String password;
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Controller :
import com.opensymphony.xwork2.ActionSupport;
public class LoginController extends ActionSupport{
UserModel userModelObj = new UserModel();
public UserModel getUserModelObj() {
return userModelObj;
}
public void setUserModelObj(UserModel userModelObj) {
this.userModelObj = userModelObj;
}
public String login()
{
UserModel userModelObj = new UserModel();
System.out.println(userModelObj.emailId);
System.out.println(userModelObj.password);
return "success";
}
}
On console it returns null null
You must use your bean class reference in your form's name attribute like this :
<div>
<form action="login" method="post">
<label>Email Id</label>
<input type="text" name="userModelObj.emailId"/>
<label>Password</label>
<input type="password" name="userModelObj.password"/>
<input type="submit" value="Login">
</form>
</div>
Otherwise use the concept Of ModelDriven interface.
I'm trying to handle a simple JSP form, that accepts your first and last name, and then prints:
Your first name: entered_first_name
Your last name: entered_last_name
using jsp:useBean action tags, so far with no luck...
Let me first show what I have written so far, and then I'll explain the problem.
This is how the UserData class looks like:
package pack;
public class UserData {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
This is how the first form (index.jsp) looks like:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<jsp:useBean id="userinfo" class="pack.UserData" scope="session"></jsp:useBean>
<jsp:setProperty property="*" name="userinfo"/>
<body>
<form action="MyServlet" method="post">
First Name: <input type="text" name="firstName"><br>
Last Name: <input type="text" name="lastName"><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
and this is the relevant part from MyServlet.java:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("another.jsp").forward(request, response);
}
and this is another.jsp:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<jsp:useBean id="userinfo" class="pack.UserData"></jsp:useBean>
<body>
Your first name: <%=userinfo.getFirstName() %><br>
Your last name: <%=userinfo.getLastName() %>
</body>
</html>
When I run index.jsp, enter my first and last name, and hit "Submit", I get:
Your first name: null
Your last name: null
Which is obviously bad.
First of all, and most importantly: what am I doing wrong? why aren't the setters invoked?
Second, as you might noticed, MyServlet.java doesn't do much. it only redirects to another.jsp, so do I really need it? is there a faster, more elegant way for redirecting from one jsp to another in cases where there is no much work to do between redirection?
You must put a UserData bean in a request attribute in your servlet before forwarding :
UserData userinfo;
userinfo.setFirstName(request.getParameter("firstName");
userinfo.setLastName(request.getParameter("lastName");
request.addAttribute("userinfo", userinfo);
request.getRequestDispatcher("another.jsp").forward(request, response);
If you want things to happen automatically, you will have to use a framework such as Struts2, Spring MVC, or ...
Simple form example to understand Bean properties
index.html
<form action="welcome.jsp">
Enter Name:<input type="text" name="firstName"/>
<input type="submit" value="go" />
</form>
welcome.jsp
<jsp:useBean id="obj" class="pack.UserData" />
<jsp:setProperty name="obj" property="*" />
Welcome, <jsp:getProperty name="obj" property="firstName" />
UserData.java
public class UserData {
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
System.out.print("the values are"+firstName);
}
}
You will get the values entered in the html page .