Reputation: 2772
I have simple entity ...
@Entity
public class WatchedDirectory {
@Column(nullable=false)
@NotBlank(message="Filesystem path CANNOT be empty")
String filesystemPath;
}
... and GET endpoint for creating one ...
@GetMapping("/add")
public String add(@ModelAttribute WatchedDirectory watchedDirectory) {
return "mng-dir-add";
}
... that shows form made in Thymeleaf, with error validation and all. Once you hit sumbmit button data goes into POST endpoint ...
@PostMapping("/add")
public String addExecute(@Valid @ModelAttribute WatchedDirectory watchedDirectory, BindingResult result, RedirectAttributes redirect, Model model) {
if(result.hasErrors()) {
// here I want to iterate through
// errors and clean erroneous fields
return "mng-dir-add";
}
watchedDirectory = fs.persistDirectory(watchedDirectory);
redirect.addFlashAttribute("added", watchedDirectory);
return "redirect:/list";
}
... and everything is nice and dandy. When data is valid it get persisted and redirect to list is issued (POST/Redirect/GET). When data is invalid thymeleaf's error fields are populated and I list error messages below appropriate fields.
The only thing I want to change, but I can't figure out how to, is to clear some data from model.
Things I tried so far: modifying @ModelAttribute
parameter, setting attributes in Model
, setting attributes in RedirectAttributes
. Every time I get the very same data user provided without any changes in output form, for some reason I can't change a thing. I tried also redirecting to GET method but it seems it clears slate clean, which I don't want.
If someone is interested this is how form in thymeleaf looks:
<form id="content" action="#" th:action="@{/add}" th:object="${watchedDirectory}" method="post" class="was-validated">
<div class="form-group has-feedback has-error">
<label for="filesystemPath">Filesystem path:</label>
<input th:field="*{filesystemPath}" type="text" id="filesystemPath" name="filesystemPath" class="form-control" placeholder="~/" required />
<label th:if="${#fields.hasErrors('filesystemPath')}" th:errors="*{filesystemPath}"></label>
</div>
<button type="submit" class="btn btn-outline-success">Save</button>
</form>
required
attribute on input field will shut up when provided with whitespace but there will be error message from Spring's validation. Clearing this field and returning it to user will make things more consistent than showing mixed signals such as:
Any help would be really appreciated.
Upvotes: 1
Views: 454
Reputation: 1731
You need to define a BeanPropertyBindingResult
object that provides the fields having the errors. Then make a model with this results,
@PostMapping( "/add" )
public String addExecute( @Valid @ModelAttribute WatchedDirectory watchedDirectory, BindingResult result, RedirectAttributes redirect, Model model )
{
if( result.hasErrors() )
{
BeanPropertyBindingResult result2 = new BeanPropertyBindingResult( watchedDirectory, theBindingResult.getObjectName() );
for( ObjectError error : theBindingResult.getGlobalErrors() )
{
result2.addError( error );
}
for( FieldError error : theBindingResult.getFieldErrors() )
{
result2.addError( new FieldError( error.getObjectName(), error.getField(), null, error.isBindingFailure(), error.getCodes(), error.getArguments(), error.getDefaultMessage() ) );
}
model.addAllAttributes( result2.getModel() );
return "mng-dir-add";
}
watchedDirectory = fs.persistDirectory( watchedDirectory );
redirect.addFlashAttribute( "added", watchedDirectory );
return "redirect:/list";
}
Upvotes: 1
Reputation: 2665
According to Validation by Using Spring’s Validator Interface from the Spring Framework Documentation:
The
Validator
interface works by using anErrors
object so that, while validating, validators can report validation failures to theErrors
object.
validate(Object, org.springframework.validation.Errors)
: Validates the given object and, in case of validation errors, registers those with the givenErrors
object.
And the Errors
interface doesn't provide any API for deregistering binding errors.
So, it seems there is no Spring
provided way to achieve what you want.
Upvotes: 0