首页 > 代码库 > JAVAWEB开发之Session的追踪创建和销毁、JSP详解(指令,标签,内置对象,动作即转发和包含)、JavaBean及内省技术以及EL表达式获取内容的使用

JAVAWEB开发之Session的追踪创建和销毁、JSP详解(指令,标签,内置对象,动作即转发和包含)、JavaBean及内省技术以及EL表达式获取内容的使用

 Session的追踪技术

已知Session是利用cookie机制的服务器端技术,当客户端第一次访问资源时 如果调用request.getSession() 就会在服务器端创建一个由浏览器独享的session空间,并分配一个唯一且名称为JSESSIONID的cookie发送到浏览器端,如果浏览器没有禁用cookie的话,当浏览器再次访问项目中的Servlet程序时会将JSESSIONID带着,这时JSESSIONID就像唯一的一把钥匙  开启服务器端对应的session空间,进而获取到session中的内容(Session没有失效的情况下)。之所以第一次访问会创建与浏览器对应的一个Session空间,是因为第一次访问浏览器是不会携带对应的JSESSIONID,凡是不带有JSESSIONID的访问 调用request.getSession()方法都会为客户端创建一个session空间。
  当浏览器客户端禁用了cookie之后,浏览器端就无法保存JSESSIONID,就无法使用session。不是说服务器端的Session空间丢失了,而是在服务器端找到打开对应Session空间的钥匙(JSESSIONID)丢失了。这时就需要使用Session的追踪技术。
  session的销毁:
(1)非正常关闭服务器。注意:非正常关闭服务器是不会序列化session到本地的。会导致session丢失。
(2)手动正常关闭服务器。不会导致session丢失(正常关闭服务器后,会在服务器中将session存储起来,再次启动服务器的时候 会被重新加载到内存中)
(3)session的过期,默认是30分钟(在不关闭浏览器的情况下) 可以在服务器的web.xml文件中进行设置
         <session-config>
<session-timeout>30</session-timeout>
</session-config>
    注意:关闭浏览器 后重新访问无法获取session内容 并不是因为session被销毁 而是session只是一次会话,其客户端的JSESSIONID是保存在内存里的,关闭浏览器后JSESSIONID在内存里被释放。
(4)调用session.invalidate() 手动销毁session 。
示例如下:
  SessionDemo1.java    路径:/session1
public class SessionDemo1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// session域对象
		HttpSession session = request.getSession();
		session.setAttribute("username", "小风");
		// DD64756D56885AF87E883B887BF77E6C		jsessionid=DD64756D56885AF87E883B887BF77E6C
		System.out.println(session.getId());
		
		response.sendRedirect("/day12/session2");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

SessionDemo2.java  /session2
package cn.itcast.session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo2 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 手动传入jsessionid=DD64756D56885AF87E883B887BF77E6C	
		HttpSession session = request.getSession();
		String username = (String) session.getAttribute("username");
		
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write("<h4>访问到了..."+username+"</h4>");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
技术分享

技术分享

正常关闭服务器
技术分享

重新启动服务器 session又被反序列化到内存中
技术分享

禁用浏览器的cookie之后
技术分享

重新访问:
技术分享

发现cookie被浏览器被禁用之后,无法获取session空间的内容。可以使用cookie追踪技术,就是在跳转路径后加上;jsessionid=DE3D5641D0D1D248D66C7A3D67E47F8E 访问路径即http://localhost/day12/session2;jsessionid=DE3D5641D0D1D248D66C7A3D67E47F8E 效果如下:
技术分享
session的域对象:
ServletContext:代表整个web应用,数据库连接
session:一次会话,存放个人信息
request:一次请求,存放错误处理

JSP设置与页面的注释

(1)设置JSP文件的打开方式(以便快速打开)window -- 选项 -- General -- Editors -- 文件关联 -- *.jsp -- 选择MyEclipse JSP Editor -- default
技术分享
(2)设置JSP的编码(用于显示中文)window -- 搜索JSP -- 找到JSP -- 选择UTF-8 -- OK
技术分享

JSP页面的注释:
(1)HTML的注释 <!--  -->  JSP文件的阶段存在,在翻译成Java文件后也存在,在页面也存在。
(2)Java的注释     JSP文件的阶段存在,在翻译成Java文件也存在,在页面不存在。
     <%
          //       单行
          /**/    多行
         /**
          *        文档注释
          */
     %>
(3)JSP的注释   <%--  JSP的注释  --%>   只存在于JSP文件阶段。

JSP指令元素

功能:用于指示JSP执行某些步骤 或用于指示JSP表现特定行为。
语法格式:<%@ directive [attribute="value"]*%>   即 <%@  指令元素  属性名=属性值  %>
分类:page指令标记、include指令标记、taglib指令标记

