概念
jsp是一种简化的servlet
有人说servlet是java里面嵌入html,jsp是html里面嵌入java。那他的历史到底是什么样的?
java用servlet实现了web模式,在浏览器和数据库之间加入了一个servlet容器来响应用户的请求,并读取数据库中的数据。但是servlet要输出html就非常麻烦,需要使用system.println一句句的打印。因此出现了jsp,它是一种特殊的servlet,其实理论上讲还是在java中写html代码,但是只不过书写方式让用户觉得更多的像是在写html。
jsp的生命周期
jsp是特殊的servlet,因此它的生命周期和servlet很相似
jsp页面
转移为servlet
其实HttpJspBase是继承HttpServlet类的,这一下子就明白了吧
带下划线的函数_jspInit()是由系统自己生成的,程序员不能自己修改,那如果我们要设置一些初始化代码怎么办?这就是jspInit()函数存在的意义,我们可以在代码中重写这个初始化函数。jspDestroy()同理。
当浏览器访问一个jsp页面的时候,jsp引擎会首先会检查该页面是否需要编译?如果这个页面没有被编译过,或者说它又有新的更新,该页面就需要被编译了!(jsp是一种特殊的servlet,servlet又是一个class,因此要运行它也需要编译)这需要3步骤就可以了:
- 分析jsp页面
- 转换jsp页面成为servlet
- 编译这个servlet
可以通过查看jsp编译后的.java文件来解决一下bug,具体的位置如下
F:\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\demo\org\apache\jsp,这是windows系统,其他系统只要找到workspace就可以了
语法(jsp有3大指令,7种常用动作标签, 9种内置对象)
- 指令
- page
- include
- taglib
- 动作标签
- jsp:forward 执行页面转向
- jsp:param 用于传递参数
- jsp:include 在页面被调用的时候引入一个jsp文件
- jsp:plugin 用于下载javaBean或applet到客户端执行
- jsp:useBean 使用javaBean
- jsp:setProperty 修改javaBean实例的属性值
- jsp:getProperty 获取javaBean实例的属性值
- jsp:element 动态的定义xml元素
- jsp:attribute 动态定义xml元素的属性
- jsp:body 动态定义xml元素的主体
- jsp:text 用jsp页面或者文档生成模版内容
- 内置对象
对象名 | 对象的类型 | 作用范围 |
---|---|---|
pageContext | javax.servlet.jsp.PageContext | Page |
page | javax.servlet.jsp.HttpJspPage | Page |
request | javax.servlet.jsp.HttpServletRequest | Request |
response | javax.servlet.jsp.HttpServletResponse | Page |
session | javax.servlet.jsp.HttpSession | Session |
application | javax.servlet.jsp.ServletContext | Application |
out | javax.servlet.jsp.JspWriter | Page |
config | javax.servlet.jsp.ServletConfig | Page |
exception | javax.servlet.jsp.ThrowAble | Page |
- 其他
- <% 代码 %> 对应_jspService()函数体
- <%=表达式 %>对应_jspService()函数里的输出语句
- <%! 声明 %>对应声明类的方法和属性
- <%-- 注释 --%>
- jsp是可以用使用java的流程控制语法的(if/else,do...while,switch)
指令详解
命令 | 描述 |
---|---|
<%@ page ... %> | 定义一些页面需要依赖的属性,例如脚本语言,错误页面,缓存 |
<%@ include ... %> | 在编译阶段包含一个文件,包含源代码 |
<%@ taglib ... %> | 声明一个标签库,包含页面中常用的行为 |
- page指令
该指令可以指定的属性是:
属性 | 目的 |
---|---|
buffer | 指定流输出的缓存 |
autoFlush | 控制servlet输出缓存的行为 |
contentType | 定义字符编码 |
errorPage | 定一个独立的jsp错误报告页面 |
isErrorPage | 判断当前页面是否为错误报告页面 |
extends | 继承于哪个servlet |
import | 指定一个需要导入的packages或者classes列表 |
info | 定义一个字符串,可以被servlet的getServletInfo函数访问 |
isThreadSafe | 是否为servlet的线程模型 |
language | 声明该页面使用的是jsp语言 |
session | 声明该页面是否启动session |
isELIgnored | 声明是否会屏蔽EL表达式 |
isScriptingEnabled | 判定脚本元素是否会被使用 |
- include指令
<%@ include file="relative url">
- 可以在任何地方使用指令
- file是相对地址
- 最重要的!!这里是包含file的内容,也就是把代码包含进来!
- taglib指令
taglib是自定义标签功能,也就是自己定一个jsp标签,uri是定义标签库文件的位置,库文件是一个.tld文件,声明了标签的名字和实际代码位置
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>myTag</shortname>
<tag>
<name>hello</name>
<tagclass>mytag.HelloWorldTag</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>
其中mytag.HelloWorldTag是一个类
package mytag;
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class HelloWorldTag extends TagSupport{
public int doStartTag() throws JspTagException{
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspTagException{
try{
pageContext.getOut().write("Hello World");
} catch (IOException ex){
throw new JspTagException("Error!");
}
return EVAL_PAGE;
}
}
然后在jsp页面中调用的方式:
<%@ tablib uri="uri" prefix="自定义标签名称" >
行为
-
必要属性
- Id属性
行为的ID标示,jsp代码可以通过行为的id,引用行为所对应的对象 - Scope属性
有四个值可选:page,request,session,application。分别代表这个行为的生命周期
- Id属性
include动作:<jsp:include page="relative URL" flush="true" />
include动作和include指令不一样,指令是包含代码,而动作时包含输出的内容useBean动作:<jsp:useBean id="myBean" class="package.class" />
javaBean是一种特殊的类,这里相当于实例化javaBean,如果想设置javaBean中的属性,可以使用方法jsp:getProperty和jsp:setProperty-
setProperty动作:<jsp:setProperty name="myBean" property="xxx" value="xxxx" />
该动作需要javaBean已经被创建,可以通过四种方式来调用该行为为javaBean属性赋值:- <jsp:setProperty name="myBean" property="*" />
这种是client的表单项和javaBean的属性一一对应,通过该方法,所以javaBean属性被一次性赋值 - <jsp:setProperty name="myBean" property="xxx" />
只赋值一个属性(xxx),这个属性对应的表单元素是xxx - <jsp:setProperty name="myBean" property="xxx" value="hello world" />
给javaBean的属性xxx赋值为hello world - <jsp:setProperty name="myBean" property="xxx" param="yyy" />
表单字段不一一对应,可以用yyy表单元素给xxx属性赋值
- <jsp:setProperty name="myBean" property="*" />
getProperty行为:<jsp:getProperty name="myBean" property="xxx" />
没啥可说的...forward行为:<jsp:forward page="Relative URL" />
这里是内部转发,类似于request.getRequestDispatcher("Relative URL").forward(request.response)plugin行为 <jsp:plugin>
官方解释:该行为用来给jsp页面插入一段java组件,这个组件可以是Applet或者JavaBean。这里常用的就是Applet,以下是一段知乎关于Applet的描述:
Java Applet出现于1996年,那时候的浏览器也出现不久,还只能支持静态页面,因此Applet技术出现了,来解决:动画动态内容与服务器的通讯富客户端应用但是Flash技术出现后,Applet技术没有竞争过Flash,Flash在动画和与服务器的通讯方面(Flex)都能满足。后来出现了Ajax,JavaScript可以和服务器通讯了。再后来出现HTML5技术(包括HTML 5/CSS 3/JavaScript)引入了音频,视频,2D图形(Canvas),以及WebGL引入了3D图形。HTML 5技术替代了Flash技术的地位。
其他的行为不经常使用,请查询手册。
内置对象
-
request对象
有很多可用的函数- Cookie[] getCookies()
- HttpSession getSession()
- Object getAttribute(String name)
- String getContentType()
- String getContextPath()
- String getParameter(String name)
- ...还有很多,看手册吧
-
response对象
- void addCookie(Cookie cookie)
- void flushBuffer()
- void sendRedirect(String location)
- ...
cookie
- 写cookie
三步骤:- 创建cookie对象
- 设置生存时间
- 保存cookie至response header
<%
// Create cookies for first and last names.
Cookie firstName = new Cookie("first_name",
request.getParameter("first_name"));
Cookie lastName = new Cookie("last_name",
request.getParameter("last_name"));
// Set expiry date after 24 Hrs for both the cookies.
firstName.setMaxAge(60*60*24);
lastName.setMaxAge(60*60*24);
// Add both the cookies in the response header.
response.addCookie( firstName );
response.addCookie( lastName );
%>
- 读取cookie
<%
Cookie cookie = null;
Cookie[] cookies = null;
// Get an array of Cookies associated with this domain
cookies = request.getCookies();
if( cookies != null ){
out.println("<h2> Found Cookies Name and Value</h2>");
for (int i = 0; i < cookies.length; i++){
cookie = cookies[i];
out.print("Name : " + cookie.getName( ) + ", ");
out.print("Value: " + cookie.getValue( )+" <br/>");
}
}else{
out.println("<h2>No cookies founds</h2>");
}
%>