0

I simply want to validate a form data and display an error message. Validating email format, password size and password matching. What would be the best way to do that?

Here's what I've tried

My controller

@PostMapping("/{customerId}/createUser")
public String signIn(@PathVariable(value = "customerId", required = false) Long customerId,
        @ModelAttribute(name = "user") @Valid Users user, RedirectAttributes redirectAttributes,
        BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "customerNewUser";
    }

    // Encrypt password
    user.setPassword(encoder.encode(user.getPassword()));
    user.setCustomerId(customerId);
    user.setEventDescription("User Admin creation");

    try {
        Users returnedUser = userService.save(user);

        List<Authorities> authorities = new ArrayList<Authorities>();
        Authorities auth = new Authorities(new AuthoritiesPK(returnedUser.getId(), "ROLE_CLI_ADM"), returnedUser,
                "ROLE_CLI_ADM");
        authorities.add(auth);
        returnedUser.setAuthorities(authorities);
        returnedUser.setEventDescription("Add Admin role");

        for (int i = 0; i < returnedUser.getAuthorities().size(); i++) {
            authorityService.save(returnedUser.getAuthorities().get(i));
        }
        userService.save(returnedUser);
    } catch (WebExchangeBindException webe) {
        StringBuilder errorBuilder = new StringBuilder();
        for (ObjectError error : webe.getAllErrors()) {
            errorBuilder.append(messageSource.getMessage(error.getCode(), null, Locale.getDefault())).append("\n");
        }
        redirectAttributes.addFlashAttribute("signInError", errorBuilder.toString());
    }

    return "redirect:/customers/?id=" + customerId;
}

My form in my customerNewUser html file

<form
                        th:action="@{${user?.id} ? '/customers/' + ${customer.id} + '/createUser/' + ${user.id} : '/customers/' + ${customer.id} + '/createUser/'}"
                        th:object="${user}" action="#" method="post">

<div class="alert alert-danger" th:if="${#fields.hasAnyErrors()}">
                            <div th:each="detailedError : ${#fields.detailedErrors()}">
                                <span th:text="${detailedError.message}"></span>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="form-row">
                                <div class="col-md-5">
                                    <label class="text-right label-control"
                                        th:text="#{firstname} + ':'">Firstname:</label>
                                </div>
                                <div class="col-md-4">
                                    <input type="text" id="firstname" name="firstname"
                                        th:value="${user?.firstname} ? ${user?.firstname} : ''"
                                        class="form-control" th:placeholder="#{firstname}"
                                        required="required" autofocus="autofocus" th:field="*{firstname}"/>
                                        <label th:style="'color: red;'" class="text-right label-control" th:if="${#fields.hasErrors('firstname')}" th:errors="*{firstname}" th:text="#{passwordError}">Password Error</label>
                                </div>
                            </div>
                            </div>
                            <div class="form-group">
                                <div class="form-row">
                                    <div class="col-md-5">
                                        <label class="text-right label-control"
                                            th:text="#{surname} + ':'">Surname:</label>
                                    </div>
                                    <div class="col-md-4">
                                        <input type="text" id="surname" name="surname"
                                            th:value="${user?.surname} ? ${user?.surname} : ''"
                                            class="form-control" th:placeholder="#{surname}"
                                            autofocus="autofocus" />
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="form-row">
                                    <div class="col-md-5">
                                        <label class="text-right label-control"
                                            th:text="#{email} + ':'">Email:</label>
                                    </div>
                                    <div class="col-md-4">
                                        <input th:placeholder="#{email}" required="required"
                                            autofocus="autofocus" id="email" class="form-control"
                                            type="text" th:value="${user?.email} ? ${user?.email} : ''"
                                            name="email" th:field="*{email}"/>
                                            <label th:style="'color: red;'" class="text-right label-control" th:if="${#fields.hasErrors('email')}" th:errors="*{email}" th:text="#{emailError}">Email Error</label>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group" th:if="!${user?.id}">
                                <div class="form-row">
                                    <div class="col-md-5">
                                        <label class="text-right label-control"
                                            th:text="#{password} + ':'">Password:</label>
                                    </div>
                                    <div class="col-md-4">
                                        <input type="password" id="password" name="password"
                                            class="form-control" th:placeholder="#{password}"
                                            required="required" autofocus="autofocus" th:field="*{password}"/>
                                            <label th:style="'color: red;'" class="text-right label-control" th:if="${#fields.hasErrors('password')}" th:errors="*{password}" th:text="#{passwordError}">Password Error</label>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group" th:if="!${user?.id}">
                                <div class="form-row">
                                    <div class="col-md-5">
                                        <label class="text-right label-control"
                                            th:text="#{passwordConfirmation} + ':'">Password confirmation:</label>
                                    </div>
                                    <div class="col-md-4">
                                        <input type="password" id="matchPassword" name="matchPassword"
                                            class="form-control" th:placeholder="#{password}"
                                            required="required" autofocus="autofocus" th:field="*{matchPassword}"/>
                                            <label th:style="'color: red;'" class="text-right label-control" th:if="${#fields.hasErrors('matchPassword')}" th:errors="*{matchPassword}" th:text="#{matchPassword}">Match Password Error</label>
                                    </div>
                                </div>
                            </div>

                            <div class="form-group" th:if="${user?.id}">
                                <div class="form-row">
                                    <div class="col-md-5">
                                        <label class="text-right label-control"
                                            th:text="#{userStatus} + ':'">Status:</label>
                                    </div>
                                    <div class="col-md-3">
                                        <select class="form-control form-control" id="userStatus"
                                            name="userStatus">
                                            <option
                                                th:each="userStatus : ${T(br.com.macrosul.stetho.entity.UserStatus).values()}"
                                                th:text="${userStatus}" th:value="${userStatus}"
                                                th:selected="${user.userStatus} eq ${userStatus}"></option>
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <p class="error-control" th:text="${signInError}"></p>
                            </div>
                            <input type="submit" class="btn btn-md btn-block"
                                value="Sign in"
                                th:value="${user?.id} ? #{updateUser} : #{signIn}" />
                    </form>

