Spring Validator用于数据库中的重复记录

时间:2013-05-11 11:27:21

标签: spring validation

在我的页面jsp中,我有一个表单,我可以将用户添加到我的数据库,并且我使用验证器在字段为空时显示错误,但我想要做的是,当我插入重复的条目我的表的主键,验证器向我显示一条消息,例如已经采用此登录而不是Apache的错误!

这是我的用户POJO:

package gestion.delegation.domaine;

import java.io.Serializable;

public class User implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    int id;
    String nom;
    String prenom;
    String login;
    String password;
    String role;
    boolean enable;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getNom() {
        return nom;
    }
    public void setNom(String nom) {
        this.nom = nom;
    }
    public String getPrenom() {
        return prenom;
    }
    public void setPrenom(String prenom) {
        this.prenom = prenom;
    }
    public String getLogin() {
        return login;
    }
    public void setLogin(String login) {
        this.login = login;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public boolean getEnable() {
        return this.enable;
    }
    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public User(int id, String nom, String prenom, String login,
            String password, String role, boolean enable) {
        super();
        this.id = id;
        this.nom = nom;
        this.prenom = prenom;
        this.login = login;
        this.password = password;
        this.role = role;
        this.enable = enable;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public User() {
        super();
    }

}

这是我的验证器:

package gestion.delegation.validator;

import gestion.delegation.domaine.User;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class AddUserValidator implements Validator{

    @Override
    public boolean supports(Class<?> clazz) {

        return User.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object obj, Errors err) {
        ValidationUtils.rejectIfEmptyOrWhitespace(err, "nom", "name.required","Choisissez un nom");
        ValidationUtils.rejectIfEmptyOrWhitespace(err, "prenom", "prenom.required", "Choisissez un prenom");
        ValidationUtils.rejectIfEmptyOrWhitespace(err, "login", "login.required", "Choisissez un login");
        ValidationUtils.rejectIfEmptyOrWhitespace(err, "password", "password.required", "Choisissez un password");
        ValidationUtils.rejectIfEmpty(err, "role", "role.required", "Choisissez un role");

    }

}

形式:

<c:if test="${not empty msg_success}">
                    <div class="success">Vous avez ajouter un utilisateur avec
                        succès !</div>
</c:if>
                <form:form name="ajf"
                    action="${pageContext.request.contextPath}/ajouter_user"
                    method="post" commandName="user">

                    <table id="tabmenu">


                        <tr>
                            <td id="idtab">Nom :</td>
                            <td><form:input type="text" path="nom"
                                    class="round default-width-input" name="name_" /></td>
                            <td><form:errors path="nom" Class="errorbox" /></td>
                        </tr>
                        <tr>
                            <td id="idtab">Prénom :</td>
                            <td><form:input type="text" path="prenom" name="prenom_"
                                    class="round default-width-input" /></td>
                            <td><form:errors path="prenom" cssClass="errorbox" />
                        </tr>
                        <tr>
                            <td id="idtab">Login :</td>
                            <td><form:input type="text" path="login" name="login_"
                                    cssClass="round default-width-input" /></td>
                            <td><form:errors path="login" cssClass="errorbox" /></td>
                        </tr>

                        <tr>
                            <td id="idtab">Password :</td>
                            <td><form:input type="password" path="password" name="pass_"
                                    class="round default-width-input" /></td>
                            <td><form:errors path="password" cssClass="errorbox" /></td>

                        </tr>

                        <tr>
                            <td id="idtab">Séléctionner un rôle :</td>
                            <td><form:select path="role">
                                    <form:option value="" label="" />
                                    <form:option value="ROLE_ADMIN">Administrateur</form:option>
                                    <form:option value="ROLE_USER">Simple utilisateur</form:option>
                                </form:select></td>
                            <td><form:errors path="role" cssClass="errorbox" /></td>
                        </tr>
                        <tr>
                            <td id="idtab">Activé :</td>
                            <td><form:input type="checkbox" value="true" path="enable" />
                                Oui</td>
                        </tr>
                        <tr></tr>
                        <tr></tr>
                        <tr>
                            <td><input
                                class="button round blue image-right ic-right-arrow"
                                type="submit" value="Créer" /></td>
                            <td><input
                                class="button round blue image-right ic-right-arrow"
                                type="reset" value="Initialiser" /></td>
                        </tr>

                    </table>
                </form:form>

任何想法?

5 个答案:

答案 0 :(得分:3)

在这种情况下,我担心验证器是不够的。虽然您可以扩展AddUserValidator类以检查给定的用户名是否是免费的,但它不会 在两个用户同时尝试使用相同的用户名注册的情况下工作 - 验证将通过,但是其中一个用户将从数据库中收到错误。

为了保护自己免受这种情况的影响,我会将注册逻辑放在try catch块中,并在出现错误时向用户显示正确的消息。这将是一种application-level validation

答案 1 :(得分:1)

Spring验证器只需在将对象引入数据库之前按照规定的规则检查对象。它对数据库一无所知。要显示使用数据库时发生的错误,您需要手动捕获异常。

答案 2 :(得分:1)

在您的控制器中只需通过查询模型库来检查重复。

@Model Entity

@Table(name = "people")
public class People {
        @Column(name = "nic")
        @NotEmpty(message = "*Please provide your nic")
        private String nic;

@Repository

    public interface PeopleRepository extends JpaRepository<People, Integer>{
        People findByNic(String nic);

    }

@Controller

 @RequestMapping(value = "/welcome", method = RequestMethod.POST)
        public ModelAndView createNewPeople(Model model,, BindingResult bindingResult) {
            ModelAndView modelAndView = new ModelAndView();
            People peopleExistsEmail = peopleService.findUserByNic(people.getNic());
            if (peopleExistsEmail != null) {
                bindingResult
                        .rejectValue("nic", "error.people",
                                "There is already a person registered with the nic provided");
            }
            if (bindingResult.hasErrors()) {
                modelAndView.setViewName("welcome");
            } else {
                peopleService.savePeople(people);
                modelAndView.addObject("successMessage", "People has been registered successfully");
                modelAndView.addObject("people", new People());

                } catch (Exception e) {
                    e.printStackTrace();
                }   
            }
            return modelAndView;
        }

答案 3 :(得分:0)

所以这是正确答案:

DAO类实现中的方法如下:

public boolean AddUser(User user) {
        boolean t=true;
        final String User_INSERT1 = "insert into utilisateurs (login, password, nom, prenom,enable) "
                + "values (?,?,?,?,?)";
        final String User_INSERT2="insert into roles (login,role) values(?,?)";
        /*
         * On récupère et on utilisera directement le jdbcTemplate
         */
        MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("SHA");
        String hash = encoder.encodePassword(user.getPassword(), "");

        final String check ="select count(*) from utilisateurs where login = ?";

       int result= getJdbcTemplate().queryForInt(check, new Object[]{String.valueOf(user.getLogin())});
        if (result==0) { 
            getJdbcTemplate()
            .update(User_INSERT1,
                    new Object[] {user.getLogin(),
                            hash, user.getNom(),
                            user.getPrenom(), user.getEnable(),
                             });
    getJdbcTemplate().update(User_INSERT2, new Object[]{user.getLogin(),user.getRole()});
       return t;
        }   

        else { t = false ; return t;}

        }

控制器:

@RequestMapping(value ="/ajouter_user", method = RequestMethod.POST)
    public String add(@ModelAttribute User us,BindingResult result,ModelMap model) {
        AddUserValidator uservalid=new AddUserValidator();

        uservalid.validate(us, result);
        if (result.hasErrors()) {
            model.addAttribute("usersystem", userservice.getAllUsers());
            return "gestionUser";
        }else {
            boolean e = userservice.AddUser(us);
            if (e==false){
                model.addAttribute("msg_failed","true");
            }
            else {
            model.addAttribute("msg_success","true");}
            model.addAttribute("usersystem", userservice.getAllUsers()); /*verifier*/
            return "gestionUser";

        }


    }

并显示jsp文件中的错误:

<c:if test="${not empty msg_failed}">
                    <div class="errorblock">Il existe déjà un utilisateur avec cet login </div>
</c:if> 

答案 4 :(得分:0)

DAO类实现中的方法是这样的:

    public final long insert(final User user) throws MyException {
        String sql = "INSERT INTO users ....";
    String chkSql = "SELECT count(*) FROM users WHERE username=:username";
    Map namedParams = new HashMap();
    namedParams.put("username", user.getUsername());
    long newId = namedTemplate.queryForInt(chkSql, namedParams);
    if (newId > 0) {
        try {
            throw new MyException(-1);
        } catch (MyException e) {
              throw e;
        }
    }
    newId = ...;// could be generated if not inc field or triggered...
    namedParams.put("username", user.getUserName());
    ...
    ...
    namedParams.put("id", newId);
    namedTemplate.update(sql, namedParams);
    return newId;
}

像这样的MyException:

public class MyException extends Exception{
private static final long serialVersionUID = 1L;
   int a;
   public MyException(int b) {
     a=b;
   }
}

控制器:

@RequestMapping(value = "/user", method = RequestMethod.POST)
    public final ModelAndView actionUser(
        final ModelMap model,
        @ModelAttribute("myitemuser") @Valid final User user,
        final BindingResult bindResult,
        ...);
        ...
        try {
             userService.addUser(user); // or dao... ;)
             } catch (Exception e) {
                 UserValidator userValidator = new UserValidator();
               userValidator.custError(bindResult);
        }
像这样的UserValidator:

...
@Override
public final void validate(final Object object, final Errors errors) {
    User user = (User) object;
    ...
    if (user.getPassword().isEmpty()) {
        errors.rejectValue("password", "error.users.emptypass");
    }
}

public final void custError(final Errors errors){
    errors.rejectValue("username"/* or login */, "error.users.uniqname");
}
...

Нукактотак))))