Java平台的企业版

来源:互联网 发布:网络女强与传统女强 编辑:程序博客网 时间:2024/04/29 16:26
J2EE: Java平台的企业版
J2SE: 标准版
J2ME:微型版(Micro)


J2EE课程内容:
Servlet
JSP(Java Server Page)
JDBC
JavaBean
设计模型,有两种
Struts1
Struts2
Hibernate
Spring
SSH(Struts + Spring + Hibernate)


开发工具:Eclipse + Mysql + Tomcat


Web程序 也就是B/S程序 (Browser Server)   


C/S程序(Client Server)
1. 客户目标范围有限
2. 网络范围小
3. 升级困难



用户通过浏览器访问Web服务器,之间通过Internet网络传输信息
Internet网络是基于TCP/IP协议进行连接
TCP/IP协议分为四层:网络接口层、Internet层、传输层、应用层(Web开发、应用)
应用层常用协议:HTTP(超文本传输协议;HTTPS是HTTP的安全版)、FTP、SMTP、POP3
HTTP协议:超文本传输协议 (Hyper Text Transfer Protocol),是用于Web服务器传输HTML到浏览器的通信协议
HTTP基于请求/响应形式,无状态


浏览器与服务器通信的步骤:
1. 建立TCP/IP连接
2. 客户端向服务器端发出请求
3. 解析请求信息
4. 服务器端向客户端发出响应
5. 客户端接收响应

客户端浏览器:IE7、8、9   FireFox  Chrome  Opera


