一、jsp页面元素的构成
1.jsp指令
三大指令元素为 page include taglib 可没有import哦,import是page的属性
①page指令
通常位于jsp页面顶端,同一个页面可以有多个page指令
语法:
<%@ page 属性1="属性值" 属性2="属性值1,属性值2" … 属性n="属性值" %>
常用属性值:
属性 | 描述 | 默认 |
---|---|---|
language | 指定jsp页面使用的脚本语言 | java |
import | 引用脚本语言中用到的类文件 | / |
contentType | 指定jsp页面所采用的编码方式 | text/html,ISO-8859-1 (不支持中文) |
例:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
②include指令
将外部文件(如jsp、html等)嵌入到当前的jsp文件中,同时解析这个页面中的jsp语句
例:
<%@ include file="copyright.html"%>
file是include指令唯一的属性 前面不加/表示当前目录下(绝对路径),加了/时表示应用程序文档根目录
③taglib指令
使用标签库定义新的自定义标签,在jsp页面中启用定制行为
在之前的文章中曾经讲过:jsp标签技术——自定义标签开发
2.jsp注释
注释一般有如下几种方法:
1.<!-- html注释 -->
客户端通过查看源代码可见
2.<%-- jsp注释 --%>
客户端不可见
3.<%//java注释(jsp脚本注释)%>
客户端也不可见
3.jsp脚本——在jsp页面中执行的java代码
语法:
<%
java代码
%>
不能在小脚本中声明方法,因为java语言中不能在方法中定义方法。(方法的声明放到jsp声明里)
4.jsp声明——定义变量或方法
语法:<%! java代码 %>
,注意声明语句要以分号结束。
注:声明的变量只在页面第一次载入时初始化一次,而小脚本在每次访问页面时都会被执行
例:输出页面被访问次数的代码:
<%@ page contentType="text/html; charset=utf-8" %>
<%! int count = 0; %>
<html><body>
<%
count++;
%>
该页面已被访问<%= count %>次。
</body></html>
5.jsp表达式
语法:<%= 表达式%>
注:表达式不以分号结束,且百分号和等号之间不能有空格
例:
<%! String s="张三"; %>
你好,<%=s %><br/>
二、jsp内置对象
内置对象是web容器创建的,不需要new就可以直接使用。
例如下文的out就是内置对象之一:
<%
int[] value = {60,70,80};
for(int i:value)
{
out.println(i);
}
%>
jsp内置对象:out、request、response、session、application、page、pageContext、exception、config
web程序的请求与响应模式:客户端向服务器提交请求,服务器响应。
out对象
out对象常用方法:
方法 | 说明 |
---|---|
void println() | 向客户端打印字符串 |
void clear() | 清除缓冲区内容,如果在flush后调用会抛出异常 |
void clearBuffer() | 清除缓冲区内容,在flush后调用不会产生异常 |
void flush() | 将缓冲区的内容输出到客户端 |
int getBufferSize() | 返回缓冲区的大小(字节数计),不设缓冲区则为0 |
int getRemaining() | 返回缓冲区剩余可用容量 |
boolean isAutoFlush() | 返回缓冲区满时,是自动清空还是抛出异常 |
void close() | 关闭输出流 |
关于flush:
out.println("1");
out.println("2");
和
out.println("1");
out.flush();
out.println("2");
上面两段代码的显示结果并没有什么差别,只是后一种其实是1先输出的(输出后缓冲区里只剩了2),而前面那种是两者在缓冲区然后一起输出的(输出后1和2都还在缓冲区里),所以再分别写getRemaining的话后者的值比前者的大。
<br/>
而以下这段代码:
<%
out.println("床前明月光");
out.flush();
out.clear();
out.println("疑是地上霜");
%>
浏览器中输出床前明月光 后台跳异常(clear用在flush之后了)
以下代码:
<%for(int i = 0;i < 3;i++){ %>
out.print(i*2);
<%} %>
//输出out.print(i*2);out.print(i*2);out.print(i*2);
//而以下代码:
<%for(int i = 0;i < 3;i++){ %>
out.print(<%=i %>*2);
<%} %>
//输出out.print(0*2);out.print(1*2);out.print(2*2);
会这样是因为out.println没有被含在尖括号内,所以直接输出了。而且在<% %>
内声明的变量也只能在其中使用,比如说像上面第二段代码一样。在html页面中是无法直接使用的。
request对象
客户端的请求信息被封装在request对象中
常用方法:
方法 | 说明 |
---|---|
String getParameter(String name) | 返回name指定参数的参数值 这个name就是html表单上name属性值 |
String[] getParameterValues(String name) | 返回包含参数name的所有值的数组(一般用于复选按钮) |
void setAttribute(String name,Object) | 存储此请求中的属性,存储属性之后其他的jsp页面也可用,不需要再次getParameter |
object getAttribute(String name) | 返回指定属性的属性值 这里的name对应上面存储时的name |
String getContentType() | 得到请求体的MIME类型 |
String getProtocol() | 返回请求用的协议类型及版本号 |
String getServerName() | 返回接受请求的服务器主机名 |
int getServerPort() | 返回服务器接受此请求所用的端口号 |
String getCharacterEncoding() | 返回字符编码方式 |
void setCharacterEncoding() | 设置请求的字符编码方式 |
int getContentLenth() | 返回请求体的长度(以字节数) |
String getRemoteAddr() | 返回发送此请求的客户端ip地址 |
String getRealPath(String path) | 返回以虚拟路径的真实路径 |
String request.getContextPath() | 返回上下文路径 |
关于getParameter——不仅仅是表单可以用,url也是可以用的(get和post方法都使用)
例:<a href="request.jsp?username=ll">url传递参数</a>
也是可以用reques.getParameter("username");
的
解决中文乱码问题:在表单之前添加request.setCharacterEncoding("utf-8")
但是上面这种并不能解决url传递的中文乱码问题,只能解决表单的。要解决URL传递;乱码的话需要修改Tomcat服务器的配置文档/tomcat根目录/conf/server.xml
<Connecter port="…" …>
在最后加上一个属性URIEncoding="utf-8"
即<Connecter port="…" … URIEncoding="utf-8">
(更改端口就是改这里的port)
get与post区别:
get:以明文方式通过url提交数据,数据在url中可以看到。提交的数据最多不超过2kb。安全性较低,但效率比post高,适合提交数据量不大,安全性不高的数据,比如搜索、查询功能。
post:将用户提交的信息封装在HTML HEADER内。适合提交数据量大,安全性高的用户数据。比如注册、修改、上传。
提交用户名和密码用get的话地址栏上会有显示。
response对象
reponse对象包含了响应客户请求的有关信息,但在jsp页面中很少直接用到它。
response对象具有页面作用域,即访问一个页面时,该页面内的response对象只能对这次访问有效,且其他页面的response对象对当前页面无效。
response对象常用方法:
方法 | 说明 |
---|---|
String getCharacterEncoding() | 返回响应所用的字符编码 |
String setContentType(String type) | 设置响应的MIME类型 |
PrintWriter getWriter() | 返回可以向客户端输出字符的一个对象 |
sendRedirect(String location) | 重新定向客户端的请求 |
关于getWriter:
例:
PrintWriter outer = response.getWriter();
outer.println() ;
其输出总是提前于内置out对象,就算先写out.println 再写outer.println也是一样的。除非在out之后写out.flush()强制先将缓存中的内容输出。
sendRedirect和getRequestDispatcher的区别:
重定向是一种客户端行为,从本质上讲等同于两次请求,前一次请求的对象不会保存,地址栏的url会改变
而请求转发(request.getRequestDispatcher().forward(req,resp);)是一次请求,转发后请求对象会保存,地址栏的url不变
比如在一个页面提交数据 提交到了1.jsp 而要从1转去2进行处理,就要用请求转发,如果是请求重定向,则2.jsp没法接收到表单数据。
session对象
session表示客户端与服务器的一次会话(用于区分用户身份),在服务器的内存中保存着不同用户的session。
如果<%@ page session="false" %>
则该容器不会声明session变量,对它的使用将会产生错误。
session对象常用方法:
方法 | 说明 |
---|---|
long getCreation Time() | 返回session创建时间 |
public String getID() | 返回session创建时jsp引擎为它设的唯一ID号 |
public void setAttribute(String name,Object value) | 使用指定名称将对象绑定到此会话 |
public Object getAttribute(String name) | 返回此会话中与指定名称绑定在一起的对象,若没有则返回null |
String[] getValueNames() | 返回一个包含此session中所有可用属性的数组 |
int getMaxInactiveInterval() | 返回两次请求间隔多长时间此session被取消(以秒为单位) |
int setMaxInactiveInterval() | 设置两次请求间隔多长时间此session被取消(以秒为单位) |
session的生命周期:
1.创建。当客户端第一次访问某个jsp或servlet时,服务器会为当前会话创建一个sessionId,每次客户端向客户端发送请求时都会携带这个Id,服务器会进行校验
2.活动。当把所有相关页面都关闭再重新访问某个jsp或servlet时才会创建新的会话(在其中一个页面还在的时候就算换浏览器也没用)。但是注意此时旧的会话依旧在服务器中存在,等到超时了它才会结束。
3.销毁。三种方式:①调用session.invalidate()方法 ②session超时(过期)③服务器重启(销毁所有会话)
application对象
application对象是ServletContext类的实例,开始于服务器的启动,终止于服务器的关闭
在用户的前后连接后不同用户的连接中,可以对application对象的同一属性进行操作。因此它实现了用户间数据的共享,可存放全局变量。
在任何地方对application对象属性的操作都将影响到其他用户对此的访问
常用方法:
方法 | 说明 |
---|---|
public void setAttribute(String name,Object value) | 使用指定名称将对象绑定到此会话 |
public Object getAttribute(String name) | 返回此会话中与指定名称绑定在一起的对象,若没有则返回null |
Enumeration getAttributeNames() | 返回所有可用属性名的枚举 |
String getServerInfo() | 返回jsp(servlet)引擎名及版本号 |
Enumeration的例子:
Enumeration attributes = application.getAttributeNames();
while(attributes.hasMoreElements())
{
out.println(attributes.nextElements()+" ");
}
且
String path = application.getRealPath("/XX");
application.log("绝对路径为:"+path);
等价于
String path = getServletContext().getRealPath("/XX");
getServletContext().log("绝对路径为:"+path);
page对象
page对象指当前jsp页面本身,有点像类中的this指针,是java.lang.Object类的实例
即 page.XXX 就相当于this.XXX
常用方法:(和Object类的常用方法一致)
方法 | 说明 |
---|---|
class getClass() | 返回此Object的类 |
int hashCode() | 返回此Object的hash码 |
boolean equals(Object obj) | 判断此Object是否与指定的Object对象相等 |
void copy(Object obj) | 把此Object拷贝到指定的Object对象中 |
Object clone() | 克隆此Object对象 |
String toString() | 把此Object对象转换为String类的对象 |
void notify() | 唤醒一个等待的线程 |
void notifyAll() | 唤醒所有等待的线程 |
void wait(int timeout) | 使一个线程处于等待直到timeout结束或被唤醒 |
void wait() | 使一个人线程处于等待直到被唤醒 |
pageContext对象
pageContext对象提供了对jsp页面内所有的对象及名字空间的访问,因此它可以访问到本页的session,也可以获取本页面所在的application的某一属性值。
常用方法:
方法 | 说明 |
---|---|
JspWriter getOut() | 返回当前客户端响应被使用的JspWriter流(out) |
HttpSession getSession() | 返回当前页中的HttpSession对象(session) |
Object getPage() | 返回当前页的Object对象(page) |
ServletRequest getRequest() | 返回当前页的ServletRequest(request) |
ServletResponse getResponse() | 返回当前页的ServletResponse(response) |
void setAttribute(String name,Object attribute) | 设置属性及属性值 |
Object getAttribute(String name,int scope) | 在指定范围内取属性的值 |
int getAttributeScope(String name) | 返回某属性的作用范围 |
void forward(String relativeUrlPath) | 使当前页面重导到另一页面 |
void include(String relativeUrlPath) | 在当前位置包含另一文件 |
在Servlet中将请求转发到另一个资源需要request.getRequestDipatcher(“XX.jsp”).forward(request,response);
而在jsp页面中:pageContext.forward(“XX.jsp”);
config对象
用于一个Servlet初始化时jsp向其传递信息,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
常用方法:
方法 | 说明 |
---|---|
ServletContext getServletContext() | 返回含有服务器相关信息的ServletContext对象 |
String getInitParameter(String name) | 返回初始化参数的值 |
Enumeration getInitParameterNames() | 返回Servlet初始化所需所有参数的枚举 |
Exception对象-异常对象
当一个页面在运行过程中发生了异常,就产生exception对象。如果jsp页面要应用该对象,则需把page指令属性isErrorPage值设为true,否则无法编译
<%@page errorPage="XX.jsp"%>
->错误交由XX.jsp处理
然后XX.jsp中 <%@page isErrorPage="true"%>
然后可以在其中使用exception调用方法
常用方法:
方法 | 说明 |
---|---|
String getMassage() | 返回描述异常的消息 |
String toString() | 返回关于异常的简短描述消息 |
void printStackTrace() | 显示异常及其栈轨迹 |
Throwable FillInStackTrace() | 重写异常的执行栈轨迹 |
三、指令与动作
include动作
语法:
<jsp:include page="url" flush="true/false" />
flush表示被包含的页面是否从缓冲区读取,默认为false
include指令和动作的比较:
区别 | include指令 | include动作 |
---|---|---|
发生作用的时间 | 页面转换期间 | 请求期间 |
包含的内容 | 文件的实际内容 | 页面的输出 |
转换成的servlet | 主页面和包含页面转换为一个servlet | 主页面和包含页面转换为独立的servlet |
编译时间 | 较慢——资源必须被解析 | 较快 |
执行时间 | 稍快 | 较慢——每次资源必须被解析 |
include指令静态包含如果乱码,html页面中也要写<@page pageEndcoding=”utf-8”>
forward动作
语法:<jsp:forward page="url" />
等同于 request.getRequestDispatcher(“/url”).forward(request,response);
param动作常作为
<jsp:forward page="xx.jsp">
<jsp:param name="name1" value="value1" />
<jsp:param name="name2" value="value2" />
</jsp:forward>
可以用来强制修改表单提交过来的值 也可以新增传递值