multi urls in Spring Security prmitAll not working - java

I have a spring boot app and i need to Primit multi urls in security Configration but that not working I did this :
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/login/**").antMatchers("/register").antMatchers("/home");
}
and this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().antMatchers("/login/**").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/home").permitAll()
.and().authorizeRequests().anyRequest().authenticated().and().httpBasic();
http.exceptionHandling()
.authenticationEntryPoint(
(request, response, ex) -> {
response.sendError(
HttpServletResponse.SC_UNAUTHORIZED,
ex.getMessage()
);
}
);
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
but it's the same, no pages loaded - only login screen appears-
In first code :
In second one :
This is my view controller class :
#Controller
public class ViewController {
#Autowired
IEmployeeRepository employeeRepository;
#GetMapping("/home")
public String viewHomePage(){
return "index";
}
#GetMapping("/register")
public String showRegistrationForm(Model model) {
model.addAttribute("user", new Employee());
return "signup_form";
}
#GetMapping("/login")
public String showLoginForm() {
return "login_form";
}
#PostMapping("/process_register")
public String processRegister(Employee user) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
employeeRepository.save(user);
return "register_success";
}
#GetMapping("/addCustomer")
public String addCustomer() {
return "addcustomer";
}
#GetMapping("/addItem")
public String addItem() {
return "additem";
}
}
and this is my html :
signup_ form :
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Sign Up</title>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container text-center">
<div>
<h1>User Registration - Sign Up</h1>
</div>
<form th:action="#{/process_register}" th:object="${user}"
method="post" style="max-width: 600px; margin: 0 auto;">
<div class="m-3">
<div class="form-group row">
<label class="col-4 col-form-label">E-mail: </label>
<div class="col-8">
<input type="email" th:field="*{email}" class="form-control" required />
</div>
</div>
<label class="col-4 col-form-label">Serial Number : </label>
<div class="col-8">
<input type="email" th:field="*{serialNumber}" class="form-control" required />
</div>
</div>
<div class="form-group row">
<label class="col-4 col-form-label">Password: </label>
<div class="col-8">
<input type="password" th:field="*{password}" class="form-control"
required minlength="4" maxlength="10"/>
</div>
</div>
<div class="form-group row">
<label class="col-4 col-form-label">First Name: </label>
<div class="col-8">
<input type="text" th:field="*{firstName}" class="form-control"
required minlength="2" maxlength="20"/>
</div>
</div>
<div class="form-group row">
<label class="col-4 col-form-label">Last Name: </label>
<div class="col-8">
<input type="text" th:field="*{lastName}" class="form-control"
required minlength="2" maxlength="20" />
</div>
</div>
<div class="form-group row">
<label class="col-4 col-form-label">Country: </label>
<div class="col-8">
<input type="text" th:field="*{country}" class="form-control"
required minlength="2" maxlength="20" />
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">Sign Up</button>
</div>
</form>
</div>
</body>
</html>
The index html :
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Welcome</title>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container text-center">
<h1>Welcome</h1>
<h3><a th:href="/#{/users}">List of Users</a></h3>
<h3><a th:href="/#{/register}">Register</a></h3>
<h3><a th:href="/#{/login}">Login</a></h3>
</div>
</body>
</html>
and this is Employee model :
#Entity
#Table(name = "employee")
public class Employee implements UserDetails {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name = "serial_number")
private long serialNumber;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "role_id")
private Role role;
private String email;
private String mobileNumber;
private String country;
private String password;
private boolean isDeleted;
#OneToMany
private Set<Invoice> invoices;
#OneToMany
private Set<InvoiceHistory> invoiceHistories;
public Employee(){}
public Employee(long serialNumber, String firstName, String lastName, Role role, String email, String mobileNumber,String country,String password){
super();
this.serialNumber = serialNumber;
this.firstName = firstName;
this.lastName = lastName;
this.role= role;
this.email = email;
this.mobileNumber = mobileNumber;
this.country = country;
this.password = password;
this.isDeleted = false;
}

The first one you are using ignoring lol.
The second one it's not Spring Security problem. This is Thymeleaf error, check your thymeleaf parsing.

Related

Null value passed from drop-down list

I am creating a Spring Boot application with thymeleaf where I have an relationship Many-to-One between a table named figures and a table named states (many figures to one state). Everything is OK when creating a state. The problem is with creating a figure.
These are the classes:
#Entity
#Table(name = "state")
public class State implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_state")
private Integer idState;
#Column(name = "official_state_name")
private String officialStateName;
#Column(name = "official_language")
private String officialLanguage;
#Column(name = "state_currency")
private String stateCurrency;
//setters and getters
#Entity
#Table(name = "figure")
public class Figure implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_figure")
private Long idFigure;
#Column(name = "pib")
private String fullName;
#Column(name = "date_of_birth")
private java.sql.Date dateOfBirth;
#Column(name = "date_of_death", nullable = true)
private java.sql.Date dateOfDeath;
#Column(name = "kind_of_activity")
private String kindOfActivity;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "id_state", nullable = false)
private State state;
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public Long getIdFigure() {
return this.idFigure;
}
public void setIdFigure(Long idFigure) {
this.idFigure = idFigure;
}
public String getFullName() {
return this.fullName;
}
public void setFullName(String pib) {
this.fullName = fullName;
}
public java.sql.Date getDateOfBirth() {
return this.dateOfBirth;
}
public void setDateOfBirth(java.sql.Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public java.sql.Date getDateOfDeath() {
return this.dateOfDeath;
}
public void setDateOfDeath(java.sql.Date dateOfDeath) {
this.dateOfDeath = dateOfDeath;
}
public String getKindOfActivity() {
return this.kindOfActivity;
}
public void setKindOfActivity(String kindOfActivity) {
this.kindOfActivity = kindOfActivity;
}
}
Now this is the controller for the Figure class:
#Controller
public class FigureController {
#Autowired
FigureService figureService;
#Autowired
FigureRepository figureRepository;
#Autowired
StateRepository stateRepository;
#Autowired
StateService stateService;
#GetMapping("/figures")
public String showAllFigures(Model model){
List<Figure> listFigures = figureService.findAllFigures();
model.addAttribute("listFigures", listFigures);
return "figures";
}
#GetMapping("/figures/new")
public String showNewFigureForm(Model model){
List <State> listStates = stateService.findAll();
model.addAttribute("listStates", listStates);
model.addAttribute("figure", new Figure());
model.addAttribute("pageTitleF", "Add New Figure");
return "figure_form";
}
#PostMapping("/figures/save")
public String saveFigure (Figure requestFigure, RedirectAttributes redirectAttributes) throws StateNotFoundException {
figureRepository.save(requestFigure);
redirectAttributes.addFlashAttribute("messageF", "The figure has been saved successfully!");
return "redirect:/figures";
}
#GetMapping("/figures/edit/{id}")
public String showEditFigureForm(#PathVariable("id") Integer id, Model model, RedirectAttributes redirectAttributes){
try {
Figure figure = figureService.findFigureById(id);
List <State> listStates = stateService.findAll();
model.addAttribute("listStates", listStates);
model.addAttribute("figure", figure);
model.addAttribute("pageTitleF", "Edit Figure (ID: " + id + ")");
return "figure_form";
} catch (EntityNotFoundException e) {
redirectAttributes.addFlashAttribute("messageF", e.getMessage());
return "redirect:/figures";
}
}
#GetMapping("/figures/delete/{id}")
public String deleteFigure(#PathVariable("id") Integer id, Model model, RedirectAttributes redirectAttributes){
try {
figureService.deleteFigure(id);
redirectAttributes.addFlashAttribute("messageF", "The figure ID " + id + " has been deleted!");
} catch (StateNotFoundException e) {
redirectAttributes.addFlashAttribute("messageF", e.getMessage());
}
return "redirect:/figures";
}
}
So I need to pass an id of state from drop-down list of states and assign it to the foreign key of the figure entity. These are the html files.
figures.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Welcome to My Application</title>
<link rel="stylesheet" type="text/css" th:href="#{/webjars/bootstrap/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container-fluid text-center">
<div><h2>Manage Figures</h2></div>
<div class="m-2">
<a class="h3" th:href="#{/figures/new}">Add New Figure</a>
</div>
<div class="m-2">
<a class="h3" th:href="#{http://localhost:8080/}">Back to Main Menu</a>
</div>
<div th:if="${messageF}" class="alert alert-success">
[[${messageF}]]
</div>
<div>
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th>ID</th>
<th>Full Name</th>
<th>Date of Birth</th>
<th>Date of Death</th>
<th>kindOfActivity</th>
<th></th>
</tr>
</thead>
<tbody>
<th:block th:each="figure : ${listFigures}">
<tr>
<td>[[${figure.fullName}]]</td>
<td>[[${figure.dateOfBirth}]]</td>
<td>[[${figure.dateOfDeath}]]</td>
<td>[[${figure.kindOfActivity}]]</td>
<td>
<a class="h4 mr-3" th:href="#{'/figures/edit/' +${figure.idFigure}}">Edit</a>
<a class="h4" th:href="#{'/figures/delete/' +${figure.idFigure}}">Delete</a>
</td>
</tr>
</th:block>
</tbody>
</table>
</div>
</div>
</body>
</html>
figure_form.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>[[${pageTitleF}]]</title>
<link rel="stylesheet" type="text/css" th:href="#{/webjars/bootstrap/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container-fluid">
<div class="text-center"><h2>[[${pageTitleF}]]</h2></div>
<form th:action="#{/figures/save}" method="post" th:object="${figure}"
style="max-width: 500px; margin: 0 auto;">
<input type="hidden" th:field="*{idFigure}">
<div class="border border-secondary rounded p-3">
<div class="form-group row">
<label class="col-sm-4 col-form-label">Full Name</label>
<div class="col-sm-8">
<input type="text" th:field="*{fullName}" class="form-control" required minlength="4" maxlength="40"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Date of Birth</label>
<div class="col-sm-8">
<input type="date" th:field="*{dateOfBirth}" class="form-control" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Date of Death</label>
<div class="col-sm-8">
<input type="date" th:field="*{dateOfDeath}" class="form-control" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">Kind of Activity</label>
<div class="col-sm-8">
<input type="text" th:field="*{kindOfActivity}" class="form-control" required maxlength="60"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">State</label>
<div class="col-sm-8">
<select class="form-control" id="idState" name="idState">
<option value="">Select State</option>
<option th:each="state : ${listStates}"
th:value="${state.idState}"
th:text="${state.idState}+' : '+${state.officialStateName}"></option>
</select>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary m-2">Save</button>
<button type="button" class="btn btn-secondary m-2" onclick="cancelForm()">Cancel</button>
</div>
</div>
</form>
</div>
<script type="text/javascript">
function cancelForm(){
window.location = "[[#{/figures}]]"
}
</script>
</body>
</html>
So the form looks like this:
When I hit the save button I get an error status 500:
And the error description
org.hibernate.PropertyValueException: not-null property references a null or transient value : com.historicalreferencebook.historicalreferencebook.domain.Figure.state
As you can see even though I chose a state and therefore its key is assigned to the foreign key of the figure entity, it is null. Why? And what should I do to pass the value from the drop down list to the foreign key of the figure? Any help is appreciated! Thanks in advance!
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "id_state", nullable = false)
private State state;
change to:
#ManyToOne(fetch = FetchType.LAZY,
optional = false,
cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "id_state", nullable = false)
private State state;
I got it solved by dropping a table and then creating it again with Maven installation, I changed the id data type to Integer and used this as a drop down list (because there is a "th:field" which tells Spring which field will be filled with a value from a drop down list):
<div class="form-group row">
<label class="col-sm-4 col-form-label">State</label>
<div class="col-sm-8">
<select th:field="*{state}" class="form-control" required>
<th:block th:each="state : ${listStates}">
<option th:text="${state.officialStateName}" th:value="${state.idState}"/>
</th:block>
</select>
</div>
</div>

Request method 'POST' not supported - Java Spring Boot

My resister page works fine, it takes the input and pushes to data base when "register" is clicked. However, when I click to go to a "list an item" page, which similarly takes input to be pushed to a table in a database when "list item" is clicked, it comes up with "Request Method 'POST' not supported". So the "list an item" page doesn't appear when clicked from the main logged-in menu page.
Part of the controller class here:
#GetMapping("/register")
public String goToRegisterPage(Model model) {
User user = new User();
model.addAttribute("user", user);
return "register_page";
}
#GetMapping("/go_to_create_item_page")
public String goToCreateItemPage(Model model) {
FreeItem freeItem = new FreeItem();
model.addAttribute("freeItem", freeItem);
return "create_item_page";
}
Part of the html file here that offers to go to the create_item_page:
<div>
<form th:action="#{/update_user_page}" method="post">
<input type="submit" value="Update account" />
</form>
</div>
<div>
<form th:action="#{/go_to_create_item_page}" method="post">
<input type="submit" value="List an Item" />
</form>
</div>
The create_item_page:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Create Item</title>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" />
</head>
<body>
<div class="container text-center">
<div>
<h1>Create an Item to list publicly</h1>
</div>
<form th:action="#{/process_created_item}" method="post"
style="max-width: 600px; margin: 0 auto;"
th:object="${freeItem}">
<div class="m-3">
<div class="form-group row">
<label class="col-form-label col-4">Item Name</label>
<div class="col-8">
<input type="text" class="form-control" th:field="*{itemName}" required
minlength="2" maxlength="20" />
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-4">Item Description</label>
<div class="col-8">
<input type="text" class="form-control"
th:field="*{itemDescription}" required
minlength="6" maxlength="10" />
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-4">Quantity Of Item</label>
<div class="col-8">
<input type="text" class="form-control" th:field="*{quantityOfItem}" required
minlength="2" maxlength="20" />
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-4">General Item Location</label>
<div class="col-8">
<input type="text" class="form-control" th:field="*{itemLocation}"
required minlength="2" maxlength="20" />
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-4">E-mail for contact</label>
<div class="col-8">
<input type="email" class="form-control" th:field="*{email}"
required />
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">List Item</button>
</div>
</div>
</form>
</div>
</body>
</html>
And the FreeItem class that specifies the objects being pushed to the database.
package com.marinelli.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name= "free_items")
public class FreeItem {
public FreeItem(String itemName, String itemDescription, String quantityOfItem, String itemLocation, String email) {
super();
this.itemName = itemName;
this.itemDescription = itemDescription;
this.quantityOfItem = quantityOfItem;
this.itemLocation = itemLocation;
this.email = email;
}
public FreeItem() {
}
#Id
#Column(nullable = false, unique = true, length = 64)
private String itemName;
#Column(nullable = false, length = 64)
private String itemDescription;
#Column(nullable = false, length = 25)
private String quantityOfItem;
#Column(nullable = false, length = 25)
private String itemLocation;
#Column(nullable = false, unique = true, length = 45)
private String email;
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemDescription() {
return itemDescription;
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDescription;
}
public String getQuantityOfItem() {
return quantityOfItem;
}
public void setQuantityOfItem(String quantityOfItem) {
this.quantityOfItem = quantityOfItem;
}
public String getItemLocation() {
return itemLocation;
}
public void setItemLocation(String itemLocation) {
this.itemLocation = itemLocation;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "FreeItem [itemName=" + itemName + ", itemDescription=" + itemDescription + ", quantityOfItem="
+ quantityOfItem + ", itemLocation=" + itemLocation + ", email=" + email + "]";
}
}
you need to create go_to_create_item_page and update_user_page as #Postmapping("....")
#Postmapping("/update_user_page")
public String goToUpdateUserPage(Model model) {
...
...
...
}
#Postmapping("/go_to_create_item_page")
public String goToCreateItemPage(Model model) {
...
...
...
}
The error clearly stated that you are using the incorrect method for that provided endpoint.
In your case, /go_to_create_item_page defined as GET, your form declared method = post. Either changing them to both use POST or GET should resolve the problem (In terms of API design, it should be GET, as you are getting resources from the server rather than creating / updating).

Spring+Thymeleaf: post data from modal form

I need to post data from html form into database. I have gradle project with springboot and thymeleaf.
I have java object Class witch has id, name, description, teacher and minutes.
In html I use modal form to ask for all but id.
main.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Class Scheduler</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="webjars/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"/>
<script type="text/javascript" src="webjars/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="webjars/bootstrap/4.0.0-beta.2/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="container">
<h2>Class Scheduler</h2>
<div class="text-right">
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#addClassModal">Add new class</button>
</div>
<div class="modal fade" id="addClassModal" tabindex="-1" role="dialog" aria-labelledby="addClassModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addClassModalLabel">Add new class</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form th:action="#{/addClass}" th:object="${class}" method="post">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" th:value="*{name}"/>
</div>
<div class="form-group">
<label for="description">Description:</label>
<input type="text" class="form-control" id="description" th:value="*{description}"/>
</div>
<div class="form-group">
<label for="teacher">Teacher:</label>
<input type="text" class="form-control" id="teacher" th:value="*{teacherName}"/>
</div>
<div class="form-group">
<label for="minutes">Minutes:</label>
<input type="number" class="form-control" id="minutes" th:value="*{timeMinutes}"/>
</div>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
And my controller looks like this:
#Controller
public class ScheduleController {
#Autowired
private ClassService classService;
#Autowired
private StudentService studentService;
#RequestMapping(value = "/addClass", method = RequestMethod.POST)
public String addClass(#RequestAttribute("class") Class newClass, Model model) {
classService.addClass(newClass);
return "main";
}
The error message, that I get is:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'class' available as request attribute.
What am I doing wrong?
Edit:
My ClassService looks like this:
#Service
public class ClassService{
private static final BeanPropertyRowMapper<Class> CLASS_ROW_MAPPER = BeanPropertyRowMapper.newInstance( Class.class );
#Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void addClass(final Class newClass) {
MapSqlParameterSource in = new MapSqlParameterSource();
in.addValue("id", newClass.getId());
in.addValue("name", newClass.getName());
in.addValue("description", newClass.getDescription());
in.addValue("teacher_name", newClass.getTeacherName());
in.addValue("time_minutes", newClass.getTimeMinutes());
namedParameterJdbcTemplate.update("INSERT INTO class(name, description, teacher_name, time_minutes) values(:name,:description,:teacher_name,:time_minutes)", in);
}
Here
public String addClass(#RequestAttribute("class") Class newClass, Model model) {
Use ModelAttribute instead of RequestAttribute
public String addClass( #ModelAttribute("class") Class newClass, Model model) {
Also, in your controller class return an instance of Class associated with the ModelAttribute
#ModelAttribute(value = "class")
public Class getClass()
{
return new Class();
}

JEE Spring submit form doesn't work with POST request

I'm using Spring and I would like to submit my agentForm with POST method but submitNewAgent isn't called on form submit. However, it works when I replace POST by GET. I've been working on it for a few days now, and I have no idea what to change. Does anyone can help me please ?
Here my files
new.html
<!DOCTYPE html>
<html lang="fr"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorator="index" >
<head th:replace="index :: head">
<link href="../../static/css/bootstrap.min.css" rel="stylesheet" media="screen" />
</head>
<body>
<th:block layout:fragment="body">
<h1 class="page-header"> Nouvel Agent </h1>
<form class="form" th:modelAttribute="agentForm" th:object="${agentForm}" action="/agents/ajouter-submit/" method="POST">
<div class="form-group">
<label>Prénom</label>
<div th:if="${#fields.hasErrors('prenom')}" th:errors="*{prenom}" class="text-danger">
Erreur prénom
</div>
<input type="text" th:field="*{prenom}" class="form-control" />
</div>
<div class="form-group">
<label th:for="*{nom}">Nom</label>
<div th:if="${#fields.hasErrors('nom')}" th:errors="*{nom}" class="text-danger">Erreur nom</div>
<input type="text" th:field="*{nom}" class="form-control" />
</div>
<div class="form-group">
<button class="btn btn-primary"><span class="glyphicon glyphicon-ok"></span>
<span th:remove="tag" th:text="#{label.add}"></span>
</button>
</div>
</form>
</th:block>
</body>
</html>
AgentForm.class
public class AgentForm {
#NotNull
#Size(min=2, max=255)
private String prenom;
#NotNull
#Size(min=2, max=255)
private String nom;
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
#Override
public String toString() {
return "Agent{" +
"prenom='" + prenom + '\'' +
", nom='" + nom + '\'' +
'}';
}
}
AgentController.class link agent views and agent model.
#Controller
#RequestMapping("/agents")
public class AgentController {
private final AgentService agentService;
#Autowired
public AgentController(AgentService agentService) {
this.agentService = agentService;
}
/**
* Gets all agents
*
* #param model view
* #return template name
*/
#RequestMapping(value = {"/", "lister"}, method = RequestMethod.GET)
public String allAgents(Model model) {
List<Agent> agentList = agentService.findAll();
if (agentList != null)
model.addAttribute("agentList", agentList);
return "agents/list";
}
/**
* Displays form to add an agent
*
* #return template and attributes
*/
#RequestMapping(value = {"/", "ajouter"}, method = RequestMethod.GET)
public ModelAndView addAgentForm() {
AgentForm a = new AgentForm();
a.setNom("test");
a.setPrenom("prenom");
return new ModelAndView("agents/new", "agentForm", a);
}
/**
* Manages the form to add an agent and submit in the repository
*
* #param agentForm form
* #param result results
* #param model form the view
* #param attributes view attributes
* #return url
*/
#RequestMapping(value = {"/", "ajouter-submit"}, method = RequestMethod.POST)
public String submitNewAgent(#ModelAttribute("agentForm") #Validated AgentForm agentForm,
BindingResult result, Model model, final RedirectAttributes attributes) {
if (result.hasErrors())
return "agents/new";
agentService.saveAndFlush(AgentAdapter.adaptAgentFormToAgent(agentForm));
attributes.addFlashAttribute("css", "success");
attributes.addFlashAttribute("msg", "L'agent est correctement ajouté !");
return "redirect:/agents/lister";
}
}
I'm sorry for mixing English and French.
<!DOCTYPE html>
<html lang="fr"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorator="index" >
<head th:replace="index :: head">
<link href="../../static/css/bootstrap.min.css" rel="stylesheet" media="screen" />
</head>
<body>
<th:block layout:fragment="body">
<h1 class="page-header"> Nouvel Agent </h1>
<form class="form" th:modelAttribute="agentForm" th:object="${agentForm}" th:action="#{ajouter-submit}" method="POST">
<div class="form-group">
<label>Prénom</label>
<div th:if="${#fields.hasErrors('prenom')}" th:errors="*{prenom}" class="text-danger">
Erreur prénom
</div>
<input type="text" th:field="*{prenom}" class="form-control" />
</div>
<div class="form-group">
<label th:for="*{nom}">Nom</label>
<div th:if="${#fields.hasErrors('nom')}" th:errors="*{nom}" class="text-danger">Erreur nom</div>
<input type="text" th:field="*{nom}" class="form-control" />
</div>
<div class="form-group">
<button class="btn btn-primary"><span class="glyphicon glyphicon-ok"></span>
<span th:remove="tag" th:text="#{label.add}"></span>
</button>
</div>
</form>
</th:block>
</body>
</html>

