jsp基础
jsp 是用java + html 开发动态资源的技术, jsp本质上就是servlet
jsp特点: 由服务器运行 jsp页面既可以写html 又可以写java代码 apahce服务器的work目录存放jsp运行时的临时文件 java代码写在 <% %> 中 执行过程: 1.tomcat服务器检测到jsp文件 在work目录将jsp翻译成java源文件 2.交给jvm编译成class字节码文件 3.构造jsp类对象 4.调用相关方法 返回内容到浏览器 jsp修改或者临时文件被删除 会重新执行1,2 第n(n>1)次访问执行直接执行4
服务器翻译出来的java文件头:
public final class showTime_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
}
其中org.apache.jasper.runtime.HttpJspBase 这个服务器内部的类 继承HttpServlet,因此 jsp间接继承HttpServlet,故jsp就是一个sevlet程序
jsp生命周期:
- 翻译 .java
- 编译 .class
- 构造方法 同servlet一样 构造方法,init方法只在第一次调用
- init方法
- service方法
- destroy方法
servlet技术可以在jsp中使用 jsp的技术并不全部适用于servlet
Jsp 语法:
模板:
jsp页面中的html代码
表达式:
<%=变量或表达式 %> 向浏览器输出变量值或者表达式结果
执行原理: 翻译成java代码后为 out.print(变量表达式);
脚本:
<% java代码%> 执行java代码 实质是把脚本中的java代码拷贝到翻译后的servlet类中的_jspServive 方法中执行 可以在其中穿插html代码 <% for(int i = 0; i < 5; i++){ %> <h<%=i %» 标题<%=i %></h<%=i %» <% } %>
声明: <%! 声明变量或者方法 %> 翻译成java代码后为类的成员变量或成员方法,不能重复声明定义已有的方法 脚本中的变量为service方法中局部的,脚本中不能声明方法
注释: <!–html注释 – > <%–jsp注释 –%> jsp注释的内容不会翻译到java文件 html注释内容会翻译执行
Jsp的三大指令:
- include: 在当前页面包含其它页面在当前页面包含其它页面
原理: 将被包含页面的代码拷贝到当前页面相应位置合并为一个文件, 再翻译为java文件 ——— 这种包含叫静态包含 (由于被包含页面全部被拷贝,所以只需要写body的内容即可) 2.page: 告诉服务器如何翻译jsp文件 包含常用属性如下:
<%@page
import="java.util.* , java.text.*" ---导包语句,多个包逗号分隔
language="java" ---使用什么动态语言翻译(只支持java)
contentType="text/html; charset=utf-8"
---服务器发送给浏览器的数据类型和编码 //默认参考pageEncoding的值
(翻译成:response.setContentType();)
pageEncoding="utf-8" ---告诉服务器页面的编码,eclipse中默认保存编码参考这个
errorPage="error.jsp" ---指定错误处理页面
isErrorPage="false" ---指定当前页面是否错误页面错误信息会封装到exception中,
默认false。 指定为true后,可以使用 <% exception.getMessage() %> **exception**内置对象
可在web.xml 配置全局错误页面 <<error-page> <error-code></error-code><location/></error-page>>
errorPage="error.jsp" 优先
buffer="8kb" ---jsp页面的缓存大小
session="true" ---是否开启session功能 false 不能用session内置对象 true可以使用
isELIgnored="false" 是否忽略EL表达式
%>
- taglib** –引入标签库,后面介绍
jsp的内置对象:
jsp加载翻译时会自动声明并创建好这些对象,开发者可以直接使用这些内置对象
九大内置对象 对象名 所属类
- request HttpServletRequest
- response HttpServletResponse
- config ServletConfig
- application ServletContext
- session HttpSession
- exception Throwable
7.out JspWriter JspWriter 类 相当于带缓存的 PrintWriter,它有write() 方法向浏览器写出数据,向jsp缓冲区写出内容 buffer指定大小默认8kb 缓冲区满 、 flush刷新缓冲区 、关闭缓冲区(buffer=0kb)、 jsp页面执行完毕 、 缓冲区内容都会写向页面 out.getRemaining() 查看缓冲区剩余大小 out.getBufferSize()查看缓冲区大小
8.page Object(this) //等价servlet中的this
9.pageContext PageContext
jsp上下文对象,可以获取其它八个内置对象,它们都封装到了pagecontext对象中 由于这八个对象都是jspservcice 内的局部变量,如果在其他方法使用就需要将pageContext传入,由pageContext取得。 自定义标签时使用此对象较多pageContext本身也是一个域对象 可以在不同资源间共享数据 setAttribute() getAttribute() 保存到page域中,其作用范围只在本页面 也可以指定参数保存到其它域中: setAttribute(“message”,”hello world”, PageContext.REQUEST_SCOPE); 其它页面中request.getAttribute(“message”) 取得 或 getAttribute(“message”, PageContext.REQUEST_SCOPE); 可以指定常量,表示保存到相应的域中
pageContext.findAttribute(“key”) 可以自动在所有域中搜索查找key的value 搜索顺序:page域 –> request域 –> session域 –> context域
servlet 与jsp结合,各取所需 servlet: 接收数据 处理数据 跳转页面 jsp: 显示数据
**EL表达式:
** 因为jsp开发尽量少些java代码,可以用EL表达式简化。
-
替换jsp表达式<%= %>语法:${变量或表达式},向浏览器输出 域对象 中的变量值或表达式的结果.因此值应先保存到域对象中: pageContext.setAttribute(“name”,name); 取值: ${name} 等价于: pageContext.findAttribute(“name”);
-
从指定域中获取数据: ${requestScope.name}
-
取对象的属性值 ${student.name} 本质上等价于 ((Student)pageContext.getAtrribute(“student”)).getName(); 使用类的getName方法取值
-
获取集合对象值 ${list[0]} 等价调用list.get() 方法 ${map[‘key’]} 等价调用map.get(key)方法
el表达式中的运算: 比较运算 算术运算 逻辑运算 判断字符串的简写: ${empty string} 等价于– ${string == null | string == “”} |
jsp标签:
标签用来替换jsp中的java脚本 .达到减少java代码,简化书写效果 ·内置标签(动作标签) ·
转发标签:
·包含标签:
·外置jstl标签
-外置需要导入标签库 java standard tag library 标准标签库 1.使用需要导入jstl.jar包 myeclipse新建javaee项目时已自动导入 2.需要导入标签库通过: <%@taglib uri=”tld文件名字” prefix=”简写”%> tld名字在jstl包中web-inf文件内 ·核心标签库(c标签库) 保存数据
重定向
当标签库中没有满足需求的标签时,可以自定义标签 例:用户需要一个显示ip的标签 1.写一个继承标签处理类SimpleTagSupport的类
public class ShowIp extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
// TODO Auto-generated method stub
//通过pageContext域对象取得其它域对象
PageContext pc = (PageContext)getJspContext();
HttpServletRequest request = (HttpServletRequest) pc.getRequest();
JspWriter out = pc.getOut();
out.write(request.getRemoteHost());
}
}
2.在web项目的WEB-INF目录下建立.tld后缀的标签库声明文件(参考核心标签库写法)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary\_2\_0.xsd"
version="2.0">
<description>my own tag</description>
<display-name>test tag</display-name>
<!\-\- 标签库版本 -->
<tlib-version>1.1</tlib-version>
<!\-\- 使用标签库的简写 -->
<short-name>mytag</short-name>
<!\-\- tld文件的唯一标记 -->
<uri>http://com.ctguggbond.mytag</uri>
<!\-\- 一个标签的声明 -->
<tag>
<name>showip</name>
<!\-\- 处理标签类的全名 刚才自定义的类全名-->
<tag-class>com.ctgu.taglib.ShowIp</tag-class>
<!\-\- 输出内容的格式 -->
<body-content>scriptless</body-content>
</tag>
</taglib>
3.在jsp头部导入自定义标签库 <%@ taglib uri=”http://com.ctguggbond.mytag” prefix=”mytag”%>
4.使用自定义标签
public class tagTest extends SimpleTagSupport{
/\*
\* 自定属性就是定义此类的成员变量,并提供setter方法
*/
private Integer num;
public void setNum(Integer num) {
this.num = num;
}
/\*
\* 控制标签体及标签后面的内容输出
*/
@Override
public void doTag() throws JspException, IOException {
System.out.println("执行了标签");
/\*\*
\* 1 .通过调用invoke()控制标签内容输出
*/
JspFragment jspBody = this.getJspBody();
/\*\*
\* 执行invoke方法: 把标签体内容输出到指定的Writer对象中
\* 若writer对象指定为null 就默认为out内置对象
*/
JspWriter out = this.getJspContext().getOut();
jspBody.invoke(out);
//jspBody.invoke(null);等价于上面的代码
/\*\*
\* 循环控制重复输出标签体内容
*/
for(int i=1;i<=num;i++){
jspBody.invoke(null);
}
/\*\*
\* 改变标签体内容
\* 通过自定义传入writer对象,将标签体内容取出,再作处理后,通过out输出到浏览器
*
*/
StringWriter sw = new StringWriter();
jspBody.invoke(sw);
String content = sw.toString();
content = content.toLowerCase();
this.getJspContext().getOut().write(content);*/
/*
* 2控制标签余下内容是否输
* 抛出SkipPageException异常将停止执行后面的内容
*/
throw new SkipPageException();
}
}