page指令标记

(1)page属性包含在" <%@ page " 和 "%>" 之间。
(2)这些属性可以单独使用,也可以几个或多个同时使用。
(3)在JSP页面中,只有import可以出现多次,其他属性都只能出现一次。
page指令属性:
  • language:声明使用脚本的种类,即JSP文件运行嵌入的语言。目前只支持Java一种语言(不需要改变)例如:language="java"
  • extends:JSP翻译成Servlet的Java文件时,Servlet继承的类(不需要改变)例如:extends="src.class"
  • session:例如session="true",指定一个Http会话是否使用session对象,默认值是true 可以直接使用session。设置成false不能直接使用session(如果设置成false 要想获取session  只能使用Java代码  <%  HttpSession session2 = request.getSession()  %>)
  • import: 用于导入Java包或类的列表 (可以使用后多次  import="java.util.Date")
  • buffer:指定JSP对客户端输出缓冲区的大小,默认是8kb  (buffer="8k")
  • autoFlush:设置默认自动刷新缓冲区(不需要改变),如果buffer溢出,设置成true时正常输出,设置成false时 出现异常 (autoFlush="true")
  • errorPage: 处理异常事件时调用的JSP页面 ,指定错误页面 (errorPage="error.jsp")
  • isErrorPage:设置此页是否可以为其它页的errorPage目标 (设置值为true,可以是exception对象,设置成false不能使用exception对象)
  • contentType:定义JSP页面响应的MIME类型(指定服务器端输出所有内容采用的编码 contentType="text/html,charset=utf-8")
  • pageEncoding:JSP页面字符编码,其优先权高于contentType(JSP翻译成Servlet文件时采用的编码 pageEncoding="gb2312")
  • isELIgnored:用于指定EL(表达式语言)是否被忽略。true则忽略,false则计算表达式的值 (isELIgnored="false")
 重点:session  import contentType  pageEncoding  isELIgnored

配置全局的错误页面

在项目中的web.xml中进行配置:
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
<error-page>
<error-page>
     <error-code>500</error-code>
     <location>/500.jsp</location>
</error-page>
注意:所有的请求出现错误后 都会跳转到对应的错误页面。errorPage属性的优先级大于全局错误页面的优先级。如果一个JSP的page指令属性后指定了errorPage属性,出现了错误的话,会跳转到errorPage指定的页面。

在WebRoot下新建jsp的文件夹,在jsp文件夹下新建demo.jsp、error.jsp, 在WebRoot根目录下下新建全局的错误页面404.jsp、500.jsp 进行测试page指令有关的属性
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true" %>
<!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>
	
	<h3>亲,服务器正在维护!!</h3>

<%=exception.getMessage() %>	


</body>
</html>

404.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>Insert title here</title>
</head>
<body>
	
	<h3>亲,您访问的资源恋爱了,不在服务区!!</h3>
	
</body>
</html>
500.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>Insert title here</title>
</head>
<body>
	
	<h3>亲,服务器正在维护,这回是真的维护!!</h3>
	
</body>
</html>

demo.jsp
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="true" buffer="8kb" autoFlush="true" 
    errorPage="/jsp/error.jsp" isELIgnored="false"%>

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

<h4>欢迎</h4>

<%
	List list = new ArrayList();	
	// int a = 10 / 0;
	request.setAttribute("username", "小风");
%>

<!-- HTML的文本 -->
${ username }

</body>
</html>

首先测试errorPage属性,屏蔽demo.jsp代码中除了 int a=10/0; 以外的代码 运行结果如下:
技术分享
去掉demo.jsp中page指令中的errorPage属性 再次运行
技术分享

如果访问的路径错误 会跳转到全局的404错误页面
技术分享


屏蔽错误代码 运行如下:
技术分享
将demo.jsp 中page属性中的isELIgnored设置为true 运行如下:

技术分享

include指令标记

include指令的语法格式如下:<%@ include file="filename"%>   <%@ include file="要包含文件(静态包含)" %>
include指令的作用是在jsp页面中静态包含一个文件,同时由JSP解析包含的文件内容。
静态包含的含义:
  file不能为一变量
       <% String url="index.html" %>
       <%@ include file="<%= url %>" %>
  不可以在file所指定的文件后接任何参数
       <%@ include file = "jw.jsp?nm=browser" %>
静态包含举例:
     包含的是目标文件的源码;包含过来,一起翻译
main.jsp
      <%
 String s = “abc”;
      %>
      <%include file=“part.jsp” %>
part.jsp
      <%=s %> 没有定义变量s