Web服务器:硬件、软件
1. Apache (htpp://www.apache.org)
2. IIS window自带的服务器
3. Tomcat  (http://tomcat.apache.org)


应用服务器:首先是web服务器软件,然后比web服务器软件多部分功能(比如:事务、安全等)
1. Tomcat 支持的功能较少(Java Servlet和JSP,HTML)
2. WebLogic 市场占有率较高,价格高
3. JBoss 开源免费,支持EJB



Servlet大纲
1. Servlet技术及其作用
2. Web应用的基本目录结构 与 Eclipse中工程目录的 区别
3. Servlet的结构 Servlet接口 ——> GenericServlet抽象类 ——> HttpServlet抽象类
4. Servlet生命周期
init()  方法由容器调用,当第一次请求该Servlet,若再次请求则不再调用,生命周期内只执行一次
service()  用于判断请求类型,执行对应的处理方法(doGet还是doPost) 我们一般不重写
destory()  用于销毁该Servlet对象,释放内存
5. Servlet API
HttpServlet抽象类 、GenericServlet 、Servlet
doGet initinit
doPost service service

HttpServletRequest接口  extends  ServletRequest
request.setCharacterEncoding("utf-8");
request.getParameter("name")  获取请求参数(表单、url参数)


HttpServletResponse接口  extends  ServletResponse
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
response.getWriter();
response.isCommitted();

6. Servlet 在web.xml配置
<web-app ...>
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
</servlet>

<servlet-mapping>
<servlet-name></servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
</web-app>


7. Servlet 参数配置
ServletConfig接口,通过在Servlet里调用getServletConfig()方法获取ServletConfig对象
再调用ServletConfig对象的getInitParameter(name)方法获取Servlet参数值
或直接在Servlet中调用getInitParameter(name)获取Servlet参数值
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>

8. 上下文参数配置
ServletContext接口
getContext(String path) 用于获取ServletContext对象,path参数必须以斜杠"/"开头
getContextPath()  用于获取当前web应用的上下文路径
getInitParameter(name)
getRealPath(path)  用于返回指定path在服务器上的绝对路径
getRequestDispatcher(path)  path参数必须以斜杠"/"开头

<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>

9. 请求转发
从一个Servlet将请求转发到另一个Servlet或页面
javax.servlet.RequestDispatcher接口
forward(ServletRequest request, ServetResponse response)
include(ServletRequest request, ServetResponse response)
区别:forward在请求转发后当前Servlet的响应随之结束;
 include在请求转发后当前Servlet继续处理响应,被调用的Servlet做出的响应会并入到原先的响应中
 
获取RequestDispatcher对象的3种方法:
1. HttpServletRequest的getRequestDispatcher(String path)
2. ServletContext的getRequestDispatcher(String path)  path要以斜杠"/"开头
3.   getNamedDispatcher(String name)  name:部署配置文件中Servlet的名字

response.sendRedirect(String path) 首先响应当前请求,并让客户端重新发起指定path的请求



10. Tomcat连接池配置
1. 修改server.xml配置文件,在Context元素下 配置Resource元素属性
2. 代码中通过DataSource获取数据库连接对象

11. 会话
Cookie
是服务器发送给客户端的一组信息,并存储在客户的硬盘上,在随后的请求中发回
1. 在服务器端生成Cookie信息
2. 发送给客户端,由浏览器保存到客户硬盘上
3. 客户端接下来的请求会将Cookie信息发回给服务器

javax.servlet.http.Cookie类
public Cookie(String name, String value)
setMaxAge(int second)
getMaxAge()

setValue(String newValue)
getValue()
getName()


Session
服务器端记录客户的操作状态(如在线购物)
1. 客户第一次访问服务器的时候,服务器为其创建一个Session,并分配唯一的标识SessionID
2. 以后客户每次提交请求,都会将SessionID提交给服务器(通过Cookie传递)
3. 服务器根据SessionID获取对应的Session,再用这个Session记录客户的状态

javax.servlet.http.HttpSession接口,容器会提供该接口的实现
Object getAttribute(String name)
setAttribute(String name, Object obj)
removeAttribute(String name)

获取HttpSession对象方式:request.getSession()

Servlet
利用已实现HTTP协议的服务器端软件,这样的软件为我们留出了扩展的接口,只需要按照一定的规则去实现相应的扩展功能,
然后由服务器软件判断客户的请求是否是访问我们提供的扩展功能,如果是则将请求交由我们所写的程序处理;程序处理完成后
将结果交回给服务器软件,服务器软件再将结果作为响应返回给客户端。
优势:
1. 不需要过多了解HTTP协议
2. 只需完成自己的功能模块,最后部署到Web服务器


Java提供了编写扩展功能的技术 —— Servlet


Java Servlet是一个基于Java技术的Web组件,由Servlet容器所管理,用于生成动态页面。


Servlet容器 是Web服务器的一部分,用于在客户端发送的请求和服务器响应之上提供网络服务,并在Servlet的生命周期内包
容和管理Servlet。


课程采用Tomcat作为Servlet容器。


Servlet处理流程,分6步




Web应用的基本目录结构:
ProjectName
WEB-INF (* 不对客户端开放)
classes
lib  (存放扩展jar包)
web.xml (*工程配置信息)

index.html
index.jsp
/pages/...html jsp




web.xml文件基本结构
<web-app ...>

</web-app>


Servlet的结构
javax.servlet.Servlet  (接口)
javax.servlet.GenericServlet  (抽象类)
javax.servlet.http.HttpServlet(抽象类)


ServletRequest (接口)
Object getAttribute(String name)
Enumeration getAttributeNames()
void removeAttribute(String name)
void setAttibute(String name, Object ojb)
String getLocalAddr()  返回接收到请求的网络接口ip地址 (Server端ip)
String getLocalName()  Server主机名
String getLocalPort()  Server端口号
String getRemoteAddr()  返回发送请求的客户端ip地址(Client端ip)
String getRemoteHost()  Client名称
String getRemotePort()  Client端口号
String getServerName()  服务器的主机名
String getServerPort()服务器端口号
String getParameter(String name)  根据name值获取请求中的第一个参数值
Enumeration getParameterNames()  获取请求中所有的参数名
String[] getParameterValues(String name)  获取所有请求中名为name的参数值

ServletResponse  (接口)


HttpServletRequest extends ServletRequest
HttpServletResponse extends ServletResponse


Servlet生命周期

初始化  init()  当Servlet第一次被调用时,Servlet容器调用该Servlet的init方法 对其进行初始化操作,
并将该Servlet对象存放在Servlet容器里(在Servlet生命周期内,初始化操作只执行一次)

激活  service()  当请求调用该Servlet时,执行service方法 (当接收到HTTP请求时,由service方法来选择执行doxxx方法),
在Servlet生命周期内 server方法被调用n次

终止  destory()  当容器检测到Servlet实例应该从服务中被移除的时候,容器就调用该实例的destroy方法,可以释放所使用的资源,
随后该实例会被Java的垃圾回收器所回收。


1. 客户端发送请求,容器接收请求
2. 容器解析请求
3. 创建一个实例
4. 调用该实例的init方法初始化
5. 调用该实例的service方法
6. 该实例输出相应信息 给容器
7. 容器将相应信息放回给客户端
8. 最后调用该实例的destroy方法



web.xml配置扩展
<web-app>


<!-- 配置应用上下文参数 -->
<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>

<!-- 配置Servlet -->
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
<!-- 配置Servlet初始参数 -->
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
</servlet>
<!-- 配置Servlet映射 -->
<servlet-mapping>
<servlet-name></servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
</web-app>



Servlet Config接口
Servlet容器使用ServletConfig对象在Servlet初始化时向其传递配置信息。




练习:
1. 登陆页面,输入用户名、密码,提交按钮,重置按钮
login.html
2. 登陆成功、错误信息 作为Servlet参数 配置在web.xml里,信息通过响应输出(动态生成页面内容)
LoginServlet.java
登陆成功,您的登陆信息为:。。。(显示用户的ip地址、用户的端口号)

Servlet Context接口
每一个Web应用程序都有一个与之相关的Servlet上下文(ServletContext接口表示)。
作用:Servlet可以使用Servlet上下文提供的方法与Servlet容器进行通信(如请求转发、写入日志消息)


Servlet容器在Servlet初始化时,向其传递ServletConfig对象
获取ServletContext对象的方法:
ServletConfig对象的getServletContext()方法;
GenericServlet类的getServletContext()方法(其实就是通过调用ServletConfig对象的getServletContext()方法实现)


请求转发
一个Servlet作为控制器,可以将请求转发给另外一个Servlet或页面,然后由转发后的Servlet或页面进行处理并产生响应。

RequestDispatcher接口 提供了方法 能让请求从一个Servlet转发到另外一个Servlet或页面
RequestDispatcher对象是由Servlet容器创建。
接口中定义了两个方法:
public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
用于将请求从一个Servlet传递给另外的Servlet或页面(JSP、HTML);
必须在响应被提交前调用,否则抛出异常。
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
用于在响应中包含其他的资源(Servlet或页面)的内容。

两个方法不同点:include()方法将请求转发给其他的Servlet,被调用的Servlet对该请求做出的响应将并入原先的响应对象,
原先的Servlet还可以继续输出响应。
forward()方法将请求转发给其他Servlet,被调用的Servlet负责对请求做出响应,而原来Servlet终止执行。

得到RequestDispatcher对象方法:
1. ServletRequest接口中的 getRequestDispatcher(String path)方法
2. ServletContext接口中的 getRequestDispatcher(String path)方法  path参数必须以斜杠(/)开始
3. ServletContext接口中的 getNamedDispatcher(String path)方法


HttpServletResponse.sendRedirect() 与 RequestDispatcher的forward() 的区别
sendRedirect实现跳转的步骤:
1. Servlet调用sendRedirect方法,将客户端的请求重定向到另一个Servlet
2. 客户端访问另一个Servlet
3. 另一个Servlet对客户端请求作出响应

区别:
1. 请求响应次数不同
2. sendRedirect方法可以重定向到不同的Web应用程序或其他服务器上的Web应用程序



Servlet总结:
Servlet是Sun公司推出的一种技术,
Servlet是实现部分里的一个接口

Servlet包结构:
javax.servlet Servlet接口、GenericServlet抽象类
javax.servlet.httpHttpServlet抽象类

请求响应:
ServletRequest接口、ServletResponse接口
HttpServletRequest接口、HttpServletResponse接口

Servlet配置:
ServletConfig接口

Servlet生命周期: init()、service()、destroy()    doGet、doPost 。。。

Servlet上下文:
ServletContext接口

Servlet请求转发:
RequestDispatcher接口,forward、include
RequestDispatcher对象3种获取方法

sendRedirect() 与 forward()的区别


Web应用程序的部署
1. 每一个Web应用程序都一个起始目录,Tomcat默认起始目录在 \webapps\ROOT
2. 配置任意目录下的Web应用程序,可以在server.xml文件里进行配置
<Host> 元素  虚拟主机的配置,unpackWARs="true"  autoDeploy="true"
<Context> 元素  是Host元素的子元素
*docBase 指定Web应用程序的文档基础目录(该属性是必须)
path 指定Web应用程序的上下文路径。如果值为空字符串(""),则定义当前主机的默认Web应用程序
reloadable 如果值为true,Tomcat在运行时,会监视WEB-INF/classes和WEB-INF/lib目录下的改变,如果
发现有更新,Tomcat服务器自动重新加载该Web应用程序。(多用于开发阶段)
默认是false

3. Web应用归档
将整个Web应用程序打包成Web归档文件,然后部署到服务器
归档文件是.war文件

归档方式:
1. 命令提示符
2. 开发工具
3. 手动打包(基于编译后的)


4. Servlet配置  web.xml
<servlet>元素
<servlet-mapping>元素
url-pattern
1. 当Servlet容器接收到一个请求,首先确定该请求由哪一个Web应用程序来响应,通过比较请求URI的开始部分和
Web应用程序的上下文路径来确认
2. 映射到Servlet的路径是请求URI减去上下文的路径,将剩余部分按照路径映射规则进行处理
映射的规格:
1) 将请求的路径和Servlet映射的路径进行精确匹配,如果成功 则调用该Servlet来处理请求
2) 匹配最长的路径前缀,以斜杠(/)为路径分隔符,按路径树逐级递减匹配
3) 如果请求的URL最后有扩展名,如.jsp Servlet容器会去试着匹配
4) 容器调用默认的Servlet来处理,如果没有默认的Servlet,容器向客户端发送HTTP404错误信息
 
