5.xmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
6.xsi:
schemaLocation="
7.version="2.4">
8.
9.
10.HelloServlet
11.anni.HelloServlet
12.
13.
14.
15.HelloServlet
16./
17.
18.
19.
只要注意servlet和servlet-mapping两部分就可以了。
a.servlet标签中定义一个了名字叫做HelloServlet的servlet。
这个HelloServlet对应的class是anni.HelloServlet,请注意这里的class要写全名。
b.servlet-mapping标签则是把刚刚定义的HelloServlet映射到“/”这个请求路径上。
请回忆我们之前讲过的第 3.4.1 节“绝对路径与相对路径”中的部分,这里的“/”就代表当前应用的根路径,既http:
//localhost:
8080/06-01/,凡是有客户对此路径发出请求,就会交由HelloServlet处理。
例子在lingo-sample/06-01目录下,将整个目录放入tomcat的webapps即可使用。
对应的源代码放在lingo-sample/06-01/WEB-INF/src目录下,要放到tomcat的webapps目录下,才能使用compile.bat脚本进行编译。
6.2. jsp与servlet的关系
通过上面的例子,我们可以看到servlet与jsp的功能差不多,都是处理请求并返回响应。
甚至在操作时使用到的变量都极为相似,request,response,out这些在我们使用jsp的时候也遇到过。
不同的时是,jsp中这些变量拿来即用,servlet中还要通过参数来获得。
jsp和servlet如此相似,它们之间难道有什么联系吗?
为什么sun创造了两种功能相似的东西呢?
其实jsp就是servlet,你所写的jsp页面最终都会被服务器转换成servlet。
为了验证这一说法,我们编写一个效果与HelloServlet完全一样的hello.jsp,它的内容就只有这么点儿。
hello
访问http:
//localhost:
8080/06-01/hello.jsp,会看到与刚刚一样的效果。
现在打开tomcat的work目录。
在Catalina/localhost/06-01/org/apache/jsp目录下,可以看到两个文件,分别是hello_jsp.class和hello_jsp.java。
打开hello_jsp.java可以看到里边的源代码,我们只挑出其中一部分来看。
out=pageContext.getOut();
_jspx_out=out;
out.write("hello");
获得pageContext的输出流并将"hello"写入,于是浏览器上就看到了hello的字样。
是的,这里的hello_jsp.java就是由hello.jsp生成的。
服务器在获得请求的时候会先根据jsp页面生成一个java文件,然后使用jdk的编译器将此文件编译,最后运行得到的class文件处理用户的请求返回响应。
如果再有请求访问这jsp页面,服务器会先检查jsp文件是否被修改过,如果被修改过,则重新生成java重新编译,如果没有,就直接运行上次得到的class。
为什么第一次访问jsp的时候速度会那么慢?
就是因为要经过生成java和编译class的步骤。
以后再次访问同一页面就会感觉到速度明显变快,也是因为class文件已经生成的原因。
为什么jsp要经过这些步骤转换成servlet再去执行呢?
因为java起初做网站的时候就只有servlet可以使用,为此还专门指定了一套servlet标准,就是我们在代码中看到的javax.servlet包下的类。
但是人们马上就发现,使用servlet显示复杂页面太费力气了,使用servlet里的输出方式简直让人写到手抽筋,于是就有了仿效asp和php的jsp出现,开发人员可以在美工做好的页面上直接嵌入代码,然后让服务器将jsp转换成servlet执行。
有的朋友可能迷糊了,既然jsp是为了简化servlet开发,那么为什么我们现在又要去学习servlet?
既然servlet那么麻烦为什么不直接使用jsp就好了呢?
这是因为jsp虽然比servlet灵活,却容易出错,你找不到良好的方式来测试jsp中代码,尤其在需要进行复杂的业务逻辑时,这一点儿很可能成为致命伤。
所以一般都不允许在jsp里出现业务操作有关的代码,从这点来看,我们上一章中举的例子就严重违反了这一标准,CRUD的操作都写在了jsp这种,一旦出现问题就会让维护人员头大如斗。
servlet是一个java类,需要编译之后才能使用,虽然显示页面的时候会让人头疼,不过在进行业务操作和数据运算方面就比jsp稳健太多了。
因此我们就要结合两者的优点,在servlet进行业务操作和请求转发,jsp全面负责页面显示,这也是目前公司企业里常用的开发方式。
6.3. 使用servlet改写联系簿
既然jsp就是servlet,jsp中的那些功能在servlet中也就都可以实现,当然咱们不能再使用jsp指令(directive)和jsp动作(action)了,不过它们也都有替代方法,我们以后慢慢介绍。
现在我们使用servlet改写第五章中联系簿的例子,将CRUD操作都转移到servlet中,让jsp只负责页面显示。
新建一个ContactServlet.java,让它负责处理那些CRUD操作,它会直接引用ContactDao操作数据,现在我们可以把jsp中对ContactDao的引用删除了,所有数据都将由ContactServlet提供,现在jsp只管从request里取出数据显示出来即可。
为了让ContactServlet起作用,在web.xml中添加处理请求的配置。
ContactServlet
anni.ContactServlet
ContactServlet
/contact.do
servlet标签指定使用anni.ContactServlet,servlet-mapping将它绑定到/contact.do请求上,当我们看到浏览器上出现http:
//localhost:
8080/06-02/contact.do的时候,就表明ContactServlet在起作用了。
请别06-02目录下去找contact.do这个文件,它是不存在的。
与之前提到的forward()情况类似,虽然浏览器指定要contact.do这个资源,但服务器暗地里把这个请求交给ContactServlet处理,你可以把contact.do当作一个地址,实际上你要找的人是Cont