论坛首页 Java企业应用论坛

在什么时候对参数进行验证

浏览 14129 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-20  
wolf_awp 写道
为了保证函数运行的正确性,在函数的开始一般要对参数的正确性进行判断,如果函数间相互进行调用的时候,可能会出现多次对同一个参数的正确性进行验证,出现代码冗余。
比如在Action的一个函数里面调用一个Service的方法,参数验证位置有三种情况:
  • 1、在Service的函数里面
  • 2、在Action里调用Service的方法前
  • 3、在两个函数里面都对参数进行验证(肯定会有代码冗余)

如果一个函数要求参数不能为空或是空字符串,在函数的里面应该就是这样的:
public void doSomething(String foo) {
	if (null == foo || "".equals(foo.trim())) {
		return;
	}
	// some code
}

在另一个函数里面调用到了上面的方法:
public void doAnything(String foo) {
	if (null == foo || "".equals(foo.trim())) {
		return;
	}		
	doSomething(foo);
    // some code
}

这样的话验证参数的代码就重复了。

个人认为,在Service层里面可以不进行参数的验证,假定参数都是正确的。而是在调用Service层的方法之前,先对要传入的值进行验证,正确了才能调用相应的方法。

问题核心就是,是要在一个函数里面进行参数验证,还是在调用函数前对参数进行验证。

大家平常怎么写的,相互参考下。

这个问题我也考虑过很久
一般来说,私有方法肯定不需要参数合法性校验的
而对于公开方法,那看你的服务声明了
一般写方法,都会提供相应的API文档,里面会表明你是不是进行参数校验
如果为空时是直接返回还是抛异常

一般来说,如果你是写服务,供其它客户端调用,那么你完全就可以不必进行参数校验
你所需要完成的是在参数正确的情况下保证逻辑的正确性
况且你也不知道客户端是打算如何处理错误的参数
也许它是返回一个默认值,或者抛出异常,你不能也不必替客户端做决定

而参数的校验则由客户端进行校验
0 请登录后投票
   发表时间:2011-05-20  
同意private的不验证,public的验证……
0 请登录后投票
   发表时间:2011-05-21  
wolf_awp 写道
我认为参数的正确性检测,应该由调用方进行,如果不正确,就不能调用相应的函数。一个函数可以假定参数是正确的进行处理。这样即可以保证参数的正确性又没有代码冗余。



请问你如何保证客户端传递给你的一定是正确的,只有一个程序负责调用,你可以要求,如果很多地方都调用你的service,你怎能保证所有客户端都按你的要求提供了正确的数据呢?

1 请登录后投票
   发表时间:2011-05-21   最后修改:2011-05-21
nianien 写道


一般来说,如果你是写服务,供其它客户端调用,那么你完全就可以不必进行参数校验
你所需要完成的是在参数正确的情况下保证逻辑的正确性
错误的参数的时候不需要保证程序的正确性?
况且你也不知道客户端是打算如何处理错误的参数
也许它是返回一个默认值,或者抛出异常,你不能也不必替客户端做决定
客户端怎么处理错误的参数,那是客户端的事情,但是返回什么数据则是服务器端得事情,这也没有提客户端做决定。
而参数的校验则由客户端进行校验
我是倾向于服务器端做校验,因为你不能保证每个客户端的程序都是很细心的,按你的要求去做,还有一个就是,你不校验,有的东西,可能会对系统照成危害,或者数据不正确等。校验不校验,关键要看提供给客户的服务的重要性,参数对系统的影响,比如让一个没有写权限的客户端调用了,却能实现。



楼主只是说什么时候需要对参数进行校验,不只是空或非空校验,也有包括一些逻辑校验,比如扣款是金额是否足够。仅仅是举例。
0 请登录后投票
   发表时间:2011-05-21   最后修改:2011-05-21
skzr.org 写道

楼主这个困惑不是你一个人困惑阿,呵呵
估计每个开发的都困惑过:严格的规范说每一个地方都要验证,但是实际上很多地方的验证都是重复的“冗余”。

每个代码的上下文都是不一样的,所以没有最好的,只有适合自己的实践。

在我的系统中,最佳实践:

  • 每一需要验证的方法,都把前置条件写入到方法注释中——必须的
  • dao不做任何验证,认为输入的参数都是验证过了的
  • service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)
  • action必须做验证,并提供友好的反馈给调用界面

现在在构建一个平台,感觉和做小项目不一样:service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)

这里service基本都是需要对外的,也就是这一条变成了所有的service都要做验证。

最终:除开dao不做验证外其他的都要做验证,因为dao是系统内部使用,外部系统无法访问。

 

和我的观点一样,我也都是这么做,比如一个比如以前的jsp+acton+service+dao的系统,因为就一个独立的系统,没有提供对外的接口(也不涉及远程调用),所以service和dao都不做校验,只做业务逻辑的校验,这两层都是我们系统内部调用,仅供action调用,所以我们的校验都放在jsp和action;

 

还有别的系统中,部分service的接口会提供出来,供其他系统调用,或者webservice等,出了我们系统调用外,还有别的系统在调用,所以这个时候,这个webservice接口就要做校验了;加入涉及远程RMI调用的,我们也会做校验;因为rmi调用不同于本地调用,本地调用不存在参数丢失或修改的问题,而远程调用,有可能网络丢包或受到干扰造成数据发生了变化,这些都有可能,所以这些我们也会校验,比如以前用ejb时,在ejb中的所有方法,都会做检验。

1 请登录后投票
   发表时间:2011-05-21  
记得谁说过,所有的输入都是“罪恶”的,本着这个原则,每一个方法都应该验证,因为你并不知道它将被谁调用。
0 请登录后投票
   发表时间:2011-05-21  
TheMarine 写道
这种问题通常是防御式编程,写service的能保证写action的帮你验证?再说都叫service了,未必只有action才调用,可能有其他客户端呢。



就是呀  service又不是只能被controller调用!
0 请登录后投票
   发表时间:2011-05-21  
不管那层调用你的都是你的客户;对客户的输入应该是开放的,返回给客户的数据要严格
0 请登录后投票
   发表时间:2011-05-21  
只要是不是private 的都应该验证,因为你公开了可能过段时间已经很多客户用户了
0 请登录后投票
   发表时间:2011-05-21  
tom&jerry 写道
记得谁说过,所有的输入都是“罪恶”的,本着这个原则,每一个方法都应该验证,因为你并不知道它将被谁调用。


if(xxx == null){
  throw new NullPointerException();
}


我觉得这种东西写不写差别不大。。。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics