字符串验证器可能有哪些改进?

时间:2012-12-27 15:32:32

标签: java sql jsf validation

我已经制作了这个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));         
  }

}

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

任何帮助都将受到高度赞赏!

6 个答案:

答案 0 :(得分:3)

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

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

  • 检查COMPONENTSTATS中是否有正在使用的值会创建race condition。也就是说,即使在检查之后,其他一些应用程序线程也可以在插入之前插入相同的值。为什么不使用UNIQUE约束强制数据库中的唯一性?

  • 当您知道s.isEmpty()时,如何在else区块中致电s == null

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

答案 1 :(得分:2)

如果确实需要,则应该只使用正则表达式。使用您当前使用的验证,标准String方法就足够了。

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

此外,您还有NullPointerException等待发生:

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

此时snullNullPointerException将被抛出,然后您可以抛出ValidatorException

答案 2 :(得分:1)

我会用regexp验证。

不幸的是,我没有足够的知识来提供确切的字符串,但我确信谁在每天使用它将在3秒内没有它:)我知道这将是最好的方式。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:1)

一些建议:

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