NETCTOSS代码实现第二版

前言

资费增加功能需求分析与程序设计

  • 那现在呢,我们把查询功能做了,然后呢,我们也了解了这些,相关的一些内容。那说完以后啊,咱们对这个web项目开发,应该有点体会了,体会的是什么呢,我们开发web项目,一定不能乱来,一定是得有套路对吧,得有一个顺序啊,那我想讲的是,这个开发的套路到底是什么,还是回到一开始的这个这个,说的这个思路,还是那句话,一定先搞清楚需求,其次要有设计,你设计明确了,逐个开发,容易解决问题,所以你课后做练习的时候啊,也是啊,也是要把这个设计呢,多想一想,那一开始,你不会,正是因为不会,你才要练,你才要画啊,自己拿个笔,拿个纸,动个手,画一画,看一看。那这个功能呢,说完以后,下面呢,我们要说一下另外一个功能。
    在这里插入图片描述
  • 那第2个功能是什么呢,看一下,我们在查询的基础上,下面要做的是增加的功能,是吧,做这个。
    在这里插入图片描述

根据需求拆分请求

  • 然后呢,这个增加的功能,那我先给大家介绍一下,这个开发的思路,那我现在呢,要开发这个增加功能,我们从何入手,先怎么办,还是先搞清楚需求对吧,就是这个玩应怎么操作,对吧,怎么用,得整明白,不过这个好像也没什么,增加么,一点增加,打开增加页面对吧,填数据呗,填数据点保存,就存呗对吧,存完以后去哪啊,还回到查询对吧,就可以了,是这意思吧,跟以前我们所说的那个增加员工是差不多的( Servlet3:增加员工功能案例 ),是类似的,那大概就这个流程。
  • 那了解了这个业务啊,这个业务简单,了解以后,然后呢,再想下一步怎么办,了解业务以后,你得做设计对吧,做设计怎么做呢,我的建议是,我们要把这个功能,拆分成若干请求,因为web项目,任何功能都是由请求构成的,对吧,一个请求一个请求处理的,一个请求就是一个单元,拆分请求,那你看,那你觉得这个增加有几个请求,几个,两个,第一个是怎么着,点增加时,点开增加页面,是一个请求么,是的;然后呢,保存,存数据是一个,对吧,两个,其实还有一个,你保存完之后,不要跳转到查询么,那还涉及到查询,那查询也是一个请求吧,只不过呢,查询已经完成了,对吧,但不管怎么样啊,整个流程是3个请求对吧,不过最后一个已经有了。
  • 那这样啊,咱们做增加的时候啊,我们当前阶段的主要的内容是在哪呢,是在Servlet和jsp这块,是在服务端,不是在前端,我们增加时,按理来说是要验证,去验证资费名是不是满足这个格式(50长度的字母、数字、汉字和下划线的组合),它的基本时长是满不满足这个格式(1-600之间的整数),是这样吧,你得写正则表达式,那这得写js了,这个js啊,我就不演示了,如果你有兴趣,自己写一写,那怎么写呢,之前的js阶段时,也介绍过正则表达式对吧,演示了一个登录功能,可以做一个参考,和那个差不多,可以参考那个。当然,没有精力的话,这个先不写,那么我们后面,后面阶段做的云笔记项目,那个时候会写大量的js,现在的话,这个阶段不在于,重点不在于js,明白吧,所以这个我就不写了。