映射的语法定义
1) 以/开始并且/*结束 用来映射路径,比如 /demo/*   /demo/1、/demo/1/2
2) 以*.为前缀 映射扩展名
3) 以一个单独的/ 表示该Web应用程序的默认Servlet
4) 自定义的地址 用于精确匹配
 


 
Servlet + JDBC
JDBC:Java Database Connectivity,是Java应用程序编程接口,描述了一套访问关系数据库的标准Java类库
包java.sql和javax.sql
驱动程序类型:
1. JDBC-ODBC桥
2. 部分本地API,部分Java驱动程序
3. JDBC网络纯Java驱动程序
4. 本地协议纯Java驱动程序,优点:效率高

Java驱动程序 每个数据库厂商有各自的协议


元数据:用于描述数据库的各个组成部分的数据   用于查看数据库表本身的结构信息
DatabaseMetaData
ResultSetMetaData



可滚动和可更新的结果集
可滚动
ResultSet.TYPE_FORWARD_ONLY  结果集只能向下移动,就是不带参数的createStatement()方法的默认值
ResultSet.TYPE_SCROLL_INSENSITIVE  结果集可以滚动,对数据库的变化不敏感
ResultSet.TYPE_SCROLL_SENSITIVE  结果集可以滚动,对数据库的变化敏感

next();
previous();
first();
last();
isBeforeFirst();
isAfterLast();
isFirst();
isLast();


可更新
ResultSet.CONCUR_READ_ONLY  结果集只读,不恩能够用于更新数据库
ResultSet.CONCUR_UPDATETABLE  结果集可用于更新数据库
insert操作  updateXXX(String columnName, String value)  然后调用insertRow()
update操作  updateXXX(String columnName, String value)          updateRow()
delete操作  deleteRow()


可更新结果集使用的条件:
1. 只能针对数据库中单张表的查询
2. 查询语句中不能有join操作
3. 查询的表必须有主键



事务
保证所有的操作作为一个工作单元来执行,要么所有的操作都被提交,要么整个事务回滚到最初状态。

// 设置不自动提交
connection.setAutoCommit(false);

// 操作失败、不满足自定义条件、发生异常 的时候 事务回滚
connection.rollback();

// 所有操作都成功了 提交事务
connection.commit();


数据库连接池
javax.sql包中,定义了DataSource接口,提供了另一种方式来连接数据库。
连接池的基本方案:系统启动时,先直接创建若干个Connection对象,然后让它们被重复使用,这样就避开了
创建时间长的问题,性能得到提升

配置Tomcat的连接池和数据源
1. conf\server.xml配置文件中,找到应用对应的Context元素
2. 在Context元素内,添加Resource元素进行配置
name 指定资源名,相对于java:comp/env
auth 指定资源的管理者:Application和Container
type 指定资源所属的Java类,包含完整的包名+类名
maxActive 指定连接池中数据库连接的最大数目(0,表示没有限制)
maxIdle 指定连接池中保留的空闲数据库连接的最大数目(-1,表示没有限制)
maxWait 指定等待一个数据库连接成为可用状态的最大时间,单位毫秒(-1,表示永久等待)
username
password
driverClassName
url

3. 代码中通过DataSource获取连接对象
javax.naming.Context ctx = new javax.naming.InitialContext();
javax.sql.DataSource ds = (DataSource) ctx.lookup("java:comp/env/ResourceName");
java.sql.Connection conn = ds.getConnection();


JDBC总结:
1. 介绍JDBC驱动程序,4种
2. 安装MySql及其驱动
3. 回顾了JDBC API
1) 加载JDBC驱动
2) 建立数据库连接
3) Statement、PreparedStatement
4) ResultSet
5) 元数据(MetaData)
6) 事务处理
7) 可滚动、可更新结果集
4. JDBC数据源和连接池





Servlet+JDBC
1. 乱码,统一为UTF-8编码
1) 数据库默认编码、  数据库连接url参数设置编码
2) 请求\响应的编码
3) HTML页面编码(meta)、HTML文件编码

2. 参数的传递
1) url参数 默认是get请求类型,请求后跟问号?,再加‘参数名=参数值’,如: getInfo?bookId=1&bookName=aaa
2) html表单 有get和post请求类型
表单内部的控件 都有name属性,通过该属性可区分控件值的含义,如:<input name="title" />

3. 端口被占用,tomcat的默认端口8080
1) 可能被Oracle的监听服务占用,在系统的服务里将Oracle相关的服务关闭并设置为手动启动
2) tomcat进程未关闭,在任务管理器进程栏里关闭javaw.exe

4. 数据库连接信息的配置方式
1) web.xml里,配置<context-param>
2) server.xml,配置Context元素下的Resource元素
3) properties文件

5. Mysql数据类型 与 Java数据类型的对应关系
Integer、int int
Tinyint、Smallintshort
Bigint long
float float
double double
char、varchar String
Boolean、bit boolean
Date java.sql.Date
DateTime java.util.Date




会话跟踪
Session
会话:服务器能够标识出来自单个客户的多个请求,把这些请求组成一个单独的工作组。
 通过把特定的请求与一个特定的工作会话相联系,类似购物车的应用就能够把一个用户与另一个用于区分开。

状态:服务器能够记住客户前面的请求信息,以及对前一请求作出处理

1. Session信息保存在服务器内存中, Cookie保存在客户端硬盘
2. Session信息容量大, Cookie容量小
3. Session安全性高, Cookie文件可随意编辑


会话技术的实现:
在Java Servlet API里提供了HttpSession接口,由Servlet容器提供了实现。
当一个会话开始的时候,Servlet容器就创建一个HttpSession对象。
Servlet容器为HttpSession对象分配一个唯一的SessionID,将其作为Cookie发送给浏览器。
当客户端再次发送HTTP请求时,浏览器将Cookie随同请求一起发送,Servlet容器从请求中读取SessionID,根据
SessionID值找到对应的HttpSession对象,从而得到客户的状态信息。

客户端禁用Cookie是,可使用URL重写,就是在URL中嵌入标识客户的SessionID,Servlet容器解析URL,取出SessionID,
然后与特定的Session关联。
例如:http://www.niit.com/index.html;jseesionid=12345?name=a&id=1
HttpServletResponse接口中的encodeURL()方法来实现重写,例如:response.encodeURL("/servlet/demo");

javax.servlet.http.HttpSession接口


Session失效的条件:
1. 服务器关闭
2. Session超时
3. invalidate()方法设置失效


javax.servlet.http.HttpSessionBindingListener接口
如果一个对象实现了该接口,当这个对象被绑定到Session中或从Session中被删除,Servlet容器会通知这个对象,
该对象接到通知后,可以做一些自定义操作
例如:购物车中有一本书,该书对应的类实现了HttpSessionBindingListener接口,当Session超时的时候,容器就会通知
购物车对象 要从Session中被删除了。购物车对象得到通知后,可以把客户选购的书的信息保存到数据库中。
当客户再次访问网站的时候,可以将保存到数据库中的内容重新读取出来放到Session中,客户以前预购的商品仍然存在。

public void valueBound(HttpSessionBindingEvent event) 对象被绑定到Session中
public void valueUnBound(HttpSessionBindingEvent event) 对象从Session中被删除
容器通过调用 javax.servlet.http.HttpSessionBindingEvent对象 来通知实现HttpSessionBindingListener接口的对象
public HttpSessionBindingEvent(HttpSession session, String name)
public HttpSessionBindingEvent(HttpSession session, String name, Object value)
public String getName() // 绑定到Session或从Session中删除的属性名
public Object getValue() // 绑定到Session或从Session中删除的属性值(对象)
public HttpSession getSession() // 获取session


Cookies 由Netscape公司公司使用,是最常用的跟踪用户会话的方式。
Cookies是由服务器发送给客户的片段信息,存储在客户端浏览器的硬盘上,在客户访问服务器时会将Cookies在请求中发回。
存放目录: X:\Documents and Settings\当前用户名\Cookies
Cookies内容是以key=value形式保存的纯文本文件,可以通过专有的API来读取这些文本文件
作用: 由于HTTP协议是基于请求/响应的无状态形式,所以可用Cookies解决浏览器与Web服务器之前的状态通行。

API:
javax.servlet.http.Cookie
构造函数 public Cookie(String name, String value
方法:
String getName() 获取Cookie的name属性
setValue() 、 String getValue()  Cookie值
setDomain() 、String getDomain()  域名
setPath() 、 String getPath()  路径
setMaxAge() 、 String getMaxAge()  Cookie有效时间(单位:秒)


JSP
JSP - JavaServer Pages
JSP是一个建立在Servlet规范提供的功能上的动态网页技术(在网页文件中嵌入脚本代码,用于生成动态内容),类似于ASP、PHP

JSP的运行机制
1. JSP文件在用户第一次访问的时候,会被转换成Servlet文件
2. Servlet源文件类被编译生成class文件
3. Servlet容器加载并生成Servlet实例,并处理请求
4. 响应以HTML的格式发送到客户端

JSP执行时,容器会检查JSP文件是否有修改或更新,如果有则容器再次编译JSP或Servlet,如果没有则直接执行前面产生的Servlet

JSP API接口
Servlet
JspPage接口
HttpJspPage接口
HttpJspBase
.jsp文件



1. JSP语法
1) 代码注释
//
/* */
/** */

