字符串验证器的可能改进



我制作了这个Java方法,用于验证字符串插入表单字段:

public void validateDatacenterName(FacesContext context, UIComponent component, 
                         Object value) throws ValidatorException, SQLException {
  String l;
  String s = value.toString().trim();
  if (s.length() > 18) {
    throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "  Value is too long! (18 digits max)", null));  
  }
  try {
    // l = Long.parseLong(s);
    // if (l > Integer.MAX_VALUE)
    // {
    //   throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
    //                    "  '" + l + "' is too large!", null));  
    // }
  } catch(NumberFormatException nfe) { 
    l = null; 
  }
  if (s != null) {
    if (ds == null) 
      throw new SQLException("Can't get data source");
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs;
    int cnt = 0;
    try {
      conn = ds.getConnection();
      ps = conn.prepareStatement("SELECT count(1) from COMPONENTSTATS where COMPONENTSTATSID = ?");
      ps.setString(1, s);
      rs = ps.executeQuery();
      while(rs.next()) 
        cnt = rs.getInt(1);
      if (cnt > 0) {
        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "  '" + s + "' is already in use!", null));                    
      }
    } catch(SQLException x) {
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "  SQL error!", null));                
    } finally {
      if (ps != null) 
        ps.close();
      if (conn != null) 
        conn.close();
    }                      
  } else {
    throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        s.isEmpty() ? "  This field cannot be empty!" : "  '" + s + "' is not a valid name!", null));         
  }
}

如何改进此代码?为了改进表单验证器,我是否可以添加其他检查?

如有任何帮助,我们将不胜感激!

  • StackOverflow的读者从您的描述中不知道什么是有效的数据中心名称,因为我们不知道您的应用程序。唯一的要求是它是数字吗?

  • 如果该值应该是数字,为什么要注释掉调用parseLong()的代码?

  • 检查COMPONENTSTATS中已使用的值会创建竞争条件。也就是说,即使在检查之后,其他应用程序线程也可以在您插入相同的值之前插入它。为什么不使用UNIQUE约束在数据库中强制执行唯一性呢?

  • 当您知道s == null时,如何在您的else块中调用s.isEmpty()

  • 如果该方法是实现javax.faces.validator.validator的类的一部分,那么该方法不应该命名为validate()吗?

只有当确实需要时,才应该使用正则表达式。根据您正在使用的当前验证,标准的String方法就足够了。

您应该尽可能地将该方法用于与验证相关的任务。为此,您应该将数据库调用提取到一个单独的方法中。

此外,您还有一个NullPointerException在这里等待发生:

throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        s.isEmpty() ? "  This field cannot be empty!" : "  '" + s + "' is not a valid name!", null));         

此时,s将是nullNullPointerException将在您可以抛出ValidatorException之前抛出。

我将使用regexp进行验证。

不幸的是,我不知道给出确切的字符串,但我相信每天使用它的人会在3秒钟内不使用它:(我知道这将是最好的方法。

要么我会在web上搜索已经实现的验证,要么我会列出一个字符列表,我想允许字符串使用这些字符,然后检查输入,例如用正则表达式检查输入不包含任何其他字符。

if (s.length() > 18)检查之前,我认为您应该检查s是否为空

if (s !=null && s.length() > 18)

并且最好对字符串s.isEmpty() 进行空检查

一些建议:

  1. 使用Regex通过定义一组允许的字符和/或符号来验证Stirng的结构
  2. 将空检查逻辑移到if(s.length() > 18)之前。如果snull,则该子句将产生NullPointerException
  3. 修复您的null检查:if (s != null)将允许s = "",因为它不是null,从而破坏了您尝试验证空字符串的else语句(这将在创建验证消息时导致NullPointerException(。如果您想在两种情况下执行不同的逻辑,请使用if(s != null && !s.isEmpty())或将验证一分为二

相关内容

  • 没有找到相关文章

最新更新