Unexpected validation errors in Spring

I have a strange error to my code. I am writing code for a eshop.
I have written code for validation when admin add products where the name field is empty. When I click the submit button the addProduct page reload with the message error that I defined.
With similar way I write code for validation when admin edit a product. I try to edit a product with an empty name that violates the NotEmpty that I have defined at the Product.java.
AddProduct at HomeController
#RequestMapping(value = "/admin/productInventory/addProduct", method = RequestMethod.POST)
public String addProductPost(#Valid #ModelAttribute("product") Product product, BindingResult result,
HttpServletRequest request) {
if (result.hasErrors()) {
return "addProduct";
}
addProduct.jsp
<div class="form-group">
<label for="name">Name</label>
<form:errors path="productName" cssStyle="color: #ff0000;" />
<form:input path="productName" id="name" class="form-Control" />
</div>
EditProduct at HomeController
#RequestMapping(value = "/admin/productInventory/editProduct", method = RequestMethod.POST)
public String editProduct(#Valid #ModelAttribute("product") Product product, Model model, BindingResult result,
HttpServletRequest request) {
if (result.hasErrors()) {
return "editProduct";
}
editProduct.jsp
<div class="form-group">
<label for="name">Name</label>
<form:errors path="productName" cssStyle="color: #ff0000;" />
<form:input path="productName" id="name" class="form-Control"
value="${product.productName}" />
</div>
product.java
#Column(name="productName")
#NotEmpty (message = "The product name must not be null.")
private String productName;
When I try to click the submit button on editProduct (with an empty name) I take:
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.
Apache Tomcat/9.0.0.M17
What's going wrong?
EDIT
editProduct.jsp
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%#include file="/WEB-INF/views/template/header.jsp"%>
<div class="container-wrapper">
<div class="container">
<div class="page-header">
<h1>Edit Product</h1>
<p class="lead">Please update the product information here:</p>
</div>
<form:form
action="${pageContext.request.contextPath}/admin/productInventory/editProduct"
method="post" commandName="product" enctype="multipart/form-data">
<form:hidden path="productId" value="${product.productId}" />
<div class="form-group">
<label for="name">Name</label>
<form:errors path="productName" cssStyle="color: #ff0000;" />
<form:input path="productName" id="name" class="form-Control"
value="${product.productName}" />
</div>
<div class="form-group">
<label for="category">Category</label> <label
class="checkbox-inline"><form:radiobutton
path="productCategory" id="category" value="instrument" />Instrument</label>
<label class="checkbox-inline"><form:radiobutton
path="productCategory" id="category" value="record" />Record</label> <label
class="checkbox-inline"><form:radiobutton
path="productCategory" id="category" value="accessory" />Accessory</label>
</div>
<div class="form-group">
<label for="description">Description</label>
<form:textarea path="productDescription" id="description"
class="form-Control" value="${product.productDescription}" />
</div>
<div class="form-group">
<label for="price">Price</label>
<%-- <form:errors path="productPrice" cssStyle="color: #ff0000;" /> --%>
<form:input path="productPrice" id="price" class="form-Control"
value="${product.productPrice}" />
</div>
<div class="form-group">
<label for="condition">Condition</label> <label
class="checkbox-inline"><form:radiobutton
path="productCondition" id="condition" value="new" />New</label> <label
class="checkbox-inline"><form:radiobutton
path="productCondition" id="condition" value="used" />Used</label>
</div>
<div class="form-group">
<label for="status">Status</label> <label class="checkbox-inline"><form:radiobutton
path="productStatus" id="status" value="active" />Active</label> <label
class="checkbox-inline"><form:radiobutton
path="productStatus" id="status" value="inactive" />Inactive</label>
</div>
<div class="form-group">
<label for="unitInStock">Unit In Stock</label>
<%-- <form:errors path="unitInStock" cssStyle="color: #ff0000;" /> --%>
<form:input path="unitInStock" id="unitInStock" class="form-Control"
value="${product.unitInStock}" />
</div>
<div class="form-group">
<label for="manufacturer">Manufacturer</label>
<form:input path="productManufacture" id="manufacturer"
class="form-Control" value="${product.productManufacture}" />
</div>
<div class="form-group">
<label class="control-label" for="productImage">Upload
Picture</label>
<form:input id="productImage" path="productImage" type="file"
class="form:input-large" />
</div>
<br>
<br>
<input type="submit" value="submit" class="btn btn-default">
<a href="<c:url value="/admin/productInventory" />"
class="btn btn-default">Cancel</a>
</form:form>
</div>
</div>
<%#include file="/WEB-INF/views/template/footer.jsp"%>
header.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>My Music Store</title>
<!-- Bootstrap core CSS -->
<link href="<c:url value="/resources/css/bootstrap.min.css" />"
rel="stylesheet">
<!-- Carousel core CSS -->
<link href="<c:url value="/resources/css/carousel.css" />"
rel="stylesheet">
<!-- My Main CSS style-->
<link href="<c:url value="/resources/css/main.css" />" rel="stylesheet">
</head>
<!-- NAVBAR
================================================== -->
<body>
<div class="navbar-wrapper">
<div class="container">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#navbar" aria-expanded="false"
aria-controls="navbar">
<span class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span> <span class="icon-bar"></span> <span
class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">My Music Store</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
<li>Products</li>
<li>Contact</li>
</ul>
<ul class="nav navbar-nav pull-right">
<li>Admin</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
EDIT AGAIN
Product
package com.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.Min;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.web.multipart.MultipartFile;
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="productId")
private String productId;
#Column(name="productName")
#NotEmpty (message = "The product name must not be null.")
private String productName;
#Column(name="productCategory")
private String productCategory;
#Column(name="productDescription")
private String productDescription;
#Min (value = 0, message = "The product price must no be less than zero.")
#Column(name="productPrice")
private double productPrice;
#Column(name="productCondition")
private String productCondition;
#Column(name="productStatus")
private String productStatus;
#Min (value = 0, message = "The product unit must no be less than zero.")
#Column(name="unitInStock")
private int unitInStock;
#Column(name="productManufacture")
private String productManufacture;
#Transient /*do not store to database*/
private MultipartFile productImage;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductCategory() {
return productCategory;
}
public void setProductCategory(String productCategory) {
this.productCategory = productCategory;
}
public String getProductDescription() {
return productDescription;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public double getProductPrice() {
return productPrice;
}
public void setProductPrice(double productPrice) {
this.productPrice = productPrice;
}
public String getProductCondition() {
return productCondition;
}
public void setProductCondition(String productCondition) {
this.productCondition = productCondition;
}
public String getProductStatus() {
return productStatus;
}
public void setProductStatus(String productStatus) {
this.productStatus = productStatus;
}
public int getUnitInStock() {
return unitInStock;
}
public void setUnitInStock(int unitInStock) {
this.unitInStock = unitInStock;
}
public String getProductManufacture() {
return productManufacture;
}
public void setProductManufacture(String productManufacture) {
this.productManufacture = productManufacture;
}
public MultipartFile getProductImage() {
return productImage;
}
public void setProductImage(MultipartFile productImage) {
this.productImage = productImage;
}
}

Categories

Resources