<!-- -->  HTML注释
<%-- --%> JSP注释(不会被前台页面源代码查看到)

2) 指令、指令元素
主要用于提供JSP页面相关信息的说明(类似于HTML中meta元素)
语法形式:
<%@ page|include|taglib {att=value} %>
起始:<%@   <与%、%与@之间不能有空格
结束:%>  %与>之间不能有空格

page指令:作用于整个JSP页面,定以页面的相关属性
<%@ page (13个属性) %>
属性:
*import="importList" 用于指定JSP中可以使用的Java类,属性值以逗号分割 或 可重复设置import属性
*contentType="text/html" 指定JSP页面响应内容类型及字符编码
*pageEncoding="" 指定JSP页面编码

language="java"
extends="className" 指定JSP转换后的Servlet类所继承的类

session="true|false" 用于指定当前JSP中是否可以使用session对象,默认是true
buffer="none|sizekb" 用于指定out对象使用的缓存大小,none则不使用缓存,默认8kb
autoFlash="true|false" 用于指定当缓冲区满的时候,缓存输出是否自动刷新。如果为false,当缓冲区溢出的时候,会抛出一个异常。默认true
isThreadSafe="true|false" 指定JSP页面的访问是否线程安全。
如果为true,则表明该页面可以同时被多个客户端请求访问,
如果false,JSP转换后的Servlet类是单线程运行模式
info="infoText" 指定页面的相关信息
errorPage="error_url" 当JSP页面发生异常时,将转向指定错误处理页面(如果一个页面通过该属性定义了错误页面,那么在web.xml中定义的任何错误页面将不会被使用)
isErrorPage="true|false" 指定当前JSP页面是否是 另一个JSP页面指定的错误处理页面
isELIgnored="true|false" 指定JSP是否不执行或忽略EL表达式,true则忽略,默认false