根据请求推导程序内部执行过程

  • 那3个请求啊,每个请求,是怎么运行的,3个请求之间是什么关系,我们还得这个画一下。那web项目啊,有浏览器,其次呢,有服务器,那个数据库,我就不画了,反正浏览器访问服务器,数据库我就不画了,就这样了啊。那你看,首先呢,我们增加的起点,是我们在查询页面上,点增加按钮对吧,我点增加,然后呢,点增加的时候呢,就访问服务器了,那访问服务器,打开增加页面,静态的还是动态的,静态的,为什么呢,因为打开以后什么都没有,每个人看都一样对吧,永远都一样,静态的,是这样的,以前模拟增加员工时也是这么说的,但其实呢,并不是这样。这个,当然没做过项目不理解,这也很正常,为什么我说这个增加网页是动态的,不是静态的呢,因为它有上面菜单栏这一排图标:
    在这里插入图片描述
  • 这一排图标是这个软件的功能,那一个软件不同的用户进来,看到的功能,应该有所差别,不同的用户进来,这个图标应该有区别,这个叫权限管理,权限控制,比如说啊,同样的tts这个软件,你进去可以考试,我进去可以阅卷,是这意思吧,不同的身份进去是不一样的,同样的这个淘宝,咱们进去可以买东西,店家进去可以上传宝贝,是这样吧,有差别,对吧,同样一个论坛,我们进去能看帖子,能发个帖子,然后呢,管理员进去能够,能够这个删帖,能够这个加精华,置顶啥的,对吧,是这样的。那几乎任何软件都有权限管理,要控制用户呢,这个访问,不能说任何功能都让他访问,所以我们这个软件也是一样啊,不同的用户进来,看见的图标呢,不一样。
  • 不过呢,因为时间有限,咱们这段课呢,不是以讲项目为主,所以这个权限管理啊,没法讲。因为要想讲权限管理的话,必须讲角色管理这个模块,讲管理员模块,这两模块讲完以后再去讲,这至少得有,得讲个大概5天的时间才能搞定,时间不允许,所以我不细说了,总之呢,这个项目做完整,这应该是动态的明白吧,图标是动态初始化的,所以呢,我也把它做成动态的,行么,就这样,所以呢,我们访问的是服务器端的谁呢,Servlet,那我们这个项目中,只有一个Servlet对吧,因为项目小啊,MainServlet,然后呢,增加,打开增加页面,我这个方法叫什么呢,叫toAddCost(),行吧,就叫这个名字啊,toAddCost,即MainServlet.toAddCost(),就去增加,去增加资费这个意思。
  • 然后啊,那这个路径是什么,也做个规定啊,我规定这个访问路径就是toAddCost.do,是有规律的对吧,其实说白了,这个方法叫什么,路径就是什么,/toAddCost.do,这是我的一个习惯啊,规律啊,叫这个名字啊。那访问它以后,它这个打开增加页面,它这个有什么业务逻辑需要处理么,有没有业务逻辑呢,没有,就打开了页面对吧,没有业务,当然做完整要有,因为你要初始化那个图标对吧,做完整要有,但是现在没有,所以呢,这里我就不调dao了,不需要访问数据库了,直接转发对吧,是吧,有人说,哎,你这,就什么业务都没有,有必要还转发么,直接写个jsp,访问jsp行不行呢,不要这样啊,就是说,我们即便是没有业务,也要遵守MVC的规则,明白吧,就将来,我们会讲什么呢,我们怎么去统一管理,咱们项目中的这个请求,做一些公共的业务,那前提是呢,它们的结构一样,明白吧,套路一样才可以,所以,一旦说你改变了套路,将来代码不好管理。将来再讲啊,反正也是MVC啊。
  • 然后呢,这个页面呢,我把它放到WEB-INF之下,然后呢,放到cost下面,叫add.jsp/WEB-INF/cost/add.jsp,这样的,然后呢,由jsp向浏览器做出了响应,最终呢,浏览器就得到了增加页面,这是增加功能的第一个请求,这样。然后呢,当浏览器得到这个网页之后,它一加载可以看到一个表单对吧,是得到一个表单,表单中有很多框,我就不细画了,然后呢,最终,表单上有一个保存按钮是吧,然后呢,当用户呢,点保存按钮时,是不是向服务器,又发请求,要求存数据是吧,这是我们这个功能的第2个请求,这样,前后的关系就是这样。然后呢,再往后看,那服务器要处理请求,因为有数据了,肯定是动态的对吧,所以还是要访问Servlet,那我还是访问同样的这个MainServlet,然后呢,是保存数据,增加数据,我这个方法叫addCost,行吧,MainServlet.addCost(),刚才是要增加,现在是,就是真增加啊,是这样的。然后呢,它的路径跟这个方法相似,要求呢,是叫/addCost.do,行吧,跟这个方法同名,对应。
  • 然后呢,那你要增加数据的话,我们得接收表单的数据对吧,接收数据,然后呢,要保存数据,保存数据怎么保存,得怎么办呢,还得调dao对吧,还得调这个CostDao,调CostDao什么方法呢,save保存方法对吧,CostDao.save(),就可以。那你要调保存方法的话,是不是要把数据传给它呢,传给CostDao.save(),传入的数据是什么数据呢,Emp,有点走火入魔了,是吧,学Emp学大了是吧,这里切换场景啊,这里是资费啊,是Cost,是吧,是Cost。那你把数据呢,封装好,传进去,然后呢,就存了,只要不报错就是成功对吧,好了,保存完以后然后怎么办, 最后怎么办啊,重定向到查询对吧,那么,在此之前,我们查询早做好了对吧,那查询是什么呢,早做好了,是MainServlet里面的findCost,当然,findCost调了Dao,MainServlet.findCost(),它调了谁呢,调了这个CostDao.findAll()方法对吧,这都已经写好了,然后呢,它已经能调这个Dao,由Dao呢,返回了集合数据。那你只要访问它就行了,访问MainServlet.findCost(),那我们要访问它的话,因为这个增加和查询是两个不同的请求,不同的功能对吧,相互独立,所以重定向就可以了,那这是这个功能当中的第3个请求,3个请求呢,互相就这样串接起来了。
    在这里插入图片描述
  • 那么,最后这个请求呢,因为它的内容啊,是我们不用再写了,已经写过了,所以我把它换个颜色啊,换个灰色,换一个不显眼的颜色,表示说,不用重点关注它,那我们需要重点关注的是前两个请求, 是这样吧,那当你能够把一个项目中的这个请求,分析到这种地步的时候,那么,你每一步就好写了,从MainServlet.toAddCost()/WEB-INF/cost/add.jsp,这不就是转发一下么,对吧;服务器返回/WEB-INF/cost/add.jsp给浏览器,这不就是一个jsp显示个东西,对吧;保存按钮被点击触发时,浏览器发送/addCost.do请求到MainServlet.addCost(),这不就是接收点参数么,MainServlet.addCost()把Cost数据发送给CostDao.save(),不就是把参数给dao,保存一下么,然后,MainServlet.addCost()再建议浏览器发起第3个请求查询资费,不就是重定向么,每一步的逻辑都非常的简单了,都比较小了,就比较容易实现了。
  • 当然你在实现的过程中呢,肯定还会遇到一些障碍,因为我们开发代码的话,是比较精细的,会遇到一些细节问题,遇到问题的时候啊,怎么说呢,自己想一想,憋一憋,哪怕这个事,我憋了半个小时,憋了一个小时没憋出来,你也要忍着,因为什么呢,这是你日后工作的一种常态,我当年啊,老板出差了,走了,剩我个人一个在那写代码,没有人帮我解决,遇到问题怎么办,就憋一天也得憋着,憋着呗,反正也憋不死。只能忍,没有招啊,然后,你工作时你会发现,那同事很多人很奇怪,很有意思啊,每个人解决问题的方式不一样。
  • 以前我有同事,那哥们这个,遇到问题实在是憋的受不了了,他也不好意思问别人,比较这个,比较腼腆,然后怎么办呢,坐在那工位上,在那运气啊,就是实在是不知道该怎么解决,老是以为这是不是电脑有问题啊,tomcat有问题啊,一启tomcat时,运气啊,气功呀,嘿,运气,给我吓坏了,我说你要干嘛,你要拉翔吧,不是,我都解决两个小时解决不了了,然后,我们抢着帮他解决,为啥呢,两个小时没解决,我们解决,能解决了的话,这个牛了是吧,牛大发了,所以说,就愿意帮他解决,就啥意思呢,你工作时啊,遇到一个问题,你就是,困扰了你这个,一个小时,两个小时,甚至是一天都有可能,这都是有可能的,所以这是一种常态,你不要说,哎呀,这个问题都困扰我10分钟了,我实在受不了了,你这太不值一提,都不屑,不屑理你是吧,所以自己多想一想,多呢,有这样的一种体会,因为这是你工作时的一种常态。

