<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>jacklondon</title>
    <description></description>
    <link>http://jacklondon.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Web 应用中用户录入数据错误检查在分层设计中的定位</title>
        <author>jacklondon</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jacklondon.javaeye.com">jacklondon</a>&nbsp;
          链接：<a href="http://jacklondon.javaeye.com/blog/189560" style="color:red;">http://jacklondon.javaeye.com/blog/189560</a>&nbsp;
          发表时间: 2008年05月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>转自我的 blog,欢迎大家讨论:&nbsp; <br /><a href="http://blog.csdn.net/jacklondon">http://blog.csdn.net/jacklondon</a> <br />..... <br />按照通常的 Web 分层开发设计模式(MVC)，Web 应用应该分 Web, Service, DAO 三层。 </p>
<p>以常见的 Struts 来讲，Web 层包含 Struts Action, JSP, HTML, Javascript, CSS. service 是单独一层，隔离 DAO 实现。 DAO 则是纯粹的数据库访问(增加、修改、删除、查询)。 </p>
<p>以笔者项目中所遇到的情况，包括笔者更改别人的项目代码，发现一个普遍的情况是，&ldquo;用户录入数据错误检查&rdquo;，被放在了 action 层。这很值得商榷。 </p>
<p>&ldquo;用户录入数据错误检查&rdquo;，通常包含以下方面： </p>
<p>1. 非空检查，比如新建用户时，用户名不能为空。 </p>
<p>2. 字符串长度检查，比如用户名最大长度检查，与数据库设计字段长度保持一致。 </p>
<p>3. 日期格式、日期有效性检查。比如不能报销半年以前的出租车费。 </p>
<p>4. 逻辑检查。比如一个用户不能报销同一天的出租车费超过 10000 元。 </p>
<p>5. 状态检查。比如&ldquo;订单已经创建，不能重复创建同一个订单&rdquo;。 </p>
<p>前三者，很多人都放在 Web 层，也就是 Struts Action 层中。 </p>
<p>然而，仔细想想，以上错误检查，都应该是业务层的东西，这些检查，都应该与用户确认需求，都是非技术的需求。 </p>
<p>对于&ldquo;字符串长度检查&rdquo;，曾经看到某个系统中，有这样的代码： </p>
<p>if (userNm.getBytes("UTF8").length &gt; 20) { </p>
<p>... </p>
<p>} </p>
<p>其中的 UTF8 是数据库的编码。这样的代码很成问题。 </p>
<p>每种字段的字符串长度限制，是纯粹的用户业务需求，不是数据库设计需求。用户需求只可能是： </p>
<p>&ldquo;用户名中汉字和字母加起来最多20 个字符&rdquo;， </p>
<p>&ldquo;用户名中汉字算两个，字母算一个，加起来最多20 个字符&rdquo;。 </p>
<p>用户需求中，不会提到数据库编码是 UTF8 还是 GBK。我们之所以在代码中，检查用户名长度，是因为有明确的用户需求，如果没有用户要求，我们在数据库设计上，可以随便放多长，2000 或者 4000，技术上，都不是问题。 </p>
<p>对于用户名的长度检查， </p>
<p>1.新增用户时会用到， </p>
<p>2.修改用户时也会用到(如果你的系统，有&ldquo;不能修改用户名&rdquo;这样低级的错误，则需要请一个技术高手好好把这个代码全部审阅一番)。 </p>
<p>3. 通常系统中会有另一个功能，通过文件导入 Excel 数据文件，来批量增加新用户，这个地方，也要进行用户名的长度检查。 </p>
<p>如果把用户名的长度检查，放在 Web 层，代码的重用性实在是有点为难。要保证以上三个情况，如果用户名长度限制，由 20 统一变成 100, 是否可能漏改其中一个，也很难说。 </p>
<p>相反，把用户名的长度检查，放在 service 层，写成一个公共的函数，比如 UserSrv.validateUserNameLen(String userName), 则方便很多。 </p>
<p>把这种长度检查放在 Web 层 Struts Action 中完全没有道理。至于放在 client 中，用 Javascript 检查用户录入的用户名长度，那更是胡扯。 </p>
<p>我们应该明白一点：如果用户需求中，有要求进行用户名长度检查，则这时一个用户需求，是一个业务逻辑，应该放到 service 层中。如果用户没有要求进行用户名长度检查，则代码中进行用户名长度检查纯粹是多余。 </p>
<p>同样的道理，上面提到的其他类型的用户录入数据检查，也都应该放在 service 层中，而不是 web 层中。</p>
          <br/>
          <span style="color:red;">
            <a href="http://jacklondon.javaeye.com/blog/189560#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 May 2008 00:06:08 +0800</pubDate>
        <link>http://jacklondon.javaeye.com/blog/189560</link>
        <guid>http://jacklondon.javaeye.com/blog/189560</guid>
      </item>
      <item>
        <title>VelocityWeb 1.0 发布了</title>
        <author>jacklondon</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jacklondon.javaeye.com">jacklondon</a>&nbsp;
          链接：<a href="http://jacklondon.javaeye.com/blog/107293" style="color:red;">http://jacklondon.javaeye.com/blog/107293</a>&nbsp;
          发表时间: 2007年07月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          VelocityWeb 1.0 在 sourceforge 上发布了&nbsp; (http://velocityweb.sourceforge.net/ )。<br />
目前这个开源框架只有我一个人在维护。<br />
<br />
新版本主要集中精力在 J2EE 单元测试上，可以不用启动 J2EE 服务器，就进行 J2EE 单元测试，并且直接看到运行后的动态网页。有此类功能的开源框架非常少。<br />
<br />
这个 1.0 版本真是难产。0.9 版本发布在 2006-11-15， 0.95 版本发布在 2006-11-20。过了一个年，就差点忘了。<br />
原 本想做成一个大一统的框架，包括定时任务触发、应用配置管理、权限管理等等，后来觉得没有必要，这些东西每个人有每个人的设计爱好，强制一种，反而让人感 到厌烦。后来就去掉了。权限管理保留了基于 URL &lt;--&gt; 用户的模式，预留了一个用户自定义的接口。
          <br/>
          <span style="color:red;">
            <a href="http://jacklondon.javaeye.com/blog/107293#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 31 Jul 2007 10:06:51 +0800</pubDate>
        <link>http://jacklondon.javaeye.com/blog/107293</link>
        <guid>http://jacklondon.javaeye.com/blog/107293</guid>
      </item>
  </channel>
</rss>