include指令:用于在JSP中静态包含一个文件,可以是JSP、HTML、文本文件
<%@ include file="url" %>

taglib
允许页面使用定制的标签
<%@ taglib uri="" prefix="" %>

2. JSP脚本
1) 声明脚本
用于在JSP页面中声明脚本语言中使用的变量和方法。
声明不会在当前页面的输出流中产生任何输出
声明只在当前JSP页面有效
在JSP页面转换为Servlet类时,在声明脚本声明的变量将作为该类的全局变量
<%!
(Java代码) 
%>

2) Scriptlet脚本
是在请求处理期间要执行的Java代码
可以产生输出
<%  (Java代码)  %>


3) 表达式
是Java语言中完整的表达式,请求处理后将结果转为字符串,并入到当前输出流中
表达式必须有结果,null也可转为"null"输出
<%= 表达式 %>

表达式最后不要添加分号结束符

3. JSP动作
动作元素为请求处理提供信息。

1. <jsp:useBean> <jsp:setProperty>和<jsp:getProperty>
2. <jsp:param> 以键值对的形式为其他标签提供附加信息
<jsp:param name="paramName" value="paramValue" />
3. <jsp:include page="url" flush="true|false">
用于在当前页面包含静态和动态的资源
page属性的值为相对于当前页面的路径
被包含的页面执行完毕后,请求处理在调用页面中继续进行。类似于RequestDispatcher的include方法
4. <jsp:forward page="url">
用于在当前页面将请求转发给另一个资源(HTML、Servlet、JSP),当前页面不再对响应做出处理
page属性的值为相对于当前页面的路径
这个动作会终止当前页面的执行,并且动作执行前响应的缓冲区不能被刷新。类似于RequestDispatcher的forward方法