尽管part.jsp本身会有错误
但是运行main.jsp就可以正确引入part.jsp
测试include,在WebRoot中新建include文件夹,在include文件夹内新建body.jsp、head.jsp、foot.jsp、menu.jsp
body.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>    

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

<%@ include file="/include/head.jsp" %>
<%@ include file="/include/menu.jsp" %>
	<h3>网站的新闻(数据变化)</h3>
<%@ include file="/include/foot.jsp" %>


</body>
</html>
head.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    


<h3>网站的LOGO</h3>
<%  int a = 100; %>	

menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

	<h3>网站的超链接</h3>
<%= a %>
foot.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h3>网站的友情链接</h3>

运行结果:
技术分享
打开Tomcat服务器中的工作目录:
技术分享

静态包含的原理是把 所包含的文件内容完全复制到一块,然后进行翻译成一个jsp文件,编译运行
技术分享

JSP九大内置对象

     request  response session application out  pageContext  page  config  exception
内置对象真实的对象方法
requestHttpServletRequestsetAttribute()   getAttribute()
responseHttpServletResponseaddCookie()   getWriter()
sessionHttpSessionsetAttribute()   getAttribute()
applicationServletContextsetAttribute()   getAttribute()
configServletConfiggetInitParameter()   getInitParameterNames()
exceptionThrowable(所有的异常父类)getMessage()
pageObject (当前的Servlet对象 this(HttpServlet))
outJspWriterwrite()    print()
pageContextPageContextsetAttribute()   getAttribute()
具体可以查看 由JSP翻译成的Servlet对象 查看如下:
技术分享

exception对象:
(1)exception对象是java.lang.Throwable
(2)(使用前 isErrorPage="true")
(3)exception对象用来处理JSP文件在执行时所有发生的错误和异常
(4)exception对象可以和page指令一起使用,通过指定某一个页面为错误处理页面,对错误进行处理
       <%@ page isErrorPage=true %>  的页面内使用

page对象(Servlet对象)
  • "page" 对象代表了正在运行的由JSP文件产生的类对象(一般不建议使用)
  • page对象是指向当前JSP程序本身的对象this
  • page对象其实是java.lang.Object类的实例对象
out对象
  • 向客户端输出数据
  • 管理服务器输出缓冲区
  • 内部使用PrintWriter对象来输出文本级数据
  • 通过page指令的buffer属性来调整缓冲区的大小,默认的缓冲区是8kb
技术分享
JSPWriter        PrintWriter  response.getWriter()
技术分享
程序实例如下:在jsp文件夹下新建out.jsp
out.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>Insert title here</title>
</head>
<body>

<!-- BBBB HELLO AAAA CCCC -->
<%= "HELLO" %>
<% out.print("AAAA"); %>
<% response.getWriter().print("BBBB"); %>
<% out.print("CCCC"); %>

</body>
</html>

运行结果如下:
技术分享
查看最后返回的页面源代码如下:

技术分享

技术分享

pageContext对象
pageContext对象也是域对象,代表当前的页面范围,在当前的页面范围内获取数据。
向JSP的四个作用域范围内存数据。
    Servlet中有三个域,而JSP中有四个域
    JSP中多了多了pageCOntext的域范围,代表当前页面范围。
域对象
    自己存取值 setAttribute(String name, Object value)
    向其他的域存取值
          setAttribute(String name,Object value, int scope)
          getAttribute(String name,int scope)
          findAttribute(String name)
获取其它8个内置对象
   编写框架、通用性较高的代码。

pageContext中的方法:
    setAttribute(String name, Object value)
    setAttribute(String name, Object value, int scope)
    getAttribute(String name)
    getAttribute(String name, int scope)
    removeAttribute(String name)
    removeAttribute(String name, int scope)
    findAttribute(String name)

通过pageContext对象获得其它对象:
getException方法返回exception隐式对象
getPage方法返回page隐式对象
getRequest方法返回request隐式对象
getResponse方法返回response隐式对象
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象
getOut方法返回out隐式对象
实例如下:
<%@ 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>

<%=request.getParameter("username") %>

<h4>pageContext向其他域中存入值</h4>	
<%
	pageContext.setAttribute("name", "美美");
	// 下面这句等价于上面
	pageContext.setAttribute("name", "美美", pageContext.PAGE_SCOPE);
	
	request.setAttribute("name", "小凤");
	// 向request域中存入值
	pageContext.setAttribute("name", "小凤", pageContext.REQUEST_SCOPE);
	
	// 向session域存入值
	pageContext.setAttribute("name", "小苍", pageContext.SESSION_SCOPE);
	// 向ServletContext域存入值
	pageContext.setAttribute("name", "小班长", pageContext.APPLICATION_SCOPE);
	
%>

