一、JSP标签介绍

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。
动作标签是由tomcat(服务器)来解释执行!它与java代码一样,都是在服务器端执行的!

二、JSP常用标签

jsp的常用标签有以下三个

  • < jsp:include >标签
  • < jsp:forward >标签
  • < jsp:param >标签

2.1、< jsp:include >标签
< jsp:include >标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。

语法:

< jsp:include page=“relativeURL | <%=expression%>” flush=“true|false” />

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
 
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。

例:使用jsp:include标签引入资源

JSPincludeTagTest.jsp :

</head>
<jsp:include page="/jsptests/head.jsp"></jsp:include>
  <body>
<h1>网页中间</h1>
    This is mid JSP page. <br>

  </body>
<jsp:include page="/jsptests/foot.jsp"></jsp:include>

head.jsp :

</head>
<h1>网页头部</h1>
  <body>

  </body>

foot.jsp :

</head>
<h1>网页尾部</h1>
  <body>


  </body>

2.2、< jsp:include >标签与include指令的区别

< jsp:include >标签是动态引入, < jsp:include >标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
而include指令(<%@ include file=“relativeURL”%>)是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。

例1、(include指令)

demo.jsp :

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  
<%!
	int i = 1000;
 %>

<h1>demo.jsp中i的值为:<%=i %></h1>

分别使用include指令(<%@ include file=“relativeURL”%>)和< jsp:include >标签包含上面的demo.jsp

使用include指令包含

</head>
  <%!
  	int i = 10;
   %>
  <body>
 <h1>includeTagDemo1.jsp中i的值为:<%=i %></h1>
<%@include file="/includeTest/demo.jsp" %>
  </body>

在编译jsp时就已经开始报错:Duplicate field
__2F_day12_5F_2_2F_WebRoot_2F_includeTest_2F_includeTagDemo1_2E_jsp.i
这个错误说的是变量i已经重复定义了

运行includeTagDemo1.jsp,浏览器显示HTTP Status 500 – Internal Server Error
Message Unable to compile class for JSP:
org.apache.jasper.JasperException: Unable to compile class for JSP:
An error occurred at line: [25] in the jsp file: [/includeTest/includeTagDemo1.jsp]
Duplicate field includeTagDemo1_jsp.k

因为静态包含是将全部内容包含进来之后,再进行处理,属于先包含后处理。由于被包含进来的页面demo.jsp中定义了一个变量i,而包含页面JspIncludeTagDemo01.jsp本身又定义了一个变量i,所以服务器在处理JspIncludeTagDemo01.jsp这个页面时就会发现里面有两个重复定义的变量i,因此就会报错。

例2、再使用< jsp:include >动态包含demo.jsp

<h1>includeTagDemo2</h1>
  <%!
  	int k = 10;
   %>
  <body>
 <h1>includeTagDemo2.jsp中k的值为:<%=k %></h1>
<jsp:include page="/includeTest/demo.jsp"></jsp:include>
  </body>

结果已经可以正确地显示,而且不会互相影响,这是因为使用jsp:include属于动态包含,动态包含就是指先将各个页面分别处理,处理完之后再将处理后的结果包含进来。
不管是< jsp:include >标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。

2.3、*.jspf扩展名文件在jsp:include、@include和c:import中的区别

JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。今天无意中发现,把一个JSP文件命名为jspf扩展名,然后include到另一个jsp文件中的,发现只有用"@include"指令的时候,jspf文件的内容才会被解析并执行其中的jsp指令和tag,而使用"jsp:include"和JSTL的"c:import"都没有用,jspf文件被当作纯文本文件处理了。

例1、< jsp:include >动态标签引入jspf页面

<body>
    <!-- include标签引入jspf -->
    <%-- include标签引入jspf --%>
    <%
    // include标签引入jspf
    /* include标签引入jspf */
     %>
     <jsp:include page="/jspfTest/head.jspf"></jsp:include>
    <%-- <%@include file="/jspfTest/head.jspf" %> --%>
    <h1>中间</h1>
     <jsp:include page="/jspfTest/foot.jspf"></jsp:include>
    
    <%-- <%@include file="/jspfTest/foot.jspf" %> --%>
  </body>

