我们都知道,在访问网站登陆的时候,会有输入验证码的情况,而且每次登陆所输入的验证码都不同,那么这是用什么实现的?
猜想1:直接写在jsp中,然后由servlet转发并呈现给用户
答:jsp一般是用来帮助我们编辑网页与java的,其本质上还是java,因为服务器在执行jsp的时候会将它翻译成一个与servlet几乎一样但是只是名字不同的一个接口实现类。那么jsp中是可以写java的,但是由于我们开发的web项目采用的是mvc模式,对数据进行运算放在数据库的相关工具类或者工厂类中,那么呈现出网页视图即向浏览器发送html则是jsp的任务,而servlet在这两者中间起到连接和传递的功能。我们知道验证码的生成其实是一个动态过程,每次请求访问都会返回一个不同的验证码,那么这种行为是不仅仅是显示图片那么简单,背后有着生成随机动态验证码的过程。那么如果我们把生成验证码的功能放在jsp中,就和mvc模式相违背。项目代码必定耦合度高,维护和复用性也会有所影响。虽然jsp脚本可以熟悉java,但是我们依然不能这么做。
猜想2 : 写在servlet中,由sevlet进行动态生成
答:这也是不对的,servlet作为处理http协议的组件,那么他的功能最好单一一些比较好,就是处理浏览器的请求并进行转发或者重定向。那么假设处理登陆功能的logservlet有输入验证码的功能,如果支付功能payservlet也要有输入验证码的功能,那么这段代码的复用性就成为了问题,耦合度也提高了。所以我们应当写在工具类中或者工厂类中,不过可以让servlet通过文件读写的字节流发送给浏览器。
上述是从mvc开发模式角度来分析这个问题,jsp一般用来呈现静态资源而servlet则是处理动态请求。那么验证码是动态的,所以从mvc开发模式角度分析,可以得出这个答案
那我们从浏览器运行html脚本的工作原理上来重新看待这个问题,是否能得出相同的结论呢?
我们附上浏览器加载网页的简易原理
假设我们的验证码就是图片img,当我们通过浏览器访问服务器,服务器通过jsp给我们返回的是一个html网页文件,浏览器开始加载网页并执行html语句给我们呈现出网页视图。这个过程是从上到下执行的,假设我们的验证码是img,处在用户和密码之后的位置,那么他会先加载用户和密码输入框,再加载验证码。那么当运行到img时,浏览器再向服务器发送请求,要求获取图片,但是这个图片是静态的而不是动态,所以不能用html的img标签来实现动态图片的展示。
所以我们要是想要向浏览器展示动态图片,只能用servlet来实现。当浏览器加载到验证码图片位置时,浏览器向服务器发送请求,这时候我们用一个imgservlet来处理浏览器需求验证码的请求,这个imgservlet则调用工厂类中的imgCreate方法构造一个动态图片,然后将这个动态图片通过字节流传输给浏览器。
从浏览器运行原理角度也能得出相应的结论,同时也是符合mvc模式设计原理。