<%= pageContext.getAttribute("name", pageContext.SESSION_SCOPE)%>
<%= session.getAttribute("name") %>


${ pageScope.name }
${ requestScope.name }
${ sessionScope.name }
${ applicationScope.name }

</body>
</html>
技术分享

   JSP标签

JSP标签也称之为JSP Action(jsp动作)元素,它用于在JSP页面中提供业务逻辑代码,避免在JSP页面中直接编写Java代码,造成jsp页面难以维护。
<jsp:useBean> 使用一个ID和一个给定作用范围和同一ID的JavaBean相关联。
<jsp:setProperty> 设置JavaBean的属性值
<jsp:getProperty> 取得JavaBean的属性值
<jsp:include> 文件包含(服务器端路径,没有项目名称)
<jsp:forward>  在JSP页面中完成转发(服务器端路径,没有项目名称)
<jsp:param> 需要写在 <jsp:forward>的中间

<jsp:forward> 和 <jsp:param>

将请求传递给另一个JSP页面    <jsp:forward  page="转发路径" />
<jsp:param> 用来传递参数,可以写在<jsp:forward>中间,可以使用request.getParameter(); 来接收参数。
<jsp:forward>之后的代码不执行
语法格式如下:
    <jsp:forward page={"relativeURL" | "<%= expression %>"} />
    <jsp:forward page={"relativeURL" | "<%= expression %>"} >
<jsp:param name="PN" value=http://www.mamicode.com/"{PV | "}/> *
    </jsp:forward>
在Servlet中如果使用request.getRequestDispatcher.forward进行页面跳转,那么该语句以后的代码会执行:
request.getRequestDispatcher.forward(“XXX”);
System.out.println(“It can execute…”);
但是JSP中<jsp:forward>后面的代码不会执行,因为翻译的时候,Serlvet容器自动为<jsp:forward>后面添加了return语句,例如:
<%
String s=request.getRemoteAddr();
if(s.startsWith("10.28.176.",0)){
%>
    <jsp:forward page="index_inner.jsp"/>
    <%}else{ %>
    <jsp:forward page="index_outter.jsp"/>
<%
}
%>

<jsp:include>与include指令的比较

  • <jsp:include>标签是动态引入,<jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个Servlet的内容在执行时进行合并。
  • 而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个Servlet,其内容是在源文件级别进行合并。
  • 不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
技术分享
include两种用法的区别:
主要有两个方面的不同:
(1)执行时间上
    <%@ include file="relativeURI" %> 是在翻译阶段执行
    <jsp:include  page="relativeURI"  flush="true" />
(2)引入的内容不同
    <%@  include  file="relativeURI" %> 引入静态文本(html, jsp),在JSP页面被转化成Servlet之前和它融合在一起。
    <jsp:include page="relativeURI"  flush="true" /> 引入执行页面或Servlet所生成的应答文本。另外两种方法中的file和page属性都被翻译成一个相对的URI。如果它以斜杠开头,那么它就是一个环境相关的路径,将根据赋给应用程序的URI的前缀进行解释;如果它不是以斜杠开头,那么就是页面相关的路径,就根据引入这个文件的页面所在的路径进行解释。
举例说明两种包含的区别:
技术分享
如果被包含的JSP页面有错误的话,静态包含是无法编译执行的。而动态包含则不受影响。
实例验证动态包含和<jsp:forward>
在WebRoot下新建action的文件夹,在action文件夹中新建body.jsp、head.jsp、menu.jsp、foot.jsp
head.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
	int a = 10;
%>

<%= a %>
<h3>网站的LOGO</h3>
	
menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

	<h3>网站的超链接</h3>
foot.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h3>网站的友情链接</h3>
body.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<jsp:include page="/action/head.jsp"></jsp:include>
<jsp:include page="/action/menu.jsp"></jsp:include>

<h3>网站的新闻(数据变化)</h3>
<jsp:include page="/action/foot.jsp"></jsp:include>

</body>
</html>
运行结果如下:
技术分享
打开服务器中的工作目录查看如下:
技术分享
原理如下:
技术分享
接着测试 <jsp:forward> 在action文件夹下新建forward.jsp
forward.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>Insert title here</title>
</head>
<body>

<h4>JSP的动作标签</h4>
<jsp:forward page="/jsp/pageContext.jsp">
	<jsp:param name="username" value=http://www.mamicode.com/"meimei"/>>运行结果:
技术分享

JavaBean及内省

什么是JavaBean?
(1)JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
        这个Java类必须具有一个无参的构造函数
        属性私有化
        私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范。
(2)JavaBean在J2EE开发中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其他程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用属性保存数据。

