初学jsp+servlet时经常碰上的几个错误:404、路径正确但页面没有任何内容、样式和图片丢失。
这几个错误曾经让我在debug时头大,现在总结一下,其实它们都跟路径有关,正是因为没有处理好路径跳转的问题,才引发了这一连串的错误。
首先要说明的是:我们的页面本来是没有问题的,导致问题发生的是路径跳转。
那么,使我们的URL路径跳转的操作有哪些呢?
大概有以下几种:
1、客户端实现的跳转(如html里的<a>标签和表单提交、js里的window.location.href)
2、request.getRequestDispatcher
3、response.sendRedirect
那么这些路径跳转方式有什么不同呢?
首先是客户端实现的跳转:
客户端实现的跳转最不容易出现问题,
但值得注意的是“/”代表的不是项目的根路径而是tomcat里指定的根路径(默认在webapps/ROOT下)
注意:urlPatterns里的“/”除外,urlPatterns里的“/”指的是项目的根目录!
所以要用request.getContextPath()来获取项目的根路径
如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<style type="text/css">
#p1 {
height: 20%;
20%
}
</style>
</head>
<body>
<a href="<%=request.getContextPath()%>/servlet/AddServlet">click</a>
<img id="p1" src="<%=request.getContextPath()%>/spic/img9.jpg"/>
</body>
</html>
绝对路径这么麻烦,那么为什么不用相对路径呢?理由如下:
使用request.getContextPath()还有一点重要原因,在服务器内部(request.getRequestDispatcher)跳转后,页面对应URL路径会发生变化,而此时若再以相对路径去请求资源很可能请求不到需要的资源,此时就会发生样式和图片丢失的问题。
服务器内部跳转(request.getRequestDispatcher)
以这种方式实现的跳转在服务器内部运行,不会经过客户端的处理,对应的URL路径不会发生变化,究其原因是因为http的特性只允许客户端发起的请求重新定位URL路径。因此,即使在servlet里用request.getRequestDispatcher跳转到其它路径,实际上其路径并不会发生改变,可以简单的理解为把本来要跳转到路径的资源移到原路径下运行。
可以看出如果我们在servlet里跳转到另一个servlet或jsp页面时,其路径还是原路径。
值得注意的是:
因为在服务器内部跳转后需要request和response对象才能进行后续操作,因此需要forward(request,response),如果没有forward就会出现页面没有任何内容的错误,因为没有获取request,不能进行后续操作。
请求重定向(response.sendRedirect)
当在servlet里用请求重定向时,实际上是返回给客户端信息,让客户端重新发一次http请求给指定的资源,因此才实现路径的跳转。
这样可以真正实现路径的跳转,也不容易出现资源错误,但也因为重新进行的http请求(http的无状态性),使request里保存的数据不能传递,数据只能通过“........?a=1&b=flypie”这种形式写在URL里。