2013-05-11 57 views
2

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

这是我的用户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> 

任何想法?

+0

什么是您的具体问题或问题? (“任何想法?”不是一个问题,除非你接受“是”作为有效答案。) – Ralph 2013-05-11 12:59:01

+0

我的确切问题是我上面说过的 - 我想要做的是当我插入主键的重复条目我的表,验证程序告诉我一个消息,例如这个登录已被take_再次阅读。 – Somar 2013-05-11 13:08:56

+0

我已经得到了这个,但是什么阻止你实现它? – Ralph 2013-05-11 13:50:06

回答

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> 
3

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

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

+0

+1 - 2.针对验证器)如果允许更新用户名,验证器将无法在 之间做出决定 - 更改名称和因此新名称必须未使用的情况或者 - 在这种情况下,用户名不变,因此旧名称必须在数据库中出现一次。 – Ralph 2013-05-11 13:49:16

+0

并向登录列添加数据库唯一约束。 (以及在存储之前先考虑首先规范化登录(小写)) – Ralph 2013-05-11 13:54:33

1

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

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"); 
} 
... 

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

0

在你的控制器通过从模型库中查询只检查重复。

@Model实体

@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; 
     }