JavaBean的属性:
  • JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有setter、getter方法,setter方法称为属性的修改器,getter方法称为属性访问器。
  • 属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要大写,例如,name属性的修改器名称为setName,password属性修改器名称为setPassword
  • 属性访问器通常以小写的get前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name属性访问器名称为getName,password属性访问器是getPassword
  • 一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。(JavaBean的属性不是由对象中定义的变量决定的,是由get或者set方法决定的)
在JSP中使用JavaBean:
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分为如下几种。
<jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
<jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
<jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
编写表单页面,把数据提交到另一个JSP的页面,可以使用传统方式封装数据,也可以使用<jsp:useBean>来封装数据。设置属性是<jsp:setProperty name="u"  property="*"> *代表所有的属性。

<jsp:useBean>标签
<jsp:useBean>标签用于在指定的域范围内查找指定名称的JavaBean对象:
     如果存在则直接返回该JavaBean对象的引用。
    如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围内
常用语法:
   <jsp:useBean  id="beanName"  class="cn.itcast.Test"  scope="" />
   id 属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
   class属性用于指定JavaBean的完整类名(即必须带包名)
   scope属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session、application等四个值中的一个,其默认值是page。
<jsp:useBean>执行原理:
<jsp:useBean id="currentDate" class="java.util.Date"/>
翻译成的Servlet源码:
java.util.Date currentDate = null;
synchronized (_jspx_page_context) {
currentDate = (java.util.Date)        _jspx_page_context.getAttribute(
"currentDate", PageContext.PAGE_SCOPE);
if (currentDate == null){
currentDate = new java.util.Date();
_jspx_page_context.setAttribute("currentDate",
currentDate, PageContext.PAGE_SCOPE);
}
}
带标签体的<jsp:useBean>标签
语法:
<jsp:useBean...>
    Body
</jsp:useBean>
功能:Body部分的内容只在<jsp:useBean> 标签创建JavaBean的实例对象时才执行。

<jsp:setProperty>标签
<jsp:setProperty>标签用于设置和访问JavaBean对象的属性
语法格式:
<jsp:setProperty name="beanName"
{
    property="propertyName"  value=http://www.mamicode.com/"{string | }" |
    property="propertyName"  [ param="perameterName" ]  |
    property="*"
}
/>
 name 属性用于指定JavaBean对象的名称。
 property属性用于指定JavaBean实例对象的属性名。
 value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相关的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。
param 属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性的值同样会自动转换成要设置的JavaBean属性的类型。

<jsp:getProperty>标签
<jsp:getProperty>标签用于读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。
语法:
<jsp:getProperty  name="beanInstanceName"  property="PropertyName" />
   name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean>标签的id属性值相同。
   property属性用于指定JavaBean实例对象的属性名。
如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容是null的字符串。

内省(Introspector)——JavaBean

访问JavaBean属性的两种方式:
直接调用bean的setXXX或getXXX方法
通过内省技术访问(java.beans包提供了内省的API)
  内省技术是基于反射技术的
  通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。
关键代码示例:
public void populate(Map<String, String[]> map, User user) throws Exception {
BeanInfo info = Introspector.getBeanInfo(user.getClass());
PropertyDescriptor [] pds = info.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
String attrName = pd.getName();
if(map.containsKey(attrName)){
Method m = pd.getWriteMethod();
m.invoke(user, map.get(attrName)[0]);
}
}
}
在src下新建cn.itcast.test包,在包内新建InstrospectorTest.java测试类
package cn.itcast.test;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.itcast.vo.User;

/**
 * 测试类
 * @author Administrator
 *
 */
public class IntrospectorTest {
	
	@Test
	public void run() throws Exception{
		User user = new User();
		// 获取类的信息
		BeanInfo info = Introspector.getBeanInfo(user.getClass());
		// 获取属性的描述
		PropertyDescriptor [] pds = info.getPropertyDescriptors();
		// 循环遍历,获取属性的名称
		for (PropertyDescriptor pd : pds) {
			// System.out.println(pd.getName());
			if(!"class".equals(pd.getName())){
				// 获取写的方法
				Method m = pd.getWriteMethod();
				m.invoke(user, "admin");
			}
		}
		
		System.out.println(user.getUsername());
		System.out.println(user.getPassword());
	}
}
技术分享

运行结果:
技术分享

内省—— beanutils工具包
需求:虽然JDK中的内省技术可以实现基本数据类型比如(String、float等)Bean属性的映射,但是对于别的类型例如Date日期类都不能进行映射。
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。
使用步骤:
    首先导入需要使用的两个jar包(commons-beanutils-xxx.jar和commons-logging-xxx.jar)
Beanutils工具包的常用类:
    BeanUtils
            populate(Object bean, Map properties)
    自定义转换器
            ConvertUtils.register(Converter convert, Class clazz)
            传入日期类型的Date.class