4. 内置对象(JSP隐含对象)
request javax.servlet.http.HttpServletReqeust
response javax.servlet.http.HttpServletResponse
session javax.servlet.http.HttpSession
application javax.servlet.ServletContext
config javax.servlet.ServletConfig

pageContext javax.servlet.jsp.PageContext
out javax.servlet.jsp.JspWriter
page java.lang.Object
exception java.lang.Throwable



1) pageContext对象提供了访问其他内置对象的方法
getRequest()
getResponse()
getSession()
getServletContext()
getServletConfig()

getOut()
getPage()
getException()


pageContext对象还可以设置和得到其他范围对象中保存的属性
setAttribute(String name, Object object, int scope)
getAttribute(String name, int scope)
removeAttribute(String name, int scope)
removeAttribute(String name) 删除所有范围指定名字的属性
scope取值范围:PageContext.PAGE_SCOPE、PageContext.REQUEST_SCOPE、
  PageContext.SESSION_SCOPE、PageContext.APPLICATION_SCOPE
findAttribute(String name),按照page、request、session、application范围的顺序搜索指定名字的属性,找到则返回值,否则返回null
  
pageContext对象提供了请求转发的方法
forward()
include()

2) out
类型是JspWriter,用于以字符流的形式输出数据
out对象多个print()和println()

3) page
是当前JSP页面转换后的Servlet实例

4) exception
表示JSP页面运行时产生的异常,该对象只在错误页面中才可使用


5. 对象和范围
对象:包含用户创建的对象、JSP的内置对象,这些对象都有一个范围属性
范围:定义了在什么时间,在哪一个JSP页面中可以访问这些对象
1) page范围
具有page范围的对象被绑定到PageContext对象中,通过调用pageContext对象的getAttribute()方法来访问
在这个范围中的对象,只能在创建对象的页面中访问。pageContext对象本身也是属于page范围
当Servlet的_jspService()方法执行完毕,属于page范围的对象的引用将被丢弃。

