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

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 &amp;&amp;                      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 &amp;&amp; value <= max);      }      ...  }  ...  string f ieldvalue = request.getparameter("numberofchoic