-1

我已经制作了这个用于验证字符串插入表单字段的 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));         
  }

}

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

任何帮助将不胜感激!

4

6 回答 6

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

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

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

  • s.isEmpty()当你知道的时候,你怎么能在你的else街区打电话s == null

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

于 2012-12-27T15:53:27.030 回答
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));         

此时s将被抛出,null然后NullPointerException才能抛出你的ValidatorException.

于 2012-12-27T15:50:21.290 回答
1

一些建议:

  1. 用于通过定义一组允许的字符和/或符号Regex来验证's 结构Stirng
  2. 将您的空检查逻辑移到if(s.length() > 18). If sisnull该子句将导致NullPointerException.
  3. 修复您的空检查:if (s != null)将允许s = "",因为它不为空,打破您尝试验证空字符串的 else 语句(这将在NullPointerException您创建验证消息时导致)。if(s != null && !s.isEmpty())如果您想在两种情况下执行不同的逻辑,请使用或将该验证一分为二。
于 2012-12-27T15:48:47.520 回答
1

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

于 2012-12-27T15:41:06.560 回答
1

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

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

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

于 2012-12-27T15:47:07.470 回答
1

我会用正则表达式验证。

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

于 2012-12-27T15:35:07.867 回答