代码设计与实现之第一个请求:/toAddCost.do

  • 那继续,刚才我们说了这个增加的这个逻辑,然后呢,还有点细节啊,这个没有介绍全,再说一下,那刚才我们看到增加页面的时候啊,有细心的会发现,增加的时候,这里有几个,可以输入几个数据呢,1,2,3,4,5,6,对吧。
    在这里插入图片描述
  • 能输出6个数据,但是我们表里一共几个字段呢,10个,还差4个,哪去了,差4个的话,你想那个id,我们需要输入么,不需要,id不算对吧,除了id,还有3个,那3个没有,怎么办呢,默认值,默认是多少呢,其实,咱们这业务上有,你看咱们这个查询页面上,这块有个什么呢,业务说明,不知道你看没看到,有个说明,怕你不知道:
    在这里插入图片描述
  • 当然我们正式做项目时啊,以后你们工作时,不会有这个东西,这是我们为了学习方便,写在这了啊,它说了创建资费,就增加对吧,增加资费的时候,状态为暂停,那不用输入状态,默认为暂停对吧,暂停是几呢,1对吧;然后呢,记载创建时间,就是那个creatime,默认为sysdate,是这意思吧,是这样吧,默认为sysdate;然后还有一个,还有一个是那个开通时间,那开通时间,因为默认状态是暂停,有开通时间么,没有,所以开通时间是几呢,null,听明白了么。所以你在这个,在这个地方啊,在这,你这个CostDao.save()里啊,保存数据的时候,那么,我们传入的是6个值对吧,id你用序列生成;其他的3个值,状态,默认为1;然后呢,创建时间,默认为系统时间;开通时间,默认为null,听明白了么,这是一些细节,那再强调一下。
  • 那我们开发的话呢,是按照我们画图这个步骤来写啊,我们先写第一个请求,第一个请求很简单啊,就是我们访问Servlet转发到jsp,对吧,这个应该都会,有人说,那你增加按钮,之前路径没写过,但是呢,我们一看,那个网页上增加按钮,它都给你写上那个格式了,对吧,都写上了onclick等于location.ref,等于一个路径对吧,<input type="button" value="增加" class="btn_add" onclick="location.href='fee_add.html';" />,你只要把路径搞明白就可以了,那有人说,哎呀,路径我还是不会写,那你不会写的话,我以前也说过,你退一步讲,你实在不会写相对路径,你可以写绝对路径,绝对路径的格式是固定的,斜线,项目名,斜线,什么什么,是这样吧,固定的,你别管访问啥,都是这样的。所以说你不行的话,写绝对路径也能做出来,或者说,你写相对路径,你先不写,点点杠,试一下,写点点杠,试一下,你可以随便试试,没准就试对了,所以说,这个呢,自己尝试一下,不要只在想,有的时候,确实想不出来啊。
