今天突然想到一个问题,我们都知道,如果我们每一个jsp页面上都需要版权信息,菜单信息的话,我们不需要每个页面都写上版权信息和菜单信息,而是我们可以单独写一个jsp页面,把版权信息和菜单信息写在这个单独的jsp页面中,然后再在每一个jsp页面上包含这个单独的jsp页面就可以了,这样这些版权信息和菜单信息,这些相同的信息只要写一遍,就可以在需要的jsp页面上包含进来就行了,达到简便复用的目的。
大家都知道在javaWeb开发中,jsp知识中,页面包含有2中方式,就是(jsp动作,如<jsp:include page="/index.jsp"></jsp:include>)和include指令(<%@ include file="/index.jsp" %>),这2种都是页面包含,我这里就不做详细的说明它们2者之间的区别了,网上的很多很多的文章说,这2者的区别主要是一个是动态包含,一个是静态包含,我个人觉得,这2者的什么动态包含,静态包含没有任何的意义,其实这2者的主要区别是jsp的include动作可以传递参数,而include指令不能传递参数,这就是2者最大的区别,至于网上大篇幅的说什么动态包含和静态包含,我都懒得理,没一点实际的意义!
看如下代码
jsp,include动作如下:
<jsp:include page="/index.jsp"><jsp:param value="zhangsan" name="userName"/></jsp:include>
jsp,include指令如下:
<%@ include file="/index.jsp" %>
想必大家都看到了上面的代码吧
include动作是可以传递参数的。而include指令是不能传递参数的!有些人会有疑问了,那可以这样写啊,<%@ include file="/index.jsp?userName=zhangsan" %> ,我也曾经这样想过,可事实上是不可以的,因为file属性只能填写一个页面地址(index.jsp或者index.html这种),后面不能带任何的参数,如果带了参数,那就会把/index.jsp?userName=zhangsan这个整体看做是一个页面路径,换句话说会把/index.jsp?userName=zhangsan这句话当成一个整体的页面路径,而项目中根本就没有叫/index.jsp?userName=zhangsan的这个页面。
所以include指令是不能带参数的,只能是<%@ include file="/index.jsp" %>或者<%@ include file="/index.html" %>这种,还有一点要注意,include指令不支持Servlet路径,也就是说,像<%@ include file="/SaveData2" %>这种是不支持的,file属性值不能写Servlet的访问路径。
请大家记住:include指令是不能带参数,nclude指令也不支持Servlet路径。
接下来,我要讲的就是一个实际中遇到的问题了,我现在想在home.jsp页面中包含一个叫hyperLinkList.jsp的页面,可是hyperLinkList.jsp页面中的数据是从一个Servlet中转发过来的,所以我不能直接在home.jsp页面中把hyperLinkList.jsp页面包含进来,那是不是可以在home.jsp页面中包含该Servlet呢?OK,说干就干。
在home.jsp页面中加上如下代码:其中page="/SaveData2",page的属性值/SaveData2就是Servlet路径
<jsp:include page="/SaveData2"></jsp:include>
需要特别注意一点:Servlet中不能写转发,需要写包含
需要这样写request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response);
而不能写request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response);
所以Servlet中必须是include包含,才能通过<jsp:include page="/SaveData2"></jsp:include>这句话,把SaveData2这个Servlet中封装的数据包含放在hyperLinkList.jsp页面中,从而最终把hyperLinkList.jsp页面包含进home.jsp页面中!
如下代码:
@WebServlet("/SaveData2") public class SaveData2 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); // 超链接实体,集合 List<HyperLink> hyperLinkList = new ArrayList<HyperLink>(); HyperLink hyperLink1 = new HyperLink("626", "智联招聘", "http://www.zhaopin.com/", "找工作上智联招聘"); HyperLink hyperLink2 = new HyperLink("627", "前程无忧", "http://www.51job.com/", "找工作上前程无忧"); HyperLink hyperLink3 = new HyperLink("628", "拉勾网", "https://www.lagou.com/", "IT互联网垂直招聘"); HyperLink hyperLink4 = new HyperLink("629", "酷狗音乐", "http://www.kugou.com/", "就是歌多"); HyperLink hyperLink5 = new HyperLink("630", "大众点评", "http://www.dianping.com/", "点评中的佼佼者"); HyperLink hyperLink6 = new HyperLink("891", "12306", "http://www.12306.cn/mormhweb/", "官方购买火车票"); hyperLinkList.add(hyperLink1); hyperLinkList.add(hyperLink2); hyperLinkList.add(hyperLink3); hyperLinkList.add(hyperLink4); hyperLinkList.add(hyperLink5); hyperLinkList.add(hyperLink6); request.setAttribute("hyperLinkList", hyperLinkList); //转发至jsp页面 // request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response); request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response); } }
如果我Servlet中用的不是包含,用的是转发,大家猜下是什么效果呢?
@WebServlet("/SaveData2") public class SaveData2 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); // 超链接实体,集合 List<HyperLink> hyperLinkList = new ArrayList<HyperLink>(); HyperLink hyperLink1 = new HyperLink("626", "智联招聘", "http://www.zhaopin.com/", "找工作上智联招聘"); HyperLink hyperLink2 = new HyperLink("627", "前程无忧", "http://www.51job.com/", "找工作上前程无忧"); HyperLink hyperLink3 = new HyperLink("628", "拉勾网", "https://www.lagou.com/", "IT互联网垂直招聘"); HyperLink hyperLink4 = new HyperLink("629", "酷狗音乐", "http://www.kugou.com/", "就是歌多"); HyperLink hyperLink5 = new HyperLink("630", "大众点评", "http://www.dianping.com/", "点评中的佼佼者"); HyperLink hyperLink6 = new HyperLink("891", "12306", "http://www.12306.cn/mormhweb/", "官方购买火车票"); hyperLinkList.add(hyperLink1); hyperLinkList.add(hyperLink2); hyperLinkList.add(hyperLink3); hyperLinkList.add(hyperLink4); hyperLinkList.add(hyperLink5); hyperLinkList.add(hyperLink6); request.setAttribute("hyperLinkList", hyperLinkList); //转发至jsp页面 request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response); // request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response); } }
效果如下:访问home.jsp的时候,直接跳转到了hyperLinkList.jsp页面
所以得出结论:include动作支持Servlet路径,<jsp:include page="/SaveData2"></jsp:include>,同时Servlet中需要使用request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response);
而不能使用request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response);
其实home.jsp页面中包含一个Servlet路径,有很多种写法,以下几种写法都可以,
<jsp:include page='${"/SaveData2"}'></jsp:include>
<jsp:include page="${'/SaveData'}"></jsp:include>
<jsp:include page="<%="/SaveData2"%>"></jsp:include>
<jsp:include page='<%="/SaveData"%>'></jsp:include>
<jsp:include page="/SaveData2"></jsp:include> (这行代码,我的Eclispe中会显示一把红色的小叉叉,不是语法错误,可能是Eclispe编辑器做了校验导致的,大家可以忽略掉,如果看这把小叉叉不舒服的话,就用上面的那4种写法,就不会出现小叉叉了)
有一点非常非常需要注意:像<jsp:include page="/SaveData2"></jsp:include>这句话必须写在同一行,不能换行写,要不然会报错,当然啦,如果像
<jsp:include page="/SaveData2">
<jsp:param value="zhangsan" name="userName"/>
</jsp:include>这种带了参数的,是可以换行的,如果像<jsp:include page="/SaveData2"></jsp:include>这种没带参数的,就必须在同一行,要不然会报错
这里的红色小叉叉,不是语法错误,可能是Eclispe编辑器做了校验导致的,不是错误,大
家可以忽略掉,如果看这把小叉叉不舒服的话,(有强迫症的人估计受不了,哈哈)就用上面的那4种写法,就不会出现小叉叉了
像下面这种写法就会报错:不信的话,你们自己亲自试一试(所以写<jsp:include page="/SaveData"></jsp:include>这句话的时候,千万别换行,你换行就会报错)
<jsp:include page="/SaveData">
</jsp:include>
换行导致的报错信息如下:
OK,我们最后再说一点,上面我也讲了include指令不支持Servlet路径,像<%@ include file="/SaveData2" %>这种是不支持的,file属性值不能写Servlet的访问路径。
那我们就是想通过include指令的方式来包含一个Servlet怎么办呢?
我们就通过一种变通的办法来试一下,看看是否可行?
我们新建一个页面index.jsp,页面名字随便取,我这里就取名index.jsp
index.jsp页面代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>临时过渡页面</title> </head> <body> <h2>临时过渡页面</h2> <% request.getRequestDispatcher("/SaveData2").forward(request, response); %> </body> </html>
我们在home2.jsp中包含index.jsp,而index.jsp页面中只有一句代码,就是转发到SaveData2这个Servlet,这样就等于变相的在home2.jsp中包含了SaveData2这个Servlet。
home2.jsp页面如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>测试include指令能否包含Servlet</title> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/body.css"> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/mark.css"> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/console.css"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/console.js"></script> </head> <body> <h2> 测试include指令能否包含Servlet(如果不能使用Servlet路径,那就写jsp路径,在jsp中再转发到Servlet,相当于利用jsp从中间过渡一下) </h2> <%@ include file="/index.jsp"%> </body> </html>
SaveData2这个Servlet的代码如下:
@WebServlet("/SaveData2") public class SaveData2 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); // 超链接实体,集合 List<HyperLink> hyperLinkList = new ArrayList<HyperLink>(); HyperLink hyperLink1 = new HyperLink("626", "智联招聘", "http://www.zhaopin.com/", "找工作上智联招聘"); HyperLink hyperLink2 = new HyperLink("627", "前程无忧", "http://www.51job.com/", "找工作上前程无忧"); HyperLink hyperLink3 = new HyperLink("628", "拉勾网", "https://www.lagou.com/", "IT互联网垂直招聘"); HyperLink hyperLink4 = new HyperLink("629", "酷狗音乐", "http://www.kugou.com/", "就是歌多"); HyperLink hyperLink5 = new HyperLink("630", "大众点评", "http://www.dianping.com/", "点评中的佼佼者"); HyperLink hyperLink6 = new HyperLink("891", "12306", "http://www.12306.cn/mormhweb/", "官方购买火车票"); hyperLinkList.add(hyperLink1); hyperLinkList.add(hyperLink2); hyperLinkList.add(hyperLink3); hyperLinkList.add(hyperLink4); hyperLinkList.add(hyperLink5); hyperLinkList.add(hyperLink6); request.setAttribute("hyperLinkList", hyperLinkList); //转发至jsp页面 // request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response); request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response); } }经过我的测试,不管SaveData2这个Servlet中 是
forward(request.getRequestDispatcher("/hyperLinkList.jsp").forward(request, response);)
还是include(request.getRequestDispatcher("/hyperLinkList.jsp").include(request, response);),
效果都是直接跳转到hyperLinkList.jsp页面
最后一点需要注意一下:
我们在浏览器地址栏中,直接输入http://127.0.0.1:8888/xml/SaveData2这个地址回车一下,会跳转到hyperLinkList.jsp页面,
会显示乱码,如下图:
需要在SaveData2这个Servlet中加入下面这句话,才不会显示乱码!
response.setContentType("text/html;charset=utf-8");