如何处理异常,而在春天MVC应用程序添加重复的用户名到数据库(How to handle excep

2019-09-29 04:00发布

我建立的Spring MVC应用程序。 我想dissalow添加重复(用户名是主键)条目和视图通知选择另一个用户名。

我工作的注册用户选项。 一切正常,直到我把用户与已经存在的用户名。 好了,这是故意的,因为用户名列是我的数据库中的主键。

我要寻找一个选项,所以处​​理这个问题:

这是我的SQL表

 create table users(
  username varchar(50) not null primary key,
  password varchar(50) not null);

这是我的仓库:

@Repository

class UserRepositoryImpl implements UserRepository{

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public void addUser(User user) throws MySQLIntegrityConstraintViolationException {
        /*language=SQL*/
        String SQL_ADD_USER= "INSERT INTO users VALUES (?,?)";

        String username  = user.getUsername();
        String password  = user.getPassword();
        jdbcTemplate.update(SQL_ADD_USER, username, password);

    }
}

这是我的控制器类的一部分:

@RequestMapping(value="/register", method = RequestMethod.GET)
public String registerPage(@ModelAttribute("user") User user){return "register";}

@RequestMapping(value="/register", method=RequestMethod.POST)
public String processRegisterUser(@ModelAttribute("user") User user, BindingResult result){

    try {
        userRepository.addUser(user);
    } catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) {

        //some line of code that would add information to the view that user with given username already exists.
    }


    return "redirect:/login";
}

正如你可以看到我试着处理,添加重复的条目时发生异常。 这就是为什么我把这一条款throws MySQLIntegrityConstraintViolationException在公共无效ADDUSER(用户用户)。 在接下来的步骤,我想处理此异常public String processRegisterUser方法,这样我可以在认为给定用户名已被占用通知用户。 好了,这是行不通的。 我不能处理com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException和视图添加重复的错误,而不是警告时,我得到:

 HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO users VALUES (?,?)]; Duplicate entry 'user' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user' for key 'PRIMARY'

type Exception report

message Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO users VALUES (?,?)]; Duplicate entry 'user' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user' for key 'PRIMARY'

description The server encountered an internal error that prevented it from fulfilling this request.

exception

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO users VALUES (?,?)]; Duplicate entry 'user' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user' for key 'PRIMARY'
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
        org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)

如果您需要任何详细信息,请发表评论。

Answer 1:

您只处理MySQLIntegrityConstraintViolationException没有其他异常:NestedServletException和DuplicateKeyException,所以你得到的堆栈跟踪和你的try / catch是行不通的。

顺便说一句,为什么不能简单地创建一个额外的方法来检查用户名是否已经存在,如果是,则显示错误消息,否则添加用户。

class UserRepositoryImpl implements UserRepository{
    //.....
    public int isUsernameExist(String username){
        String sql = "SELECT COUNT(*) FROM users WHERE username=?";
        return jdbcTemplate.queryForObject(sql, new Object[] { username }, String.class);
    }
    //....
}

@RequestMapping(value="/register", method=RequestMethod.POST)
public String processRegisterUser(@ModelAttribute("user") User user, BindingResult result){
    int status = userRepository.isUserExist(user.getUsername());
    if(status==1){
        //Username exist... redirect and display error msg.
    } else {
        userRepository.addUser(user);
    }
    //.....
}


Answer 2:

你使用Spring的JdbcTemplate的数据库连接,它有自己的异常层次结构,所以你可以尝试赶上春例外org.springframework.dao.DuplicateKeyException



Answer 3:

尝试Query.uniqueResult()因为这在描述下的文章或其他

public Account getAccountByAccountIdAndType(Long accountId, AccountType accountType) {

    Account account = null;
    try {
        Query query = getSession().getNamedQuery("getAccountByAccountId");
        query.setLong("accountId", accountId); 
        query.setString("accountType", AccountType.SAVING.toString());
        Account account = (Account)Query.uniqueResult();
    } catch(NonUniqueResultException) {
        throw new RuntimeException("Two account found with same account number and type : Acc No-" + accountId);
    }
    if (account == null) {
         throw new RuntimeException("Unable to find Account for account number :" + accountId);
    }
    return account;
}

实体类

@NamedQuery(
name = "getAccountByAccountId",
query = "from Account where username = :username")
@Entity
@Table(name = "account")
public class Account {


文章来源: How to handle exception while adding duplicate username to a database in spring mvc application