控制层之业务逻辑处理与控制分发:/web/MainServlet.java
  • 那我们来写,那写的话呢,咱们这样,我们先写Servlet,因为jsp依赖于它,然后呢,我们再写jsp,这两个都写完以后呢,再把增加按钮的路径处理好,然后呢,路径我有了要求,我要求呢,它是/toAddCost.do,这是我的规范。那打开这个Servlet,就MainServlet,当然了,我画的图上呢,我说了要加一个新方法,叫toAddCost,但是你直接加一个方法,没有用,因为我们这个类处理请求,靠的是service方法对吧,靠的是它,从父类继承过来的Servlet,你要想调用那个方法,是不是还得判断路径,才去调对吧,显然得在这,service方法里,还加一个判断,这应该能自己想到,因为这里头我都写上了,而且以前在做那个模拟员工管理时(Servlet2和Servlet3中),查询员工增加员工,不也是这么干的么,对吧,都是判断,加判断啊。那这块我判断一下, else if("/toAddCost.do".equals(path))

//根据规范(图)处理路径
if("/findCost.do".equals(path)) {
	findCost(req,res);
} else if("/toAddCost.do".equals(path)) {
	toAddCost(req,res);
} else {
	throw new RuntimeException("没有这个页面");
}

  • 当然有人可能写到这,会想,说现在我们是两个功能,判断两次,那将来项目功能多了,我就无限的判断么,可以这样,但是这样并不好对吧, 我们也可以怎么办呢,也可以说,我们把这个判断,判断之后所调的方法,封装到其他类当中,比如说,一个模块放几个方法,比如资费模块放findCost(),toAddCost(),等等,明白这意思吧,可以把这个相应的方法,分配到其他的类当中去啊。甚至呢,对这段代码我们,也可以给它写配置文件,配置好啊,每个路径对应哪个方法,然后我们去调,也可以。但是呢,其实呢,没有必要这样做,我们这块就简化做就可以了,就是简单处理就可以了,为啥呢,工作时呢,我们一般都会用到SpringMVC框架,或者是Strusts2框架,那个框架呢,会自动的帮我们调这个配置文件,调不同的方法,自动的把方法放到不同的类当中去,所以将来有框架的话,这段代码,不用我们判断了,框架帮我们处理了,会省很多事啊。
  • 那这是toAddCost.do,如果是这个路径,我就调这个方法,toAddCost(req, res);,那么这个方法呢,我需要加以声明,那方法的声明,它和findCost(),没什么区别,我可以呢,复制粘贴进行处理,那这个复制的findCost方法名改一下,改成叫toAddCost,然后呢,给个注释,这是打开增加资费的页面,这是打开那个增加的页面,不是保存,这个要把这个,它所代表的意义搞清楚,别整乱了。然后呢,toAddCost这个方法之内,没有任何的业务,就是转发,那转发到一个jsp,叫什么呢,叫add.jsp,即/WEB-INF/cost/add.jsp。然后你看啊,咱们以前做这个查询时,查询不也转发了么,是吧,查询也转发了,那查询,转发到查询jsp,find.jsp,增加转发到增加jsp,add.jsp1,这个是不是一样的方式啊,所以转发的路径是不是一样啊,对吧,所以你有了查询模块,转发的那个经验,增加时那个路径是一样的,一参考,你也不用去想它为什么会这样,它怎么写,以前怎么写,现在就怎么写对吧,就行啊。
  • 那我就转发了啊,request.getRequestDispatcher(),我记得做查询的转发的时候,我们是直接就写WEB-INF/cost/add.jsp,是吧,就从这开始写,req.getRequestDispatcher("WEB-INF/cost/add.jsp").forward(req, res);好,这就转发了,就一句话,然后呢,有同学问,说这个增加资费,我转发了,这数据 ,没有数据,我怎么去绑定数据呢,这学的有点太,太生硬了啊,这没有数据就别绑定,对吧,没有数据就不绑定了啊,就是说我们啊,给你讲一个项目,一个案例,这只是这个项目这么去做,我们换一个项目,肯定会有很多需要调整的地方,对吧,不可能都一样,参数不一样,有的有参数,有的没有,有的多,有的少啊,有的是转发,有的是重定向,可能是有调整的,这个调整,我们得多想一想啊。
