日期:2014-05-19  浏览次数:20710 次

J2EE数据验证的一些开发建议
说在前面:非原创。

输入数据验证:虽然为了用户的方便,可以提供“客户端”层数据的数据验证,但必须使用Servlet 在服务器层执行验证。 客户端验证本身就不安全,因为这些验证可轻易绕过,例如,通过禁用 Javascript。一份好的设计通常需要 Web 应用程序框架,以提供服务器端实用程序例程,从而验证以下内容:
  • [1] 必需字段;
  • [2] 字段数据类型(缺省情况下,所有 HTTP 请求参数都是“字符串”);
  • [3] 字段长度;
  • [4] 字段范围;
  • [5] 字段选项;
  • [6] 字段模式;
  • [7] cookie 值;
  • [8] HTTP 响应。

好的做法是将以上例程作为“验证器”实用程序类中的静态方法实现。以下部分描述验证器类的一个示例。
[1] 必需字段
  // Java example to validate required fields
  public Class Validator {
      ...
      public static boolean validateRequired(String value) {
          boolean isFieldValid = false;
          if (value != null && value.trim().length() > 0) {
              isFieldValid = true;
          }
          return isFieldValid;
      }
      ...
  }
  ...
  String fieldValue = request.getParameter("fieldName");
  if (Validator.validateRequired(f ieldValue)) {
      // fieldValue is valid, continue processing request
      ...
  }

[2] 输入的 Web 应用程序中的字段数据类型和输入参数欠佳。例如,所有 HTTP 请求参数或cookie值的类型都是“字符串”。开发者负责验证输入的数据类型是否正确。 使用Java基本包装程序类,来检查是否可将字段值安全地转换为所需的基本数据类型。
验证数字字段(int 类型)的方式的示例:
  // Java example to validate that a f ield is an int number
  public Class Validator {
      ...
      public static boolean validateInt(String value) {
          boolean isFieldValid = false;
          try {
              Integer.parseInt(value);
              isFieldValid = true;
          } catch (Exception e) {
              isFieldValid = false;
          }
          return isFieldValid;
      }
      ...
  }
  ...
  // check if the HTTP request parameter is of type int
  String f ieldValue = request.getParameter("f ieldName");
  if (Validator.validateInt(f ieldValue)) {
      // f ieldValue is valid, continue processing request
      ...
  }

好的做法是将所有HTTP请求参数转换为其各自的数据类型。例如,开发者应将请求参数的“integerValue”存储在请求属性中,并按以下示例所示来使用:
  // Example to convert the HTTP request parameter to a primitive wrapper data type
  // and store this value in a request attribute for further processing
  String f ieldValue = request.getParameter("f ieldName");
  if (Validator.validateInt(f ieldValue)) {
      // convert f ieldValue to an Integer
      Integer integerValue = Integer.getInteger(f ieldValue);
    // store integerValue in a request attribute
      request.setAttribute("f ieldName", integerValue);
  }
  ...
  / / Use the request attribute for further processing
  Integer integerValue = (Integer)request.getAttribute("f ieldName");
  ...

应用程序应处理的主要 Java 数据类型:
  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double
  • Date

[3] 字段长度“始终”确保输入参数(HTTP请求参数或cookie值)有最小长度和/或最大长度的限制。
以下示例验证 userName 字段的长度是否在 8 至 20 个字符之间:
  // Example to validate the f ield length
  public Class Validator {
      ...
      public static boolean validateLength(String value, int minLength, int maxLength) {
          String validatedValue = value;
          if (!validateRequired(value)) {
              validatedValue = "";
          }
          return (validatedValue.length() >= minLength &&
                      validatedValue.length() <= maxLength);
      }
      ...
  }
  ...
  String userName = request.getParameter("userName");
  if (Validator.validateRequired(userName)) {
      if (Validator.validateLength(userName, 8, 20)) {
          / / userName is valid, continue further processing
          ...
      }
  }

[4] 字段范围
始终确保输入参数是在由功能需求定义的范围内。
以下示例验证输入 numberOfChoices 是否在 10 至 20 之间:
  / / Example to validate the f ield range
  public Class Validator {
      ...
      public static boolean validateRange(int value, int min, int max) {
          return (value >= min && value <= max);
      }
      ...
  }
  ...
  String f ieldValue =