And here is the stacktrace when I try to force a password size error ->

 @Size(min=6)
@Column(nullable = false)
private String password;

Field error in object 'user' on field 'password': rejected value [12345]; codes [Size.user.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.password,password]; arguments []; default message [password],2147483647,6]; default message [tamanho deve estar entre 6 e 2147483647]

I want a simple validation. If there's a simpler way to indicate the user the data are invalid I would appreciate for any help or advice!

3 Answers 3

1

It is a little bit late, but you need to put your BindingResult next to your @valid attribute so instead of:

@ModelAttribute(name = "user") @Valid Users user, RedirectAttributes redirectAttributes, BindingResult bindingResult

you should write:

@ModelAttribute(name = "user") @Valid Users user, BindingResult bindingResult, RedirectAttributes redirectAttributes
Sign up to request clarification or add additional context in comments.

Comments

0

You need a validator like below. Its not the exact code what you need but sufficient enough and pretty close to what you need to get you going.

@Override
    public void validate(Object o, Errors errors) {
     ValidationUtils.rejectIfEmptyOrWhitespace(errors, "useremail", "NotEmpty");
     ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userfirstname", "NotEmpty");
     ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userlastname", "NotEmpty");
     ValidationUtils.rejectIfEmptyOrWhitespace(errors, "useraddress", "NotEmpty");

     ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty");
        if (user.getPassword().length() < 8 || user.getPassword().length() > 32) {
        errors.rejectValue("password", "Size.userForm.password");
        }

        if (!user.getPasswordConfirm().equals(user.getPassword())) {
        errors.rejectValue("passwordConfirm", "Diff.userForm.passwordConfirm");
        }
    }

For more details you can take a look at here, here and here.

Comments

0

You can put a div in the html that only exists if there are errors on the validation. Then you show each error in a loop:

<div th:if="${#fields.hasErrors('*')}">
  <p th:each="err : ${#fields.errors('*')}"> 
      <span th:text="${err}"></span>
  </p>
</div>

This way, when you return to this view there will be errors on your fields so this code will be shown.

1 Comment

Yes, I have it. For some reason it was cut off, already edited it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.