视图层之业务基本逻辑与视图显示:/WEB-INFO/cost/add.jsp
  • 那这个方法有了,我们下面就写jsp就行了,那么还是,我在这个WEB-INF/cost之下,创建这个jsp啊,add.jsp,然后呢,jsp中的代码,我们可以呢,从这个静态页面中贴过来啊,所以去找到这个NETCTOSS_V02,下面的资费增加页面,资费页面在fee目录之下,资费增加为fee_add.html,一目了然对吧,很直观了,或者你打开页面看一下就知道了,那我把这个fee_add.html中的代码复制一下,然后粘贴过来,当然粘贴之前,还得写那个啥呢,还得写page指令,<%@page pageEncoding="utf-8" %>,然后呢,粘贴过来。粘贴过来以后,我们还得从头到尾过一遍,因为这个网页上也需要引入样式和图片对吧,它的路径很有可能也不对,我们看一下,然后呢,七八行有link,link上,它原来写了点点杠,点点杠要么,不要,因为咱们find.jsp,也是没有要对吧,跟它的意思一样,那你找葫芦画瓢也是把它去掉,再看,这个网页上有没有图片,我搜一下。好,60行,有一个图片,也是要把点点杠去掉,那么去掉以后Servlet和jsp都有了,最后呢,我们把增加按钮处理一下就好了。
  • 那打开find.jsp,然后,在find.jsp之上,我找到这个增加按钮,那么增加按钮,它是在63行,找一下,按钮上原来写了,onclick单击时,改变网址,location.href='fee_add.html';,它写的是一个静态的网页,但现在我们不是访问静态网页对吧,我们访问的是谁呢,也不能说jsp,访问的是谁呢,Servlet对吧,我们直接访问的是Servlet,Servlet访问路径是toAddCost.do,那这里面,我们最好写相对路径,但如果说你自己写的时候,我就不会写相对路径,你可以写绝对路径,绝对路径怎么写呢,斜线开头,项目名,然后斜线,toAddCost.do,即<input type="button" value="增加" class="btn_add" onclick="location.href='/netctoss/toAddCost.do';" />,是这意思吧,也可以这样写,因为我们讲路径有3种方式,你再不会写,你可以写个完整路径http什么什么对吧,你把它写完整,肯定没有任何歧义。
  • 那相对路径怎么写呢,那分析一下啊,分析一下,我们要访问的增加页面,是我们的目标,我们是在什么地方去访问增加页面呢,是点增加按钮去访问它对吧,而增加按钮在查询页面上,是这样吧,从查询到增加,是这样的,那我给你写一下,在这啊,就是说我们当前,正在访问的是资费查询页面,它的路径是/netctoss/findCost.do啊,对于浏览器而言,不知道有jsp,它只知道,有点do,有Servlet,我们要访问的目标,是这个啊,/netctoss/toAddCost.do,你会发现,我们所访问这两个Servlet是平级关系,所以,路径就写toAddCost.do这一段就行了,<input type="button" value="增加" class="btn_add" onclick="location.href='toAddCost.do';" />,所以就可以不用写那么麻烦,那当然了,这个路径啊,如果说你已经很熟了,其实你也不用把它列举出来,你脑子里一想,当前是谁,目标是谁,你就能想出来,如果不熟的话,列举一下,对比一下,更清楚,再一个,你就可以随便试,即便是试错了,它肯定会提示你路径不对,你看是哪不对,差哪,你再调整,看浏览器。
  • 那到这啊,可以测试啊,就测一下,我把这个项目呢,重新部署一下,然后呢,启动tomcat,然后呢,我访问一下,我打开浏览器,项目名是netctoss,我先访问查询啊,findCost.do,即localhost:8080/netctoss/findCost.do,查询到以后呢,去点增加,它打开了增加页面,toAddCost.do,即localhost:8080/netctoss/toAddCost.do,没错,就这样了,好,这就是第一个请求,完成了啊。那这是第一个请求。那我们再写第二个请求,增加功能呢,它最麻烦的,也就是在第二个请求上,但是呢,这个请求,和之前模拟的增加员工,跟那个其实没什么大的区别,浏览器要访问服务器传数据,表单要配置对吧,表单要配置,有3项,form上,得有action说明目标对吧,文本框,框上得有name,声明名字对吧,还有,如果是单选多选得怎么办,加value传什么值要声明对吧,这之前都讲过,你看着这个案例,得回顾一下。
  • 然后呢,配好以后保存,数据传给Servlet,Servlet怎么接收数据呢,有人到这,MainServlet这怎么接收数据,这就忘了,服务器怎么接收数据呢,就一种方法,没有第二种,request.getParameter(),是吧,如果是多个数据,getParameterValues(),这回顾一下,这不刚讲过的么,有人这个就忘了,还有人说,我得到getParameter得到的那个数据, 我想判断它是否为空,我怎么判断呢,这个有点让我诧异,你get到的是什么,不就是字符串么对吧,字符串怎么判断为空呢,就判断呗,所以说,你看啊,其实,你问的这个问题,你自己回顾一下,有点不是那么回事对吧,你仔细想,不是那么回事,但为什么会问出来呢,就是说一旦这个案例复杂了,你会把你以前的那些,你所掌握的那些小知识,都颠覆了,一旦你感觉难的时候,你就选择混乱,你的思维就会混乱,就会遗忘,不知道为啥,这就是我们,让你做这个练习的目的。
  • 你得想啊,你工作时的那个项目,绝对是比这个功能要复杂多的多了,如果你工作时的那个项目的代码,就这么简单的话,我跟你讲,你那个软件不用java去开发,用php更快,用java干什么呢,还麻烦,是吧。所以一定是比这复杂多的多,那个时候的话,你看哎呀,我虽然做过电信计费项目,虽然做过云笔记项目,我这个项目又更复杂了,我可能又做不出来了,因为你又会忘一些东西,就是说你在有压力的时候,你就思维就乱了,所以说,这个一定要静下心来,多去想多去练,当然还有人呢,这个问题问的比较深刻,就是说比如说,这个dao里面有一些,数据的细节啊,就有个问题啊,就是问的挺好,我给你解释一下。我们已经做了查询功能,在CostDao里呢,我们写了查询方法,这个查询的时候,我们是对于这个,base_durationbase_costunit_cost,这3个字段,这3个字段都是数字对吧,或整数,或小数,然后的话呢,我说了我们实体类,应该都用封装类型,好支持null对吧,但有同学仔细,突然就看到了说,这个数组得到以后,我数据库里得到为null,我得到的是0对吧,你注意到了么,你看我这个:
    在这里插入图片描述
  • 你看find.jsp页面里的基本时长,这是不是0啊,按理说应该是null,为啥是0呢,因为,因为什么呢,c.setBaseDuration(rs.getInt("base_duration"));,我rs.getInt,int是不是,这个getInt得到的是数字,明白么,就没有null,我getDouble,得到的也是数字,也没有null,所以它默认转为0了,自动的。那有人说,我想不要这个0,我就想空,怎么办呢,你得自己判断,比如说你把这个字段呢,当作字符串处理,getString,然后判断是不是为null,明白吧,如果为null,给它一个null值,如果不为null,我就再getInt,你可以判断一下,那有人说,那这也太麻烦了,那现在没办法,只能是这样,然后呢,将来我们会学到框架,我们学到框架以后就好了,框架比较聪明,它会自动帮我们判断,自动帮我们处理null,现在的话,没办法,那我也没判断,为什么呢,因为反正将来会用框架,先暂时就简单处理了啊。