实现默认把字符串转换成日期类型
     编写一个类,实现Converter接口。重写该方法。把字符串转换日期。
     在封装数据之前进行注册。ConvertUtils.register(Converter  converter, Class clazz)      Date.class
关键代码如下:
public class MyConvert implements Converter{

/**
 * 实现转换的方法
 * clazz:类型
 * obj:输入的内容
 */
public Object convert(Class clazz, Object obj) {
String sDate = (String)obj;
// 把字符串转换成日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date;
try {
date = sdf.parse(sDate);
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("日期转换错误");
}
return date;
}
}

// 进行日期转换注册
ConvertUtils.register(new MyConvert(), Date.class);
程序实例如下:
在src下新建cn.itcast.vo包(用来存储Bean类)在里面新建User.java Bean类
package cn.itcast.vo;

import java.util.Date;

/**
 * User的JavaBean
 * @author Administrator
 *
 */
public class User {
	
	private String username;
	private String password;
	private double money;
	private Date birthday;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	
}
在src下新建cn.itcast.utils包(工具类) 在里面新建MyDateConverter.java 类(用于注册其他类型的Bean)
MyDateConverter.java
package cn.itcast.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.Converter;

/**
 * 字符串转换日期类
 * @author Administrator
 *
 */
public class MyDateConverter implements Converter{

	/**
	 * 字符串转换成日期
	 */
	public Object convert(Class clazz, Object obj) {
		// 把输入的字符串,转换成日期类型,返回
		String dDate = (String) obj;
		// 把字符串转换成日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
		try {
			date = sdf.parse(dDate);
		} catch (ParseException e) {
			e.printStackTrace();
			throw new RuntimeException("转换日期错误");
		}
		return date;
	}

}
在src下新建cn.itcast.servlet包,在包内新建UserServlet.java类(实现内省)和UserBeanUtilServlet.java(实现日期属性为Bean赋值)
UserServlet.java    路径:/user
package cn.itcast.servlet;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.vo.User;

/**
 * 获取请求参数,封装数据
 * @author Administrator
 *
 */
public class UserServlet extends HttpServlet {
	
	private static final long serialVersionUID = 6390620317553505800L;
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 获取请求参数,创建User对象,设置值。
		/**
		 * 
		 * 	// 获取表单的内容
			String username = request.getParameter("username");
			String password = request.getParameter("password");
			// 创建User对象,set设置值
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);
		 */
		
