Meine Eingabemaske für mein Spring Boot / Thymeleaf - Projekt sieht momentan so aus
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link th:href="@{/css/style.css}" rel="stylesheet" media="screen"/>
<style th:remove="all">
body {
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div th:fragment="content">
<h2 th:text="#{${subtitle}}">Create or edit a Project</h2>
<form class="form-horizontal" action="#" th:action="@{/project/save}" th:object="${project}" method="post">
<div th:if="${#fields.hasErrors('*')}" class="allert alert-danger">
<p th:text='#{project.hasErrors}'>Error Message</p>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="name" th:text="#{project.mask.name} + ' :' ">Name :</label>
<div class="col-sm-10">
<input type="text" th:field="*{name}" class="form-control" id="name" th:placeholder="#{project.mask.name.placeholder}">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="key" th:text="#{project.mask.key} + ' :' ">Key :</label>
<div class="col-sm-10">
<input type="text" th:field="*{key}" class="form-control" id="key" th:placeholder="#{project.mask.key.placeholder}">
<span th:if="${#fields.hasErrors('key')}" th:errors="*{key}" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="description" th:text="#{project.mask.description} + ' :' ">Description :</label>
<div class="col-sm-10">
<textarea class="form-control" rows="5" id="description" th:field="*{description}" th:placeholder="#{project.mask.description.placeholder}"></textarea>
<span th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-md-6 mt-5">
<input type="submit" class="btn btn-primary" value="Add Project">
</div>
</div>
</form>
</div>
</body>
</html>
hierzu habe ich auch einen Controller mit einer Ansichts- und Speicherfunktion.
@GetMapping("/project")
ModelAndView create(Project project) {
ModelAndView modelAndView = this.getMaskView("project");
modelAndView.addObject("subtitle", "project.subtitle.create");
return modelAndView;
}
....
@PostMapping("/project/save")
public ModelAndView save(@Valid Project project, BindingResult result) {
if (result.hasErrors()) {
return new ModelAndView("redirect:/project");
}
projectRepository.save(project);
return new ModelAndView("redirect:/projects");
}
Das Project Object sieht so aus:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
/**
* this is a entity for project
*
* @author tomth
*/
@Entity
public class Project {
@Id
@GeneratedValue
private Long id;
/**
* create at
*
* @var Long
*/
@CreationTimestamp
private Date created_at;
/**
* updated at
*
* @var Long
*/
@UpdateTimestamp
private Date updated_at;
/**
* selected Project
*
* @var TINYINT(1) not null default(0)
*/
@Column(nullable = false)
private Boolean selected = false;
/**
* title of the project
*
* @var String 255
*/
@NotBlank(message = "Name is mandatory")
@Size(min=5, max=60)
private String name;
/**
* key of the project
*
* @var String 10
*/
@NotBlank(message = "Title is mandatory")
@Size(min=3, max=10)
private String key;
/**
* description of the project
*
* @var TEXT
*/
@Lob
private String description;
/**
* default constructor
*/
public Project() {
}
/**
* intialize constructor
*
* @param String name name of the project
* @param String key the key of the project
*/
public Project(String name, String key) {
this.name = name;
this.key = key;
}
/**
* id of the entity
*
* @return
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* create date of the project
*
* @return
*/
public Date getCreatedAt() {
return this.created_at;
}
public void setCreatedAt(Date createdAt) {
this.created_at = createdAt;
}
/**
* last update date of the project
*
* @return
*/
public Date getUpdatedAt() {
return this.updated_at;
}
public void setUpdatedAt(Date updatedAt) {
this.updated_at = updatedAt;
}
/**
* project name
*
* @return
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* key number of the project
*
* @return
*/
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
/**
* description of the project
*
* @return
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Project [id=" + id + ", createdAt=" + created_at + ", updatedAt=" + updated_at + ", name=" + name
+ ", key=" + key + ", description=" + description + "]";
}
}
Das eigentlich Speichern funktioniert wunderbar. Problem tritt nur dann auf, wenn ich eine fehlerhafte Eingabe absetze.
<div th:if="${#fields.hasErrors('*')}" class="allert alert-danger">
<p th:text='#{project.hasErrors}'>Error Message</p>
</div>
fields.hasErrors scheint nicht zu greifen. Meine Vermutung ist, weil ich einen redirect setze vergisst er die Fehlermeldungen.
Wie kann ich es hinbekommen, dass ich die Fehlermeldung übergeben bekomme, trotz redirect?