资费增加功能代码实现之第一个请求:toAddCost.do

1…src/main/java/web/MainServlet.java
package web;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import dao.AdminDao;
import dao.CostDao;
import entity.Admin;
import entity.Cost;
import util.ImageUtil;

public class MainServlet extends HttpServlet {

	@Override
	protected void service(
		HttpServletRequest req, 
		HttpServletResponse res) throws ServletException, IOException {
		//获取访问路径
		String path = req.getServletPath();
		//根据规范(图)处理路径
		if("/findCost.do".equals(path)) {
			findCost(req,res);
		} else if("/toAddCost.do".equals(path)) {
			toAddCost(req,res);
		} else {
			throw new RuntimeException("没有这个页面");
		}
	}
	
	//查询资费
	protected void findCost(
		HttpServletRequest req, 
		HttpServletResponse res) throws ServletException, IOException {
		//查询所有的资费
		CostDao dao = new CostDao();
		List<Cost> list = dao.findAll();
		//将请求转发到jsp
		req.setAttribute("costs", list);
		//当前:/netctoss/findCost.do
		//目标:/netctoss/WEB-INF/cost/find.jsp
		req.getRequestDispatcher("WEB-INF/cost/find.jsp").forward(req, res);
	}

	//打开增加资费
	protected void toAddCost(
		HttpServletRequest req, 
		HttpServletResponse res) throws ServletException, IOException {
		req.getRequestDispatcher("WEB-INF/cost/add.jsp").forward(req, res);
	}
}
2.src/main/webapp/WEB-INF/cost/find.jsp
<%@page pageEncoding="utf-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值