2) request范围
具有request范围的对象被绑定到ServletRequest对象中,通过调用request对象的getAttribute()方法来访问
在调用forward()或include()方法转发请求时,被转发页面中可以访问request范围内的对象
因为请求对象对应每一个客户端或同一客户发出的多个请求对象是不同的,所以对于每一个新的请求,都要重新创建和删除这个范围的内的对象

3) session范围
具有session范围的对象被绑定到HttpSession对象中,通过调用session对象的getAttribute()方法来访问
服务器会为每一个会话,创建一个HttpSession对象,在会话期间 可以访问session范围内的对象

4) application范围
具有application范围的对象被绑定到ServletContext对象中,通过调用application对象的getAttribute()方法来访问
在Web应用程序运行期间,所有页面都可以访问application范围内的对象



JavaBean
为什么要在JSP中使用JavaBean?
JSP页面主要的作用是显示内容功能,为了完成动态的功能,在JSP中加入Java代码,随之造成页面维护困难的问题
为了解决该问题,需要减少页面中的代码量,所以此时引入了JavaBean技术

JavaBean是一个普通的Java类
1) 是一个public的类
2) 有一个默认的(不带参数的)构造方法
3) 包含一些属性及其对应的get、set方法

useBean动作
JSP页面里通过useBean动作来实例化JavaBean,并把实例的引用赋给一个变量
语法:
<jsp:useBean id="beanInstanceName"
class="package.className"
scope="page|request|session|application"
/>
id:用于标识JavaBean实例的名字,即脚本中变量名
class:指定JavaBean完整的类名
scope:指定对象的范围,不指定则默认为page

setProperty
用来设置JavaBean的属性值
语法:
<jsp:setProperty name="beanInstanceName"
property="属性名"
value="属性值"
/>
<% bean.setXXX(value) %>

getProperty
用来获取JavaBean的属性值
语法:
<jsp:getProperty name="beanInstanceName"
property="属性名"
/>
<% out.print(bean.getXXX(value)) %>


JSP开发的两种模型
模型一:使用JSP+JavaBean技术,将页面显示和业务逻辑处理(数据处理)分开。
JSP实现页面的显示;JavaBean用来保存数据、业务逻辑换算。


模型二:将JSP页面中的流程控制以及逻辑处理代码 提取出来,放到一个单独的角色中,这个角色就是控制器
使用Servlet+JSP+JavaBean技术,结合了三者优点,JSP页面主要负责数据的显示,流程和业务逻辑代码交给Servlet和JavaBean

Servlet的作用:进行对JavaBean的实例化;选择最终显示的JSP页面
JSP:只负责动态数据内容显示

模型二符合MVC架构模式。



MVC架构模式
M — Model 模型:数据相关
V — View 视图:只做显示功能
C — Controller 控制器:判断客户的请求,以显示哪个页面

优点: 三者各司其职,三者综合关联
有利于开发中的分工
有利于组件的重用
缺点: 系统的复杂度加强


基于MVC的Web框架
Struts 1.x 2.x
Webwork
Spring MVC



JSP EL (Expression Language)
表达式语言 主要作用:输出表达式或变量的值;减少JSP页面的代码、方便表达式和变量的输出;方便代码修改、美工维护简单
语法:${ 表达式或变量 }


算术运算符  + - * /(或div) %(或mod)
关系运算符  ==(eq) !=(nq) <(lt) <=(le) >(gt) >=(ge)
逻辑运算符  &&(and) ||(or) !(not)
条件运算符  a ? b : c
空运算符    empty 用来判断表达式结果或变量是否为null或空


使用El读取JavaBean对象
使用的操作符:“.”、“[]”


读取数组
${ arrayAttrName[index] } 等同于 array[index]

读取列表
${ listAttrName[index] } 等同于 list.get(index)


读取Map
${ mapAttrName[key] } 等同于 map.get(key)



EL内置对象 11个
pageContext  可以访问ServletContext、Request、Response、Session对象等
pageScope  获取页面范围内指定属性名的值
requestScope  获取请求范围内指定属性名的值
sessionScope  获取会话范围内指定属性名的值
applicationScope  获取应用范围内指定属性名的值

param  获取请求中的参数值  等同于request.getParameter(String name)
paramValues  获取请求中的参数值  等同于request.getParameterValues(String name)
header  获取请求头部的信息值  等同于request.getHeader(String name)
headerValues  获取请求头部的信息值  等同于request.getHeaders(String name)
cookie  等同于从request.getCookies()获取的Cookie[]中,返回匹配名字的第一个Cookie对象,例如:cookie.cookieName.value
initParam  获取Web应用初始化参数值,在web.xml中<context-param>元素配置的参数
  等同于ServletContext.getInitParameter(String name)

JSTL
JavaServer Pages Standard Tag Library   JSP标准标签库
主要作用:简化JSP页面的设计,优化脚本,提高开发效率
5个标签库
* Core http://java.sun.com/jsp/jstl/core c
* I18N(Format)http://java.sun.com/jsp/jstl/fmt fmt
SQL http://java.sun.com/jsp/jstl/sqlsql
XML http://java.sun.com/jsp/jstl/xmlxml
* Functions http://java.sun.com/jsp/jstl/functions fn