运行后,查看页面源代码与页面都原封不动的显示page指令。这说明jspf文件Tomcat服务器被当作纯文本文件处理了,没有当作jsp页面来解析执行!

两种解决办法:修改项目的web.xml或修改tomcat的web.xml

项目的web.xml :

<servlet-mapping>
  	<servlet-name>jsp</servlet-name>
  	<url-pattern>*.jsp</url-pattern>
  	<url-pattern>*.jspf</url-pattern>
  </servlet-mapping>

tomcat的web.xml :

<!-- 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>

2.4、< jsp:forward>标签

< jsp:forward>标签用于把请求转发给另外一个资源。

语法:<jsp:forward page=“relativeURL | <%=expression%>” />

page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

例1:使用使用< jsp:forward >标签跳转页面

forwardDemo1.jsp :

</head>
  
<h1>forwardDemo1</h1> 
<jsp:forward page="/jsptests/forwardDemo2.jsp"></jsp:forward> 
  <body>
    This is XKJ forwardDemo1 page. <br>
  </body>

forwardDemo2.jsp :

</head>
  <h1>forwardDemo2</h1> 
  
  <body>
    This is YTY forwardDemo2 page. <br>
  </body>

浏览器地址栏输入http://localhost:8080/day12_2/jsptests/forwardDemo1.jsp,响应成功。从页面的显示效果来看,页面已经完成了跳转,但地址栏没有变化,地址栏中显示的地址还是forwardDemo1.jsp,但页面显示的内容却是forwardDemo2.jsp中的内容。因为此跳转属于服务器端跳转。只要是服务器端跳转,则地址栏永远没有变化。

2.5、< jsp:param >标签

当使用< jsp:include >和< jsp:forward >标签引入或将请求转发给其它资源时,可以使用< jsp:param >标签向这个资源传递参数。

语法:

< jsp:include page=“relativeURL | <%=expression%>”>
 < jsp:param name=“parameterName”
 value=“parameterValue|<%= expression %>” />
 < /jsp:include>
 <jsp:forward page=“relativeURL | <%=expression%>”>
 <jsp:param name=“parameterName”
 value=“parameterValue|<%= expression %>” />
 </jsp:include>

< jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在< jsp:include>和< jsp:forward>标签中可以使用多个< jsp:param>标签来传递多个参数。

例666:使用< jsp:param>标签向被包含的页面传递参数

paramdemo1.jsp :

</head>
  <h1>paramdemo1</h1>
  <hr>
  <jsp:include page="/jspParam/getParam.jsp">
  	<jsp:param value="name" name="XkjLoveShali"/>
  	<jsp:param value="map" name="de_cache"/>
  </jsp:include>
  <body>
    This is YTY paramdemo1 page. <br>
  </body>

getParam.jsp :

</head> 韩流来袭</h1>
  <h1>接收paramdemo1传来的参数</h1>
  <h6><%=request.getParameter("XkjLoveShali") %></h6>
    <h6><%=request.getParameter("de_cache") %></h6>
  
  <body>
    This is my JSP page. <br>
  </body>

在paramdemo1.jsp页面中使用< jsp:include >标签将getParam.jsp页面包含进来,使用< jsp:param/>标签向getParam.jsp页面传递了两个参数XkjLoveShali和de_cache

例666666:使用< jsp:param >标签向要跳转的页面传递参数

paramdemo2.jsp :

</head>
  <h1>paramdemo2</h1>
  <hr>
  <jsp:forward page="/jspParam/getParam.jsp">
  	<jsp:param value="XkjLoveShali" name="name6"/>
  	<jsp:param value="de_cache" name="map"/>
  </jsp:forward>
  <body>
    This is YTY paramdemo2 page. <br>
  </body>

getParam.jsp :

</head>
  <h1> 韩流来袭</h1>
  <h1>接收paramdemo2传来的参数</h1>
  <h4><%=request.getParameter("name6") %></h4>
      <h2><%=request.getParameter("map") %></h2>
  
    <h3><%=request.getParameter("name6") %></h3>
     
  <body>
    This is getParam page. <br>
  </body>