		// 获取输入的数据
		Map<String, String []> map = request.getParameterMap();
		// 创建User对象
		User user = new User();
		// 自己编写封装数据的方法
		try {
			populate(map,user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// 完成数据封装
		System.out.println(user.getUsername());
		System.out.println(user.getPassword());
	}
	
	/**
	 * 完成的数据
	 * @param map
	 * @param user
	 * @throws Exception 
	 */
	private void populate(Map<String, String[]> map, User user) throws Exception {
		BeanInfo info = Introspector.getBeanInfo(user.getClass());
		// 获取属性的描述
		PropertyDescriptor [] pds = info.getPropertyDescriptors();
		// 循环遍历
		for (PropertyDescriptor pd : pds) {
			// 获取到属性的名称
			String name = pd.getName();
			// map的key	
			if(map.containsKey(name)){
				// 获取属性的写的方法
				Method m = pd.getWriteMethod();
				// 执行之
				m.invoke(user, map.get(name)[0]);
			}
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
UserBeanUtilServlet.java   /userBeanUtil
package cn.itcast.servlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import cn.itcast.utils.MyDateConverter;
import cn.itcast.vo.User;

/**
 * 使用BeanUtils完成数据的封装
 * @author Administrator
 *
 */
public class UserBeanUtilServlet extends HttpServlet {

	private static final long serialVersionUID = 3625882115495534032L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取数据
		Map<String, String []> map = request.getParameterMap();
		// 创建User对象
		User user = new User();
		
		// 完成注册
		ConvertUtils.register(new MyDateConverter(), Date.class);
		
		// 完成封装
		try {
			BeanUtils.populate(user, map);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		// 打印
		System.out.println(user.getUsername());
		System.out.println(user.getPassword());
		System.out.println(user.getMoney());
		System.out.println(user.getBirthday());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
在WebRoot下新建文件夹bean文件夹,在文件夹下新建login.jsp 和success.jsp文件
login.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>Insert title here</title>
</head>
<body>

<h4>表单提交到JSP的页面</h4>
<form action="/day12/bean/success.jsp" method="POST">
	姓名:<input type="text" name="username" /><br/>
	密码:<input type="password" name="password" /><br/>
	<input type="submit" value=http://www.mamicode.com/"登陆"/>>success.jsp ( <jsp:setProperty>等指令实现bean的赋值)
<%@page import="cn.itcast.vo.User"%>
<%@ 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>

<h3>传统方式封装数据</h3>
<%
	// 获取表单的内容
	String username = request.getParameter("username");
	String password = request.getParameter("password");
	// 创建User对象,set设置值
	User user = new User();
	user.setUsername(username);
	user.setPassword(password);
%>

<!-- 使用jsp的标签封装数据 -->
<jsp:useBean id="u" class="cn.itcast.vo.User"></jsp:useBean>
<jsp:setProperty property="*" name="u"/>

<jsp:getProperty property="username" name="u"/>
<jsp:getProperty property="password" name="u"/>

</body>
</html>

技术分享
跳转后如下:
技术分享

EL表达式简介(运算及获取数据和web开发常用对象)

EL全名为Expression Language。EL主要作用:

  • 获取数据EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域中检索Java对象、获取数据(某个web域中的对象,访问JavaBean的属性、访问list集合、访问map集合、访问数组)
  • 执行运算利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以及在jsp页面中完成一些简单的逻辑运算。${user==null}
  • 获取web开发常用对象:EL表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松的获取对web常用对象的引用,从而获取这些对象中的数据。
  • 调用Java方法:EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
EL表达式注意事项:
EL表达式是JSP 2.0(JavaEE1.4)规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
注意:有些Tomcat服务器如果不能使用EL表达式,解决方法如下:
(1)升级成Tomcat6
(2)在JSP中加入 <%@  page  isELIgnored="false"  %>

EL获取数据(一)
  • 使用EL表达式获取数据的语法:${标识符}
  • EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应的对象,找不到则返回 "" (注意:不是null而是空字符串)
  • 示例:${user}

EL获取数据(二)
EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
 ${user.address.city}
${ user.list[0] }:访问有序集合某个位置的元素。
${ map.key }:获得map集合中指定key的值
[]和. 的区别:
数组或List有下标这种使用[],获得对象的属性的值的时候使用 .  如果属性中有特殊字符,需要使用[], 例如:map.put("ddd.eee","老师");——${ map["ddd.eee"] }

EL执行运算(三)
语法:${运算表达式},EL表达式支持如下运算符:
关系运算符说明范例结果
== 或eq等于${ 5 == 5 } 或${ 5 eq 5 }true
!=  或 ne不等于${ 5 != 5 }  或 ${ 5 nq 5}false
<  或 lt小于${ 3 < 5 } 或 ${ 3 lt  5 }true
>  或 gt大于${ 3 > 5 } 或 ${ 3 gt 5 }false
<= 或 le小于等于${ 3 <= 5 } 或 ${ 3 le 5 }true
>= 或 ge大于等于${ 3 >= 5 } 或 ${ 3 ge 5 }false

逻辑运算符说明范例结果
&& 或 and交集${ A && B }  或 ${ A and B }true/false
||  或 or并集${ A || B }  或 ${ A or B }true/false
!  或 not${ !A }  或 ${ not A }true/false

empty运算符:检查对象是否为null 或 "空"
二元表达式:${ user != null?user.name:""}
关键代码:
<%
request.setAttribute("n1", 10);
request.setAttribute("n2", 20);
request.setAttribute("n3", 30);
request.setAttribute("n4", 40);
%>

<h3>算术运算</h3>
${ n1 + n2 }

<h3>关系运算</h3>
${n1 > n2 }${n1 gt n2 }<br/>
${n1 < n2 }${n1 ltn2 }<br/>
${n1 >= n2 }${n1 gen2 }<br/>
${n1 <= n2 }${n1 len2 }<br/>
${n1 == n2 }${n1 eqn2 }<br/>
${n1 != n2 }${n1 nen2 }<br/>

<h3>逻辑运算</h3>
${n1>n2 && n3>n4 }${n1>n2 and n3>n4 }<br/>
${n1>n2 || n3>n4 }${n1>n2 or n3>n4 }<br/>
${ !(n1>n2) }${not (n1>n2)}<br/>
EL表达式保留关键字
技术分享

所谓保留字的意思是指变量在命名时,应该避开上述的名字,以免程序编译时发生错误。

EL表达式获得WEB开发常用对象:
EL表达式语言中定义了11个隐式对象,使用这些隐含对象可以很方便的获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${ 隐式对象 }:获取对象的引用
 
隐含对象名称描述
pageContext对应于JSP页面中的pageContext对象(注意:取得是pageContext对象)
pageScope代表page域中用于保存属性的Map对象
requestScope代表request域中用于保存属性的Map对象
sessionScope代表session域中用于保存属性的Map对象
applicationScope代表application域中用于保存属性的Map对象
param表示一个保存了所有请求参数的Map对象
paramValues表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个String[]
header表示一个保存了所有http请求字段的Map对象
headerValues同上,返回String[] 数组。注意:如果头里面有"-" ,例如:Accept-Encoding,则
要使用headerValues["Accept-Encoding"]
cookie表示一个保存了所有cookie的Map对象
initParam表示一个保存了所有web应用初始化参数的map对象
param相当于request.getParameter();
paramValues相当与request.getParameterValues();
${cookie.name.name} ${cookie.name.value}
测试各个隐式对象
注意事项:
  测试headerValues时,如果头里面有"-",例如Accept-Encoding,则要headerValues["Accept-Encoding"]
  测试cookie时,例${cookie.key} 取的时cookie对象,如访问cookie的名称和值,须${cookie.key.name} 或${cookie.key.value}
 
实例如下:
在WebRoot下新建  el文件夹。在文件夹内新建jsp进行验证:
elDemo1.jsp
<%@page import="cn.itcast.vo.User2"%>
<%@page import="cn.itcast.vo.User"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ 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>

<h4>获取域对象中的值</h4>
<%
	pageContext.setAttribute("name", "黄海波");
	request.setAttribute("name", "美美");
%>

${ pageScope.name }
${ requestScope.name }


<h4>域中数组的值</h4>
<%
	String [] arrs = {"美美","波波","东东","名名"};
	request.setAttribute("arrs", arrs);
%>
${ arrs[2] }

<h4>域中集合的值</h4>
<%
	List<String> list = new ArrayList<String>();
	list.add("美美");
	list.add("小凤");
	list.add("芙蓉");
	request.setAttribute("list", list);
%>
${ list[1] }

<h4>域中Map集合的值</h4>
<%
	Map<String,String> map = new HashMap<String,String>();
	map.put("aa", "美美");
	map.put("bb", "小凤");
	request.setAttribute("map", map);
%>
${ map.bb }


<h4>域中集合中有对象的值</h4>
<%
	List<User2> uList = new ArrayList<User2>();
	uList.add(new User2("banzhang","123"));
	uList.add(new User2("美美","abc"));
	request.setAttribute("uList", uList);
%>
${ uList[1].username }

</body>
</html>
运行结果:
技术分享

注意:如果name前没有指定范围 ${name}  , 会默认从域范围从小到大进行查找 先从pageScope—> requestScope—>sessionScope —>applicationScope

elDemo2.jsp (EL进行算术和逻辑运算)
<%@ 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>

<h4>EL的运算</h4>
<%
	request.setAttribute("n1", 10);
	request.setAttribute("n2", 20);
	request.setAttribute("n3", 30);
	request.setAttribute("n4", 40);
%>
<h4>加法运算</h4>
${ n1 + n2 }

<h3>关系运算</h3>
<h4>大于</h4>
${ n1 > n2 }	${ n1 gt n2 }

<h4>小于</h4>
${ n1 < n2 }	${ n1 lt n2 }

<h4>等于</h4>
${ n1 == n2 }	${ n1 eq n2 }

<h4>不等于</h4>
${ n1 != n2 }	${ n1 ne n2 }

<h4>大于等于</h4>
${ n1 >= n2 }	${ n1 ge n2 }

<h4>小于等于</h4>
${ n1 <= n2 }	${ n1 le n2 }

<h3>逻辑运算</h3>
<h4>与</h4>
${ n1 > n2 && n3 > n4 }		${ n1 > n2 and n3 > n4 }

<h4>或</h4>
${ n1 > n2 || n3 > n4 }		${ n1 > n2 or n3 > n4 }

<h4>非</h4>
${ !(n1 > n2) }		${ not (n1 > n2) }

</body>
</html>
结果:
技术分享

elDemo3.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>Insert title here</title>
</head>
<body>

<h4>EL的运算</h4>
<form action="/day12/el/elDemo4.jsp" method="POST">
	姓名:<input type="text" name="username" /><br/>
	<input type="submit" value=http://www.mamicode.com/"登陆"/>>

elDemo4.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>Insert title here</title>
</head>
<body>

<h4>EL的WEB对象</h4>
${ param.username }

<h4>获取请求头</h4>
${ header.referer }

<h4>获取全局初始化参数</h4>
${ initParam.username }


<h4>pageContext对象</h4>
${ pageContext.request.contextPath }


</body>
</html>
运行结果:
技术分享
跳转后:
技术分享

JAVAWEB开发之Session的追踪创建和销毁、JSP详解(指令,标签,内置对象,动作即转发和包含)、JavaBean及内省技术以及EL表达式获取内容的使用