下载安装JSTL
http://jstl.java.net/


Core核心标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
1. 变量相关操作
1) out
2) set
3) remove
4) catch

2. 条件
1) if
2) choose
3) when
4) otherwise

3. 循环(迭代)
1) forEach
2) forTokens

4. URL相关
1) import 引用其他上下文资源时,需要在当前应用配置中设置crossContext="true"
2) url
3) redirect
4) param


Functions标签库
是标准EL函数集,定义了对字符串进行操作的函数
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
语法:${ fn:functionName(param...) }


I18N(Format)标签库
国际化部分:
1) requestEncoding 设置请求字符编码集,与request.setCharacterEncoding("utf-8")一样
2) setLocale 设置语言
3) bundle  basename属性指定资源文件基名,包括路径+文件名(不含本地化后缀和扩展名)
作用范围:标签体内
4) setBundle
5) message

资源文件中文处理:
命令行中输入: native2ascii -encoding utf-8 sourcefile.properties newfile.properties
Properties插件:http://propedit.sourceforge.jp/eclipse/updates/


格式化部分:
1) timeZone  用于指定时区,作用范围:标签体内
2) setTimeZone
3) formatDate  只设置value属性时,结果只输出日期部分   将Date对象转为String输出
4) parseDate  String -> Date
5) formatNumber  数字 -> String输出
6) parseNumber  String -> 数字



Servlet过滤器
1. 用于截取请求和响应
2. 用途:用户登录验证、用户权限验证、Web应用的访问统计、数据内容的处理
3. 实现
API:
1) javax.servlet.Filter接口
init
doFilter
destory

2) javax.servlet.FilterConfig接口
getInitParameter
getInitParameterNames
getServletContext

3) javax.servlet.FilterChain接口
doFilter


过滤器配置


生命周期
服务器启动时,实例化过滤器对象,再通过调用init方法初始化过滤器对象
服务器判断当前请求需要被过滤时,调用过滤器的doFilter方法
服务器关闭时,调用过滤器的destroy方法释放资源


过滤器链
顺序由配置文件中过滤器配置前后位置决定


Servlet监听器
在Web应用中 用于响应特定对象(application、session、request)的事件

实现监听器的方式: 编写一个类,实现对应的监听器接口

ServletContext监听器
1) ServletContextListener接口
public void contextInitialized(ServletContextEvent e) 上下文对象初始化时(即服务器启动 容器加载当前应用)
public void contextDestroyed(ServletContextEvent e) 上下文对象销毁时(即服务器关闭 容器销毁当前应用)

2) ServletContextAttributeListener接口
public void attributeAdded(ServletContextAttributeEvent e) 
上下文对象添加新属性时(<% application.setAttribute("user", "admin"); %>)
public void attributeReplaced(ServletContextAttributeEvent e) 
上下文对象更新属性时(再次执行<% application.setAttribute("user", "admin111"); %>)
public void attributeRemoved(ServletContextAttributeEvent e)
上下文对象删除属性时(<% application.removeAttribute("user"); %>)

HttpSession监听器
1) HttpSessionListener
void sessionCreated(HttpSessionEvent se) session对象创建时
void sessionDestroyed(HttpSessionEvent se) session对象销毁时

2) HttpSessionAttributeListener
void attributeAdded(HttpSessionBindingEvent se) 
void attributeReplaced(HttpSessionBindingEvent se) 
void attributeRemoved(HttpSessionBindingEvent se) 

3) HttpSessionBindingListener
void valueBound(HttpSessionBindingEvent event) 
当实现类的对象被添加到session中时,由容器调用对象的valueBound方法
void valueUnbound(HttpSessionBindingEvent event)
当实现类的对象从session被删除时,由容器调用对象的valueUnbound方法

4) HttpSessionActivationListener
容器为了更好利用有限资源,会将一些不频繁使用session对象临时序列化存放到硬盘
void sessionDidActivate(HttpSessionEvent se) “活化”,对象从硬盘中 读取到内存
void sessionWillPassivate(HttpSessionEvent se) “钝化”,对象从内存中序列化 存放到硬盘

ServletRequest监听器
1) ServletReqeustListener
void requestInitialized(ServletRequestEvent sre) request对象创建时
void requestDestroyed(ServletRequestEvent sre) request对象销毁时


2) ServletReqeustAttributeListener
void attributeAdded(ServletRequestAttributeEvent srae) 
void attributeReplaced(ServletRequestAttributeEvent srae) 
void attributeRemoved(ServletRequestAttributeEvent srae) 

配置监听器
在web.xml文件中添加<listener>
<listener>
<listener-class>com.niit.j2ee.CountListener</listener-class>
</listener>