2013-05-11 55 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; 
     }