一、jsp标签技术简介
在jsp中要写的java代码很多,人们希望java能从jsp页面中抽离出来,所以就出现了jsp标签技术,也称为JSP动作元素
jsp标签技术分为四大类
1.jsp标签:也称为jsp动作元素,这是java自带的,不用引入第三方的包
2.el表达式 :作用主要是替代<%= %>脚本表达式,另外有一套EL函数库(由san公司提供)
3.JSTL标签库:在javaee4.0之前要导入jar包,但是5.0之后就不用了,但是需要<%@ taglib%>指令引入标签库
4.自定义标签,这是在上面几种情况不能满足实际开发的时候,可以采取自定义标签。
二、jsp标签
从上面已经看到了jsp标签技术有四大类,下面先看
jsp标签由san公司提供,不用引入jar包,它的作用就是抽离java代码,它把用java代码实现的功能用标签技术来实现。
常见的方法
<jsp:include>标签
用来替代request.getRequestDispatcher().include(),页面包含的作用。
<jsp:forward>标签
用来替代request.getRequestDispatcher().forward(),页面转发。
<jsp:param>标签
配合前两个标签使用,可以在包含或转发时,带一些参数过去
2.1 <jsp:include>标签
新建一个 bq_Include.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<jsp:include page="bq_Include_header.jsp"></jsp:include>
<h3>这是主体</h3>
</body>
</html>
上面的bq_Include_header.jsp,如下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
</head>
<body>
<h1>这是头部</h1>
</body>
</html>
这时候再浏览器中输入:http://localhost/Day06/Biaoqian/bq_Include.jsp,可得
查看源码
而bq_Include.jsp和bq_Include_header.jsp转换的servlet没有合并
上面的我们也可以用原始的java来实现
只需要改动bq_Include.jsp即可
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%//这是jsp标签技术实现的
//<jsp:include page="bq_Include_header.jsp"></jsp:include>
%>
<%//这是java代码实现的 %>
<%
request.getRequestDispatcher("bq_Include_header.jsp").include(request,response);
%>
<h3>这是主体</h3>
</body>
</html>
那么在浏览器可显示
但是里面的源码跟用JSP标签的不一样
‘
另外可以用jsp指令来合并,那么跟上面的有什么区别?
jsp指令来合并
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%//这是jsp标签技术实现的
//<jsp:include page="bq_Include_header.jsp"></jsp:include>
%>
<%//这是java代码实现的 %>
<%
//request.getRequestDispatcher("bq_Include_header.jsp").include(request,response);
%>
<%//这是jsp指令实现的 %>
<%@ include file="bq_Include_header.jsp" %>
<h3>这是主体</h3>
</body>
</html>
注意这时候要去掉bq_Include.jsp里面的代码
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
才不会报错,为什么呢?后面再讲
然后可再浏览器看到:
然后看它的源代码:
但是跟上面不同的是,这两个jsp只转换成一个servlet 可看下面:
这就解释了为什么要删除一个路径,因为两个路径的话,会造成冲突。
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
那么转换后的bq_Include_jsp.java是怎么样的?
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2015-08-05 07:59:16 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp.Biaoqian;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
import java.util.*;
public final class bq_005fInclude_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
static {
_jspx_dependants = new java.util.HashMap<java.lang.String,java.lang.Long>(1);
_jspx_dependants.put("/Biaoqian/bq_Include_header.jsp", Long.valueOf(1438761477571L));
}
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write("\r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" ");
//这是jsp标签技术实现的
//<jsp:include page="bq_Include_header.jsp"></jsp:include>
out.write("\r\n");
out.write(" \r\n");
out.write(" ");
//这是java代码实现的
out.write("\r\n");
out.write(" ");
//request.getRequestDispatcher("bq_Include_header.jsp").include(request,response);
out.write("\r\n");
out.write(" ");
out.write('\r');
out.write('\n');
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" <h1>这是头部</h1>\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write(" <h3>这是主体</h3>\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
jsp标签include和jsp指令include的区别
其实从上面已经知道了jsp标签include将两个jsp变成两servlet
而jsp指令include则是合成一个servlet,这就说明两个jsp页面中不能有相同的变量,以免合成一个servlet的时候造成冲突。
如下面,先用jsp标签
新建一个Include02.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<jsp:include page="Include02_header.jsp"></jsp:include>
<%!
int i=10;
%>
<h1>Include02.jsp中i的值为:<%=i%></h1>
</body>
</html>
上面的Include0_header.jsp为:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%!
int i=100;
%>
<%="Include02_header的i是:"+i %>
</body>
</html>
因为上面的两个jsp不会合并成一个servlet,所以有相同的变量不会报错,可以输出:
但是如果用jsp指令include改写Include02.jsp的话:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%@include file="Include02.jsp"%>
<%!
int i=10;
%>
<h1>Include02.jsp中i的值为:<%=i%></h1>
</body>
</html>
上面则会报错
2.2<jsp:forward>标签
<jsp:forward>标签的作用是实现请求转发的
下面是案例入门,新建一个forward01.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<jsp:forward page="/Biaoqian/forward01_tiao.jsp"></jsp:forward>
</body>
</html>
然后将其转发到forward01_taio.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>这是跳转后的页面</h1>
</body>
</html>
在浏览器输入:http://localhost/Day06/Biaoqian/forward01.jsp ,这时候就会跳转了,如下:
源代码:
上面的地址栏没有变,是因为这是服务器端的跳转,而服务器端的跳转不会影响地址栏
下面用java代码来实现请求转发
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%
request.getRequestDispatcher("/Biaoqian/forward01_tiao.jsp").forward(request, response);
%>
</body>
</html>
浏览器显示:
这跟jsp标签相似。
注:不能用jsp指令来实现,因为常见的指令没有这个功能。
三大指令没有跳转功能。
2.3 <jsp:param>标签
作用是配合上面的使用,传递参数。
<jsp:param>和<jsp:include>的结合
案例:
param01.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%="这是主体" %>
<jsp:include page="param01_include.jsp">
<jsp:param name="param1" value="name"/>
<jsp:param name="param2" value="age"/>
</jsp:include>
</body>
</html>
param01_include.jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h2>param1= <%=request.getParameter("param1") %></h2>
<h2>param2= <%=request.getParameter("param2") %></h2>
</body>
</html>
在浏览器中输入:http://localhost/Day06/Biaoqian/param01.jsp,可显示
但是如果将name age改为中文的话,那么就会导致乱码
这是为什么?(待解)
<jsp:param>和<jsp:forward>的结合
只要将上面的param01.jsp 改为forward_param02.jsp即可:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<jsp:forward page="/Biaoqian/param01_include.jsp">
<jsp:param name="param1" value="name"/>
<jsp:param name="param2" value="age"/>
</jsp:forward>
</body>
</html>
运行后在浏览器可以显示: