`
wolf_awp
  • 浏览: 55174 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多
为了保证函数运行的正确性,在函数的开始一般要对参数的正确性进行判断,如果函数间相互进行调用的时候,可能会出现多次对同一个参数的正确性进行验证,出现代码冗余。
比如在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层的方法之前,先对要传入的值进行验证,正确了才能调用相应的方法。

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

大家平常怎么写的,相互参考下。
分享到:
评论
24 楼 xieyanhua 2011-05-21  
<div class="quote_title">skzr.org 写道</div>
<div class="quote_div">
<p>楼主这个困惑不是你一个人困惑阿,呵呵<br>估计每个开发的都困惑过:严格的规范说每一个地方都要验证,但是实际上很多地方的验证都是重复的“冗余”。<br><br>每个代码的上下文都是不一样的,所以没有最好的,只有适合自己的实践。<br><br>在我的系统中,最佳实践:</p>
<ul>
<li>每一需要验证的方法,都把<span style="font-size: small; color: #ff0000;"><strong>前置条件写入到方法注释中</strong></span>——必须的</li>
<li>
<span style="font-size: small; color: #ff0000;"><strong>dao不做任何验证</strong></span>,认为输入的参数都是验证过了的</li>
<li>service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)</li>
<li>
<strong><span style="font-size: small; color: #ff0000;">action必须做验证</span></strong>,并提供友好的反馈给调用界面</li>
</ul>
<p>现在在构建一个平台,感觉和做小项目不一样:service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)</p>
<p>这里service基本都是需要对外的,也就是这一条变成了所有的service都要做验证。</p>
<p>最终:除开dao不做验证外其他的都要做验证,因为dao是系统内部使用,外部系统无法访问。</p>
<p> </p>
</div>
<p>和我的观点一样,我也都是这么做,比如一个比如以前的jsp+acton+service+dao的系统,因为就一个独立的系统,没有提供对外的接口(也不涉及远程调用),所以service和dao都不做校验,只做业务逻辑的校验,这两层都是我们系统内部调用,仅供action调用,所以我们的校验都放在jsp和action;</p>
<p> </p>
<p>还有别的系统中,部分service的接口会提供出来,供其他系统调用,或者webservice等,出了我们系统调用外,还有别的系统在调用,所以这个时候,这个webservice接口就要做校验了;加入涉及远程RMI调用的,我们也会做校验;因为rmi调用不同于本地调用,本地调用不存在参数丢失或修改的问题,而远程调用,有可能网络丢包或受到干扰造成数据发生了变化,这些都有可能,所以这些我们也会校验,比如以前用ejb时,在ejb中的所有方法,都会做检验。</p>
23 楼 xieyanhua 2011-05-21  
nianien 写道


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



楼主只是说什么时候需要对参数进行校验,不只是空或非空校验,也有包括一些逻辑校验,比如扣款是金额是否足够。仅仅是举例。
22 楼 xieyanhua 2011-05-21  
wolf_awp 写道
我认为参数的正确性检测,应该由调用方进行,如果不正确,就不能调用相应的函数。一个函数可以假定参数是正确的进行处理。这样即可以保证参数的正确性又没有代码冗余。



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

21 楼 fflame 2011-05-20  
同意private的不验证,public的验证……
20 楼 nianien 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文档,里面会表明你是不是进行参数校验
如果为空时是直接返回还是抛异常

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

而参数的校验则由客户端进行校验
19 楼 skzr.org 2011-05-20  
<p>楼主这个困惑不是你一个人困惑阿,呵呵<br>估计每个开发的都困惑过:严格的规范说每一个地方都要验证,但是实际上很多地方的验证都是重复的“冗余”。<br><br>每个代码的上下文都是不一样的,所以没有最好的,只有适合自己的实践。<br><br>在我的系统中,最佳实践:</p>
<ul>
<li>每一需要验证的方法,都把<span style="color: #ff0000; font-size: small;"><strong>前置条件写入到方法注释中</strong></span>——必须的</li>
<li>
<span style="color: #ff0000; font-size: small;"><strong>dao不做任何验证</strong></span>,认为输入的参数都是验证过了的</li>
<li>service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)</li>
<li>
<strong><span style="color: #ff0000; font-size: small;">action必须做验证</span></strong>,并提供友好的反馈给调用界面</li>
</ul>
<p>现在在构建一个平台,感觉和做小项目不一样:service层如果是外部接口,那么做验证,反之认为都是合法的(一般调用者就是Action,或者其他service)</p>
<p>这里service基本都是需要对外的,也就是这一条变成了所有的service都要做验证。</p>
<p>最终:除开dao不做验证外其他的都要做验证,因为dao是系统内部使用,外部系统无法访问。</p>
<p> </p>
18 楼 kulinglei 2011-05-20  
建议每次调用都校验,你一个人调用还可以,但多个人调用时,鬼知道你写校验了吗?如果写了,校验的完整吗?说代码冗余,你可以把相同的抽象出来单独放啊。我一般都做校验
17 楼 kjj 2011-05-20  
一个原则吧,你在不能保证调用你的外围都会验证之前,还是自己验吧,不然npe会像幽灵一样纷至沓来........................
16 楼 codeincoffee 2011-05-20  
1. 尽量用apache的StringUtils.isBlank()。

2. 好的程序员即便过单行道都会左右环顾的,这种“冗余”比起安全性来说算不上什么,所以我认为都需要验证。
15 楼 ppgunjack 2011-05-20  
进公司刷卡,但一般内部就不刷卡了
但你如果进内部机房可能还需要刷卡
没定势的
关键是如果参数错了会导致异常,最好有参数内容打印
离输入端越近越需要校验
14 楼 liu.anxin 2011-05-20  
又到架构跟规范的口水里面来了
13 楼 liu.anxin 2011-05-20  
与其他业务逻辑有关联的, 去 service 校验, 其他的在 去 service 之前校验. 习惯多用 公共类 就行了
12 楼 TheMarine 2011-05-20  
这里你们的前提都是都是所有代码都是你们自己开发。如果是分组开发的,写action的时候能保证写service那位写了验证?写service的能保证写action帮你写好了验证?结果是大家都要写。当然不沟通的情况是没有的,但是我想说的是方法需要对自己负责,而不是把这种风险让别人帮你规避。因为对自己负责是百分百健壮,另外的就不一定。所有的方法加上参数验证就是对自己负责。case1,调用方没有验证,在被调用方验证了,ok,被调用方代码的自我保护工作了。case2,被调用方没有验证,调用方验证,那么调用方的自我保护工作了。除非一个验证都没写。考虑到2者得自我保护,代码冗余问题显得不那么重要。套用代码大全里的说法,开车的人不但不能撞人,主要还不能被撞啊。
11 楼 15210494746 2011-05-20  
woaiwofengkuang 写道
个人认为,在action中一般只验证用户输入的正确性。而在service中应该验证这个参数是否满足业务需要。
比如说一个日期,在action中只要验证这个传进来的参数是否日期类型。而在service中要验证这个日期是否是未来5天内的一个日期值。
当然了只举例。

觉得说的挺清楚了,如果是输入的信息的合法性验证。建议你放在BaseAction中(当然也可以不叫baseAction),放在控制层的自定义父类中做有很多好处,很多时候在具体的子类中不用重复的验证了。当然仅限于数据的合法性。

而在service层得验证,则是你业务需求的验证。为了是防止你业务逻辑出现错误~

所以我觉得对参数的验证,要看是什么类型的验证。
10 楼 wolf_awp 2011-05-20  
woaiwofengkuang 写道
个人认为,在action中一般只验证用户输入的正确性。而在service中应该验证这个参数是否满足业务需要。
比如说一个日期,在action中只要验证这个传进来的参数是否日期类型。而在service中要验证这个日期是否是未来5天内的一个日期值。
当然了只举例。

我认为这样也是合理的,虽然多次验证,但验证是内容是不一样的,也没有代码冗余。
9 楼 wolf_awp 2011-05-20  
kjj 写道
这怎么能说重复呢,除了dosomthing调用foo之外,说不定其他代码也调用呢

其他代码调前,也是要先进行参数验证的。
8 楼 szcs10138456 2011-05-20  
楼主你说的是正确的做法
7 楼 TheMarine 2011-05-20  
这种问题通常是防御式编程,写service的能保证写action的帮你验证?再说都叫service了,未必只有action才调用,可能有其他客户端呢。
6 楼 kjj 2011-05-20  
这怎么能说重复呢,除了dosomthing调用foo之外,说不定其他代码也调用呢
5 楼 woaiwofengkuang 2011-05-20  
个人认为,在action中一般只验证用户输入的正确性。而在service中应该验证这个参数是否满足业务需要。
比如说一个日期,在action中只要验证这个传进来的参数是否日期类型。而在service中要验证这个日期是否是未来5天内的一个日期值。
当然了只举例。

相关推荐

    TP3.2的简单数据验证php类

    我们在Model中处理数据的时候会一次传入很多参数,这时候可能需要对参数进行判断,是不是少参数了,参数的格式是否正确,如果每次都一大堆if判断的话会很麻烦,以前用过CI,它里面有对form表单提交的数据进行验证的...

    TP3.2的简单数据验证php类.zip

    我们在Model中处理数据的时候会一次传入很多参数,这时候可能需要对参数进行判断,是不是少参数了,参数的格式是否正确,如果每次都一大堆if判断的话会很麻烦,以前用过CI,它里面有对form表单提交的数据进行验证的...

    jquery数据验证 配置简单 使用简单

    如验证input或textbox中输入的时候email只需: 在input或textbox中加入属性ValidDataForEmail='default'即刻实现email的验证操作 还有 网址、数字、身份证、日期等验证,都只需要如上一样添加属性即可,详细的请看...

    寄生参数提取及后仿

    使用Spectre对提取的寄生参数进行后仿验证** - **步骤**: - 将提取的寄生参数导入Spectre。 - 进行电路仿真,比较前仿和后仿的结果。 - **关键指标**: - **延迟时间**:衡量信号传递速度的关键指标。 - **...

    父窗口与子窗口的参数传递验证.zip

    在.NET框架中,尤其是使用VB.NET进行开发时,经常需要在父窗口和子窗口之间进行数据传递。这个“父窗口与子窗口的参数传递验证”的示例提供了如何有效解决这个问题的一种方法,它主要依赖于事件和委托。接下来,我们...

    finereport报表工具参数控件取值与置数

    本文将深入解析如何利用FineReport中的参数控件进行取值与置数,以及这一过程在实际报表设计中的应用。 ### 参数控件取值与置数的概念 在报表设计中,参数控件主要用于收集用户输入或选择的数据,这些数据可以用于...

    小红书旋转验证码自动识别验证

    2. **标注**:在获得验证码图像后,我们需要手动或使用自动化工具对每个图像进行标注,即识别并标记出图像中的每一个字符。这一步通常采用如LabelImg等工具,将每个字符的位置和对应的文本信息记录下来,生成用于...

    Android字段验证的实例代码

    它通常涉及到对用户在应用程序中填写的文本字段进行检查,以确保输入符合预设的规则,例如非空、邮箱格式、电话号码格式等。本实例代码将向我们展示如何在Android应用中实现一个简单的字段验证功能。 首先,我们...

    【ASP.NET编程知识】ASP.NET MVC的四种验证编程方式.docx

    我们可以通过一个简单的实例来演示如何将参数验证逻辑实现在对应的 Action 方法中,并在没有通过验证的情况下将错误信息响应给客户端。 例如,我们定义了一个 Person 类作为被验证的数据类型,它的 Name、Gender 和...

    ireport报表参数传到子表步骤

    在iReport设计报表时,有时候我们需要将主报表的数据传递给子报表,以便子报表能够根据这些参数进行定制化的数据查询和展示。这个过程涉及到的主要知识点是报表参数的传递,也就是所谓的"传参"。以下是对这个过程的...

    编写可传递参数的COM组件

    应限制组件接收的参数类型和范围,对输入进行验证,避免代码注入攻击。 8. **测试与部署**:编写完成后,需要在不同的环境中测试COM组件,确保在不同版本的Windows和浏览器中都能正常工作。部署时,用户需要安装...

    ExtJS+Servlet表单验证和注册

    在服务器启动时,Servlet会被加载并初始化,处理完请求后,服务器会在适当的时候销毁Servlet实例。 2. **请求和响应** Servlet通过HttpServletRequest对象获取客户端的请求信息,如参数、头信息等;通过...

    23G切换与重选参数详细说明.doc

    如果是整个RNC 参数修改,一定要进行跟踪测试,如果只是单个小区之间的参数修改,要对单小区验证。该参数是同时起作用与同频、异频、异系统的小区重选,因此,该值的设置应该整体考虑,一般情况下不建议设置为0,...

    ASP.NET MVC的四种验证编程方式

    在定义具体Action方法的时候,对已经成功绑定的参数实施手工验证无疑是一种最为直接的编程方式,接下来我们通过一个简单的实例来演示如何将参数验证逻辑实现在对应的Action方法中,并在没有通过验证的情况下将错误...

    Ajax异步验证注册用户名是否存在

    为了安全起见,需要对用户输入进行适当的清理和验证,防止SQL注入等安全问题。如果查询结果显示用户名已存在,`checkname.php`会返回一个特定的标识或消息,例如"用户名已存在";反之,如果用户名可用,就返回...

    rails_param:Rails的参数验证和类型强制

    rails_param Rails的参数验证和类型强制介绍如果您想直接在控制器内部验证一些参数,该库非常方便。 例如:您正在构建搜索动作,并且想要验证是否已设置sort参数,并且仅将其设置为desc或asc类的东西。重要的该库不...

    多项分布参数估计的EM/MCEM算法及模拟

    在本文中,作者李柏椿和钟波对EM/MCEM算法在一般性多项分布参数估计问题中的应用进行了研究。多项分布是统计学中的一个基本概念,是二项分布的推广,用于描述在n次独立实验中,某事件发生的次数k的概率分布。在实际...

    如何提取DOS命令行中的参数程序(VB6.0源代码编写)

    然而,有时候我们可能需要对参数进行更复杂的处理,比如验证参数数量、检查参数格式或处理带特殊字符的参数。这时,我们可以自定义函数来解析这些参数: ```vb Function GetParameter(index As Integer, Optional ...

Global site tag (gtag.js) - Google Analytics