JSP技术(四)——JSP标签
来源:互联网 发布:保定学习seo 编辑:程序博客网 时间:2024/05/20 09:10
JSP标签介绍
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。
JSP常用标签
jsp的常用标签有以下三个:
<jsp:include>
标签<jsp:forward>
标签<jsp:param>
标签
<jsp:include>
标签
<jsp:include>
标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。其语法为:
<jsp:include page="relativeURL | <%=expression %>" flush="true|false" />
- page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
- flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
例,使用jsp:include标签引入资源。
<%@ 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>jsp的jsp:include标签测试</title></head><body> <%--使用jsp:include标签引入其它JSP页面--%> <jsp:include page="/public/head.jsp"></jsp:include> <h1>使用jsp:include标签引入其它JSP页面</h1><br/> <jsp:include page="/public/foot.jsp"></jsp:include></body></html>
运行结果:
<jsp:include>
标签与include指令的区别
<jsp:include>
标签是动态引入,<jsp:include>
标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。
通过下面的例子来说明<jsp:include>
标签与include指令的区别。
demo.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>jsp:include标签与include指令的区别</title></head><body> <%! int i = 1000; %> <h1>demo.jsp中i的值为:<%=i %></h1></body></html>
分别使用include指令和<jsp:include>
标签两种包含语句,包含以上的demo.jsp。
使用@include指令包含内容
<%@ 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>jsp:include标签与include指令的区别</title></head><body> <%! int i = 10; %> <h1>demo1.jsp中i的值为:<%=i %></h1> <%@ include file="/demo.jsp" %></body></html>
此时在编译jsp时就已经提示出错了,如下所示:
这个错误说的是变量i已经重复定义了。
运行demo1.jsp,结果如下:
运行后发现出现了重复定义变量i的错误提示信息,因为静态包含是将全部内容包含进来之后,再进行处理,属于先包含后处理。由于被包含进来的页面demo.jsp中定义了一个变量i,而包含页面demo1.jsp本身又定义了一个变量i,所以服务器在处理demo1.jsp这个页面时就会发现里面有两个重复定义的变量i,因此就会报错。
而如果现在使用的是<jsp:include>
动态包含的话,观察以下程序:使用动态包含
<%@ 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>jsp:include标签与include指令的区别</title></head><body> <%! int i = 10; %> <h1>demo1.jsp中i的值为:<%=i %></h1> <jsp:include page="/demo.jsp"></jsp:include></body></html>
运行结果:
发现结果已经可以正确地显示,而且不会互相影响,这是因为使用jsp:include属于动态包含,动态包含就是指先将各个页面分别处理,处理完之后再将处理后的结果包含进来。
不管是<jsp:include>
标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
*.jspf扩展名文件在jsp:include、@include和c:import中的区别
JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。今天无意中发现,把一个JSP文件命名为jspf扩展名,然后include到另一个jsp文件中,发现只有用”@include”指令的时候,jspf文件的内容才会被解析并执行其中的jsp指令和tag,而使用”jsp:include”和JSTL的”c:import”都没有用,jspf文件被当作纯文本文件处理了。
比如现在有一个head.jspf页面和foot.jspf页面。
head.jspf:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><h1 style="color:red;">网页头部</h1>
foot.jspf:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><h1 style="color:blue;">网页尾部</h1>
首先使用”@include”指令将”head.jspf和foot.jspf” include到IncludeTagTest.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>jsp的Include指令测试</title></head><body> <%-- 使用include指令引入jspf页面 --%> <%@ include file="/public/head.jspf" %> <h1>网页主体内容</h1> <%@ include file="/public/foot.jspf" %></body></html>
运行IncludeTagTest.jsp页面,运行结果如下:
jspf文件的内容会被解析并执行其中的jsp指令和tag,查看浏览器解析IncludeTagTest.jsp页面生成的源代码,如下所示:
<!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>jsp的Include指令测试</title></head><body><h1 style="color:red;">网页头部</h1> <h1>网页主体内容</h1><h1 style="color:blue;">网页尾部</h1></body></html>
然后再使用<jsp:include>
标签将”head.jspf”和”foot.jspf” include到IncludeTagTest1.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>jsp的jsp:include标签测试</title></head><body> <%-- 使用jsp:include标签引入其它JSPf页面 --%> <jsp:include page="/public/head.jspf"></jsp:include> <h1>网页主体内容</h1> <jsp:include page="/public/foot.jspf"></jsp:include></body></html>
运行IncludeTagTest1.jsp页面,运行结果如下:
查看浏览器解析IncludeTagTest.jsp页面生成的源代码,如下所示:
<!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>jsp的jsp:include标签测试</title></head><body> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><h1 style="color:red;">缃戦〉澶撮儴</h1> <h1>网页主体内容</h1> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><h1 style="color:blue;">缃戦〉灏鹃儴</h1></body></html>
可以看到,head.jspf和foot.jspf中的
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
没有解析执行,而是原封不动地作为文本内容输出到页面上了,在IE下是看不到其输出的,在Google和Firefox浏览器下运行则可以看到其输出。
这说明jspf文件Tomcat服务器被当作纯文本文件处理了,没有当作jsp页面来解析执行,那么该如何解决这个问题呢?如何让tomcat服务器能够解析执行*.jspf文件中的java代码和标签呢,有如下的几种解决办法:
解决办法一:修改web.xml文件,添加对扩展名为*.jspf文件的映射。
如下所示:<!-- 让jspf扩展名同样成为JSP Servlet处理的文件。 --><servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jspf</url-pattern></servlet-mapping><!-- 让jsp扩展名同样成为JSP Servlet处理的文件。 --><servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern></servlet-mapping>
上面的配置方式也可以简写成这样:
<servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>*.jsp</url-pattern><!-- 让jspf扩展名同样成为JSP Servlet处理的文件。 --><url-pattern>*.jspf</url-pattern></servlet-mapping>
两种写法的效果都是一样的。添加这样的配置信息后,此时tomcat服务器就可以正常解析执行*.jspf文件了,如下所示:
解决办法二:修改Tomcat服务器的web.xml文件,添加对扩展名为*.jspf文件的映射。
找到tomcat服务器的web.xml文件,如下所示:
找到名字为jsp的那个Servlet,如下所示:<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup></servlet>
然后根据Servlet名称找到对应的servlet-mapping配置,如下所示:
<servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern></servlet-mapping>
在这里可以看到,名字为jsp的那个Servlet只支持
*.jsp
和*.jspx
两种扩展名,因此可以在这个地方多添加一个<url-pattern>*.jspf</url-pattern>
,如下所示:<!-- The mappings for the JSP servlet --><servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> <url-pattern>*.jspf</url-pattern></servlet-mapping>
经过这样的配置之后,Tomcat服务器就可以正常解析和执行*.jspf文件了。
<jsp:forward>
标签
<jsp:forward>
标签用于把请求转发给另外一个资源。其语法为:
<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
例,使用<jsp:forward>
标签跳转页面。
forwardDemo1.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>使用jsp:forward标签跳转页面</title></head><body> <%--使用<jsp:forward>标签跳转到forwardDemo2.jsp--%> <jsp:forward page="/forwardDemo2.jsp"></jsp:forward></body></html>
forwardDemo2.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>使用jsp:forward标签跳转页面</title></head><body> <h1>跳转之后的页面!!</h1></body></html>
运行结果如下:
从页面的显示效果来看,页面已经完成了跳转,但地址栏没有变化,地址栏中显示的地址还是forwardDemo1.jsp,但页面显示的内容却是forwarDemo2.jsp中的内容。因为此跳转属于服务器端跳转。只要是服务器端跳转,则地址栏永远没有变化。
<jsp:forward>
标签在实际开发中的应用场景
在实际开发中,我们要为网站设置首页,访问首页时,我们要将数据交给Servlet进行处理,但我们又不能在项目的web.xml文件像下面这样这样配置:
<!-- 这儿是不能配置Servlet的!!! --><welcome-file-list> <welcome-file>/IndexServlet</welcome-file></welcome-file-list>
解决方案是:在项目的web.xml中配置网站的首页,如下:
<welcome-file-list> <welcome-file>/index.jsp</welcome-file></welcome-file-list>
然后在index.jsp在使用jsp:forward标签跳转到Servlet,如下:
<%@ 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>Insert title here</title></head><body> <!-- <jsp:forward>标签的应用场景 --> <jsp:forward page="/IndexServlet"></jsp:forward></body></html>
<jsp:param>
标签
当使用<jsp:include>
和<jsp:forward>
标签引入或将请求转发给其它资源时,可以使用<jsp:param>
标签向这个资源传递参数。
语法1
<jsp:include page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /></jsp:include>
语法2
<jsp:forward page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /></jsp:include>
<jsp:param>
标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>
和<jsp:forward>
标签中可以使用多个<jsp:param>
标签来传递多个参数。
例1,使用<jsp:param>
标签向被包含的页面传递参数。
IncludeTagTest2.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>使用jsp:param标签向被包含的页面传递参数</title></head><body> <jsp:include page="/inc.jsp"> <jsp:param value="hello" name="parm1"/> <jsp:param value="world" name="parm2"/> </jsp:include></body></html>
inc.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>使用jsp:param标签向被包含的页面传递参数</title></head><body> <h1>接收从IncludeTagTest2.jsp页面中传递过来的参数:</h1> <h2><%=request.getParameter("parm1") %></h2> <h2><%=request.getParameter("parm2") %></h2></body></html>
在IncludeTagTest2.jsp页面中使用<jsp:include>
标签将inc.jsp页面包含进来,使用<jsp:param/>
标签向inc.jsp页面传递了两个参数parm1和parm2。
IncludeTagTest2.jsp页面运行结果如下:
例2,使用<jsp:param>
标签向要跳转的页面传递参数。
forwardDemo3.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>使用jsp:param标签向要跳转的页面传递参数</title></head><body> <% int x = 10; %> <%--使用<jsp:forward>标签跳转到forwardDemo4.jsp--%> <%--使用<jsp:param>标签向forwardDemo4.jsp传递参数--%> <jsp:forward page="/forwardDemo4.jsp"> <jsp:param value="<%=x %>" name="ref1"/> <jsp:param value="liayun" name="ref2"/> </jsp:forward></body></html>
forwardDemo4.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>使用jsp:param标签向要跳转的页面传递参数</title></head><body> <h1>跳转之后的页面!!</h1> <h1>接收从forwardDemo3.jsp传递过来的参数:</h1> <h1>ref1:<%=request.getParameter("ref1") %></h1> <h1>ref2:<%=request.getParameter("ref2") %></h1></body></html>
运行结果如下:
映射JSP
例如,将forwardDemo3.jsp映射为15.html,和Servlet设置一样,只需在项目的web.xml文件中添加如下代码:
<servlet> <servlet-name>xxxx</servlet-name> <jsp-file>/forwardDemo3.jsp</jsp-file></servlet><servlet-mapping> <servlet-name>xxxx</servlet-name> <url-pattern>/15.html</url-pattern></servlet-mapping>
运行结果如下:
如何查找JSP页面中的错误
JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。如:
<%@ page language="java" import="java.util.*" 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>查找jsp的错误</title></head><body> <% int x = 1/1; %> <%=x; %></body></html>
运行结果为:
JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。
JSP页面翻译成的Servlet程序在运行时出现异常,这与普通Java程序的运行时错误完全一样,Java虚拟机将提示错误发生在Servlet源文件中的位置(行和列)以及相关信息。如:
<%@ page language="java" import="java.util.*" 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>查找jsp的错误</title></head><body> <% int x = 1/0; %></body></html>
运行以上代码会报如下异常:
java.lang.ArithmeticException: / by zero at org.apache.jsp._12_jsp._jspService(_12_jsp.java:121) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)
说明_12_jsp.java源文件中的第121行有问题。找到_12_jsp.java源文件,发现第121行代码为:
int x = 1/0;
所以对照着看就明白jsp中哪儿出现了错误。这类错误是最恶心的!
- JSP技术(四)——JSP标签
- JSP的标签技术
- JSP的标签技术
- JSP技术(四)
- JSP自定义标签开发(四)——带标签体的标签实现
- JSP标签——jsp:forward,jsp:incluce
- jsp技术(四)—— EL表达式
- JSP技术(二)——JSP指令
- JSP——了解Jsp技术
- jsp——动作标签
- JavaEE——JSP标签
- JSP 技术 —— 是敌是友
- JSP 技术 —— 是敌是友?
- JavaEE技术——JSP
- JSP————详解jsp标签
- JSTL JSP标准标签库(四)
- JSP学习笔记(四):JSTL标签
- JSP学习笔记(四)---自定义标签
- hdu4826Labyrinth-dp动态规划
- Android Studio解决plugin with id 'android' not found问题
- java se-作业5-复制文件-2016.7.24
- 【MySQL】JDBC连接MySQL的一些问题以及解决办法
- spring mvc无法访问controller的解决方法
- JSP技术(四)——JSP标签
- (4.1.27.11)Android动态加载so文件
- hdu 3699 fzu 2009 A hard Aoshu Problem 枚举 模拟
- EasyDarwin开源流媒体云平台之语音对讲功能设计与实现
- 变量的定义 scanf 的使用 简单运算符
- java开发环境配置及软件下载
- php的写时复制
- c printf格式总结
- POJ 2533 Longest Ordered Subsequence