JSP 串讲
一、JSP 简介
<!--[if !supportLists]-->(一)<!--[endif]-->JSP 简介
<!--[if !supportLists]-->1、<!--[endif]-->JSP的定义
JSP(java server page)是服务器端运行的页面,JSP本身就是一个文档,他不仅可以包含静态的HTML代码,
也可以包含动态的JAVA代码,服务器容器可以将JSP转换成Servlet发布,并接受请求。
2、JSP的特点
(1)是一个文本文件,里面可以嵌入JAVA代码
(2)文本不需要编译,直接运行
(3)在运行的时候,JSP被容器翻译成为一个servlet,
放在apache-tomcat-5.5.20à work àCatalinaàlocalhost目录下面。
(4)不需要再在配置文件里面配置
(5)文件被修改之后,自动重编译
3、跟servlet 的比较
(1)Servlet 生成静态页面比较麻烦,适合于做control层,JSP生成页面比较容易,适合做view 层,JSP的内核就是servlet.
(2)目录结构与servlet 相同。
(二)JSP的语法元素
1、Scripting脚本(代码)
(1)声明<%! %>
1)声明的是成员变量,yin里面的内容原封不动的放在servlet 的service()方法体的外边。
2)可以声明变量和方法,并且方法和变量还可以用修饰符修饰
3)在声明里面不能使用service 方法体内的任何变量:例如:out.println(“”);等。而代码块和表达式则可以。
4)另一种书写方式:
<jsp: declaration>方法或者变量的声明</jsp: declaration>
eg.<%! String hello=”hello world !” %>
(2)表达式<%= %>
1)定义的局部变量,在servlet 的service()方法体内有效,
2)“=”后边也可以是一个函数调用,但是要求这个函数必须有返回值。
3)另一种书写方式:
<jsp : expression> 表达式 </jsp: expression>
eg.<%=123%>可以,但是如果abc不是变量名,则不可<%=abc%>,abc必须用“”引起。
<!--[if !supportLists]-->(3)<!--[endif]-->代码块<% %>
1)本质是一个java 代码块,里面的注释方式跟java 代码一样
2)声明的是局部代码,原封不动的放在servlet 的service()方法中,放置的位置回影响结果,
必须保证变量先声明后使用。
3)这个代码里面不能声明方法。 (方法中不能再定义方法)
4)另一种书写方式:
<jsp: scriplet> 代码块</jsp: scriplet>
2、directive指令
(1)页面指令
<%@page %>
1)<%@ page import =””%>需要使用到的类。如果要导入多个包,那么可以用(逗号)“,”隔开:
2)<%@ page isErrorPage =””%>本页面是否是错误页面
3)<%@ page errorPage=””%>本页面错误之后,转向的错误页面
4)<%@ page contentType =””%>返回给用户的编码方式
5)<%@ page pageEncoding =””%>本页面自己的编码方式
6)<%@ page language =””%>本页面使用的scriting 语言,默认是java ,通常不写
7)<%@ page extends =””%>本页面生成的servlet 所继承的类
8)<%@ page buffer =”“%>本页面的输出是否支持缓冲
9)<%@ page autoFlush =””%>缓冲区是否自动刷新
10) <%@ page info =””%>返回本页面的描述信息。
11)<%@ page isELIgnored=””%>本页面是否支持EL表达式。
★★编码问题
<!--[if !supportLists]-->Ø <!--[endif]-->页面要指定编码
<!--[if !supportLists]-->n <!--[endif]-->html页面:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--[if !supportLists]-->n <!--[endif]-->JSP页面:
<!--[if !supportLists]-->u <!--[endif]--><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> pageEncoding是jsp文件本身的编码
<!--[if !supportLists]-->u <!--[endif]--><%@ page contentType=“text/html; charset=UTF-8” %>
contentType的charset是指服务器发送给客户端时的内容编码
<!--[if !supportLists]-->Ø <!--[endif]-->表单提交
<!--[if !supportLists]-->n <!--[endif]-->POST方式提交
servlet在获得表单数据之前需要调用:
request.setCharacterEncoding("utf-8");
指定的编码和表单页面的编码一致 (因为浏览器会按照表单页面的编码提交中文) 必须写在所有的request.getParameter("...")之前
<!--[if !supportLists]-->n <!--[endif]--> GET方式提交
最方便的方法是修改tomcat的server.xml 修改server.xml,在Connector中加入URIEncoding="utf-8"
eg.
<Connector port="80" maxThreads="150" minSpareThreads="25"
maxSpareThreads="75" enableLookups="false" redirectPort="8443"
acceptCount="100" debug="0" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="utf-8" />
<!--[if !supportLists]-->n <!--[endif]-->对于请求参数
String name = new String(request.getParameter("name").getBytes("iso-8859-1"),"UTF-8");
<!--[if !supportLists]-->Ø <!--[endif]-->Tomcat
需要在server.xml文件中的connector元素指定 :URIEncoding=“utf-8”
Tomcat默认编码是:iso-8859-1
<!--[if !supportLists]-->Ø <!--[endif]-->数据库(以mysql为例)
<!--[if !supportLists]-->n <!--[endif]-->连接数据库设置编码
jdbc:mysql://localhost:3306/test?characterEncoding=utf8
<!--[if !supportLists]-->n <!--[endif]-->my.ini中配置默认编码
default-character-set=utf8
注意:
java中的常用编码UTF-8;GBK;GB2312;ISO-8859-1;
对应mysql数据库中的编码utf8;gbk;gb2312;latin1
<!--[if !supportLists]-->(2)<!--[endif]-->包含指令
<%@include %>
1)<%@ include file =”相对路径”%>静态包含,也称为翻译时包含,被引入的页面在被翻译
也成为servlet 的一部分,不会生成一个新的servlet
2)<jsp: include page =””%> 动态包含。是运行时包含。
动态的包含:指的是本页面的request被发送到被包含页面,被包含页面被执行,执行完的response又被
包含到调用页面。被包含的页面也会被翻译成一个servlet。
◆使用注意:
·被引入的页面最好为一个片断,而不跟主页面发生冲突,并且主页面在引进某个包的时候,引入页
面也可以使用。
·还可以进行参数的传递
eg.
<jsp:include page =””>
<jsp: param name=”user” value=”Kathy”>
</jsp:include>
<!--[if !supportLists]-->(3)<!--[endif]-->标签库指令
<%@taglib url=""%>
<!--[if !supportLists]-->3、<!--[endif]-->action动作
<jsp: />
(1)include 动作: <jsp:include page="..." flush=true|false>
1)是在翻译和编译后运行时进行响应的合并,也就是对应了Servlet中RequestDispatcher类的
include(ServletRequest request, ServletResponse response)方法。
2)include动作可以传递参数(详解见上面),在使用参数时,可以用request内置对象来获取参
数的值。
3)<jsp:include page =””%>
两个页面的输出都会显示
(2) forward Action(只显示转化后的那个页面的输出内容)
<jsp: forward page=””/>
注:两种转发模式的区别:
1)forward转向,把请求委托给另外一个组件。对于用户和容器来说还是同一个请求和session。
2)request.sendRedirect():等于启动了一个新的请求。并且重起了一个session.
在使用Servlet的response的重定向sendRedirect(String location)方法在使用时要包含应用的路径,注意,
重定向会放弃这个请求,并向服务器发送一个新的请求,但是响应对象还是一个。重定向是用来避免重复提交的。
注意:对页面的刷新操作就会再一次运行程序,也就仿佛进行了再一次的提交一样,这也就是重复提交的问题,
所以需要使用重定向来解决这个问题。
两种转向赋值的方式:
1)<jsp: forward page=”hello.jsp”>
2)<jsp: forward >
<jsp:attribute name=”page”>hello.jsp</jsp:attribute>
</jsp:forward>
(3)其他的动作列表
1)Jsp:useBean: 在JSP页面中使用javabean
<jsp:useBean id="对象名" class="类全名"|type="类全名"(使用多态时使用) beanName="类全名" scope="page|request|session|application">
jsp:useBean动作,可以通过这个动作来使用java代码,id就是变量名,
注:class和type的区别:
·type: 不会创建对象,而只是会先查找如果有该对象就会使用,如果没有就会抛出异常
class: 在没有该对象存在时,则会创建新对象.
·class属性用在控制器中
type属性用在视图中,其作用是:
当用户直接访问视图页面时,不会让客户看到结果,而是转到控制器
·class后只能跟类,
type后可以跟类或接口
当type后跟类时, 该类必须和class后跟的类相同
当type后跟接口时,class后必须跟该接口的实现类
scope是用来保存实例的空间范围,page、request、session、application,由小到大,默认为page。
2)Jsp:setProperty:为javabean 属性赋值
<jsp:setProperty property="price" value="5600.00"/>
<jsp:setProperty property="price" param="price" />
注:param=“price”,price是请求中的参数的名字,要用下面的方式来访问这个JSP
http://127.0.0.1:8080/jsp/jsp/useBean.jsp?price=5600
URL中的参数名字必须和param="computerName"的参数名字一致,否则将不能设值,从而
<jsp:setProperty property="computerName" param="price" />
显示参数的值为null.
3)Jsp:getProperty:取得javabean 属性
(三)在web.xml中配置jsp 的方式。
<servlet>
<servlet-name> </servlet-name>
<jsp-file> </jsp-file>
</servlet>
<servlet-mapping>
<servlet-name></ servlet-name>
< url-pattern>< /url-pattern>
</servlet-mapping>
二、重用组件(javabean)
(一)javaBean 简介
1、定义:
在一个应用里面可以被重用和组合的java 类
2、javabean的特点:
(1)实现了序列化(在jsp页面里面传输给客户端 ,需要实现序列化才能在流中传输)
(2)无参的构造方法
(3)有属性,并且为属性提供get() ,set()方法。get() ,set()方法不是必须的,但是如果想要在JSP页面中
可以为这些属性赋值的话就必须在java程序里面提供get() ,set()方法。否则只能成为java 代码的属性,
而不能称为javaBean的属性。
(4)作为事件源,通过事件与别的组件沟通。
(二)JavaBean 在JSP中的应用。
1、在页面中生成实例
<jsp: useBean id=”” class=”” scope=””>
(1)Id : 一个实例的名字
(2)Class : 这个类字节码文件存放的位置,还可以用type 代替,两者的差别是:
1)Class:如果这个范围内没有实例,就创建一个新的
2)Type: 如果这个范围内没有实例,不创建新的,返回空指针异常。
(3)Scope: 实例生效的范围,缺省的是page
2、为实例赋值:
<jsp: setProperty name=”” property =”” value=””>自己赋值
<jsp: setProperty name=”” property =”” param=””>表单提交
<jsp: setProperty name=”” property =”” >属性与表单里面的名字相同
<jsp: setProperty name=”” property =”*” >所有的属性都与表单里面提交的名字相同,
找到相同的就赋值,找不到就什么也不做
<jsp: setProperty name=”” property =”” value=”<%表达式>”>
注:
(1)Name: 实例的名字,与useBean的id 对应
(2)Property: 属性的名字
(3)Value:给属性赋的值
(4)Param: 表单提交给属性赋值。
3、取得实例的属性
<jsp: getProperty name=”” property =”” >:取得实例的一个属性,返回值都为字符串的形式,
注意如果要跟数据库中表对应的时候,注意中间javaBean的设计需要同时可以与两边转化。(date类型的示例)
三、JSP页面中的异常处理
(一)一般步骤:
1、在每一个JSP页面中,声明错误处理的页面:
eg.<%@page errorPage=“errorpage.jsp”%>
2、声明一个错误的页面,本页面应该包含:
eg.<%@ page isErrorPage=”true”>
在错误页面里面,就可以使用系统内置的对象exception.调用它的toString()方法,就可以显示错误信息。
3、还可以在web.xml文件中配置出错之后,页面的流转。例如
<error-page>
<error-code>404</error-code>
<location>/notFound.html</location>
</error-page>
4、常见的错误编号:
404:所访问的页面没有找到
500:服务器内部异常
四、内置对象
(一)内置对象列表
变量 | 变量的类型 | 范围 |
Request | Javax.servlet.http.HttpServletRequest | Request |
Response | Javax.servlet.http.HttpServletResponse | Page |
pageContext | Javax.servlet.jsp.PageContext(jsp特有) | Page |
Session | Javax.servlet.http.HttpSession | Session |
Application | Javax.servlet.ServletContext | Application |
Out | Javax.servlet.jsp.JspWriter | Page |
Config | Javax.servlet.ServletConfig | Page |
Page | Javax.servlet.jsp.HttpJspPage | page |
exception | Java.lang.Throwable |
|
(二)内置对象的声明周期和可见范围
1、不同范围对象的共同点,都有下列方法
(1)setAttribute (String key , Object value)
(2)Object getAttribute (String key )
(3)void removeAttribute(String key )
2、不同点
生命周期和可见范围不同,范围如下:
pageContext à request à session à application
生命周期和可见范围越来越长
3、PageContext的使用
(1)通过pageContext对象可以有两种设置不同范围的属性的方法
pageContext.setAttribute( String key ,Object value, int scope);
int 值的取值有:
1)PageContext.PAGE_SCOPE;
2)PageContext.REQUEST_SCOPE;
3)PageContext.SESSION_SCOPE;
4)PageContext.APPLICTION_SCOPE
5)PageContext.getAttribute(String key );
(2)PageContext.findAttribute(String key ):
从小到大的范围开始查找, 返回的是找到的第一个对象。