1 JSP简介
1.1 JSP概念
Java 服务器页面 (Java Server Page ,JSP)
起源:(servlet的缺点—开发页面困难,代码不易维护)
定义: JSP是Java Server Pages的缩写,是由 Sun公司倡导、许多公司参与,于1999年推出的一种动态网页技术标准。JSP是基于Java Servlet 以及整个Java体系的Web开发技术,利用这一技术可以建立安全、跨平台的先进动态网站。
特点:
Jsp是一种动态页面编写技术(ASP,PHP等);
Jsp允许在页面中包含java代码;
Jsp文件的扩展名为.jsp;
用一公式来概括:
Jsp=html+java片段+jsp标签(语法)+js(css)
1.2 JSP页面简介
1.3 JSP 执行过程
1、首先,客户端发出请求(request ),请求访问JSP网页
2、接着,JSP Container将要访问的.JSP文件 转译成Servlet的源代码(.java文件)
3、然后,将产生的Servlet的源代码(.java文件)经过编译,生成.class文件,并加载到内存执行
4、最后把结果响应(response )给客户端
执行JSP网页文件时,需要经过两个时期:转译时期(TranslationTime)和请求时期(RequestTime)。
转译时期:JSP转译成Servlet类(.class文件)。
请求时期:Servlet类(.class文件)执行后,响应结果至客户端。
转译期间主要做了两件事情:
(1)将JSP网页转译为Servlet源代码(.java),此段称为转译时期(Translation time);
(2)将Servlet源代码(.java)编译成Servlet类(.class),此阶段称为编译时期(Compilation time)。
其实,JSP就是一个Servlet。
2 JSP脚本元素指令及动作
2.1 脚本元素
1 表达式:表达式是对数据的表示,系统将其作为一个值进行计算和显示
表达式在JSP页面中的表现形式
<%= Java表达式 %>
2 JSP Scriptlet:JSP Scriptlet就是在JSP页面里嵌入一段Java代码,也称脚本代码段
JSP Scriptlet在JSP页面中的表现形式
<% Java代码 %>
3 JSP 声明:JSP声明就是在JSP页面中声明Java方法或变量等(用于定义JSP代表的Servlet类的成员变量和方法 )。
JSP声明在JSP页面中的表现形式
< % ! Java 代码 %>
2.2 指令
指令:用于配置JSP页面,导入资源文件。
指令格式
<%@ 指令名称 属性名1="属性值1" 属性名2="属性值2" ...%>
1 Page指令用来定义整个JSP页面的一些属性和这些属性的值。属性值总是用单引号或双引号括起来。
Page指令格式
用一个page指令指定多个属性的值
<%@ page 属性1= “属性1的值” 属性2= “属性2的值” ……%>
用多个page指定为每个属性指定值
<%@ page 属性1= “属性1的值” %>
<%@ page 属性2= “属性2的值” %>
……
<%@ page 属性n= “属性n的值”%>
Page指令作用范围
page指令的作用对整个JSP页面有效,与其书写位置无关,但习惯把page指令写在JSP页面的最前面。
2 include 指令用于在运行时将 HTML文件或 JSP页面嵌入到另一个 JSP页面(为了代码的重用,写好的jsp页面可以被所有的其他jsp页面进行引用)
include 指令语法 :<%@ include file = ”文件名” %>
3 taglib指令可以让JSP页面使用标签
taglib 指令的作用是在JSP页面中,将标签库描述符文件引入到该页面中,并设置前缀,而去利用标签的前缀去使用标签库表述文件中的标签
<%@ taglib uri = ”标签库表述符文件” prefix = ”前缀名”
2.3 动作
动作格式
<jsp:动作名称 属性1="属性值1" 属性2="属性值2" … 属性n="属性值n”/>
1 include是动态包含,在运行期间进行嵌套,生成多个servlet类;
包含和被包含的jsp访问的虽然不是同一个request内嵌对象,但是被包含的jsp文件可以访问包含jsp文件能够访问的参数;
可以传参数;
Include动作标记语法格式
<jsp:include page=“文件的URL”/>
或
<jsp:include page =“文件的URL”>
param子标记
</jsp:include>
动态include和静态include的区别
2 Param标签以“名字—值”对的形式为其它标签提供附加信息,这个标签与jsp:include、jsp:forward、jsp:plugin标签一起使用。
param动作标记语法格式
<jsp:param name=“名字” value=“指定param的值”/>
3 forward 动作用于将用户的请求转发给其他页面
jsp:forward page=“文件的URL”/>
或
<jsp:forward page =“文件的URL”>
param子标记
</jsp:include>
4 plugin标签指示JSP页面加载java plugin,该插件由客户负责下载,并使用该插件来运行Java applet。
plugin动作标记语法格式
<jsp:plugin type="applet" code="小应用程序的字节码文件"
jreversion="java虚拟机版本号" width="小程序宽度值" height="小程序高度值" >
<jsp:fallback>
提示信息:用来提示用户的浏览器是否支持插件下载
</jsp:fallback>
</jsp:plugin>
5 寻找或者实例化一个JavaBean。
3 JSP隐式对象(内置对象)
3.1隐式对象的分类及组成
JSP隐式对象是Web容器加载的一组类的实例
它不像一般的Java对象那样用”new”去获取实例,而是可以直接在JSP页面的JAVA程序片和表达式部分使用的对象。
JSP 使用 Java 定义的隐式对象来访问网页的动态内容隐式对象的名称是 JSP 的保留字
JSP提供了一些隐式对象可简化开发。
3.2 存放数据的4大范围
page只在当前页面范围内有效
request可以在请求转发时在多个页面之间共享数据
session在当前应用中针对当前用户共享数据
application当前应用中跨用户数据共享
3.3 9大内置对象
page this 封装页面对象,该对象代表了正在运行的由JSP文件产生的类对象,相当于this。一般情况下不建议使用该对象
request ServletRequest,封装请求对象,代表的是来自客户端的请求HttpServletRequest。包括从GET/POST请求传递过来的参数
response ServletResponse,封装响应对象,代表的是对客户端的响应HttpServletResponse。网页传回客户端的信息
application ServletContext,封装应用程序对象,负责提供应用程序在服务器中运行时的一些全局信息,是一个容器级的共享对象数据
session HttpSession 封装会话对象,代表服务器与客户端所建立的会话,是javax.servlet.http.HttpSession接口。当需要在不同的JSP页面中保留客户信息的情况下用于跟踪用户状态。在客户端允许时,使用Cookie支持;否则一般使用URL重写来支持。即使不存在session引用,这个对象也是自动绑定的。但有一个例外,这就是如果你用page指令的session属性关闭了会话,此时对session变量的引用将导致JSP页面转换成Servlet时出错
config ServletConfig 封装代码配置对象,该对象提供一些该Servlet的配置信息,是javax.servlet.ServletConfig接口的实现
exception 异常信息的对象,封装异常对象,代表了JSP文件运行时所产生的并且没有被捕获的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了<%@ page isErrorPage="true "%>的JSP文件中使用
out 等价于response.getWriter() 封装输出对象,用来向客户端自定义输出内容,代表了向客户端发送数据的对象,是javax.servlet.jsp.JspWriter接口的实现。JspWriter是带缓冲的版本
pageContext 包装页面上下文对象,代表的是当前页面运行的一些属性,例如可以获取session、request、response、exception、ServletContext和ServletConfig的引用。是javax.servlet.jsp.PageContext接口的实现
4 JSP表达式语言(jsp EL)
4.1 简介
是expression language这两个英文单词的缩写(表达式语言)
它是jsp2.0规范中的一个技术,如果想解析el表达式的话,必须使用支持Jsp2.0/servlet 2.4(及以上版本)技术的web服务器(tomcat5.0以上版本)均支持el表达式
语法:${ expression}
4.2主要作用
1 获取数据
EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)
2 执行运算
利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}
获取web开发常用对象
3 EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
4 调用Java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
4.3.EL表达式中的".“和”[]"的用法
EL表达式提供".“和”[]"两种运算符来存取数据。
通常情况下两者是通用的:
${user.name}
${user[“name”]}
"[]"还可以用来对集合元素进行定位:
${booklist[0].price}
两种情况必须使用"[]":
1.包含特殊符号:
${user.first-name}错误写法
${user[“first-name”]}正确写法
2.通过变量动态取值:
${user[param]}
4.4 EL表达式的变量
范围优先级由高到低依次是:
Page、Request、Session和Application
4.5 EL运算符
5 JSP中使用数据库
5.1 JDBC概述
java数据库连接(Java Database Connectivity,JDBC)是一种用于执行SQL语句的Java API,由一组用 Java 编程语言编写的类和接口组成。
JDBC 为数据库开发人员提供了一组标准的API,使他们能够用纯Java API 来编写数据库应用程序。
JDBC访问数据库的流程
通过Class.forName加载驱动程序;
通过DriverManager类获得表示数据库连接的Connection类对象;
通过Connection对象绑定要执行的语句,生成Statement类对象;
执行SQL语句,接收执行结果集ResultSet;
可选的对结果集ResultSet类对象的处理;
必要的关闭ResultSet、Statement和Connection
JDBC常用API
5.2 连接数据库(MySQL)
1)加载JDBC数据库驱动程序
不同数据库厂商提供了不同的JDBC驱动程序,想要连接操作数据库时,就必须下载相应的JDBC。比如MySQL的JDBC可以去mysql的官网下载,将下载到的JDBC数据库驱动程序(mysql-connector-java*.jar)复制到Tomcat所使用的JDK的拓展目录中(../jre/lib/ext),或者复制到tomcat的安装目录/common/lib下
//应用程序加载MySQL的JDBC数据库驱动程序代码
try{
Class.forName("com.mysql.jdbc.Driver");
}catch(Exception e){}
2)与指定的数据库建立连接
Java.sql包中的DriverManager类中有两个用于建立连接的类方法(static方法):
Connection getConnection(java.lang.String,java.lang.String,java.lang.String)
Connection getConnection(java.lang.String)
它们都会抛出SQLException异常。DriverManger类调用上面的方法可以和数据库建立连接,返回一个connection对象。
假设mysql服务正常启动,其服务器ip为192.3.4.5,使用默认端口3306,用户root的密码是1234,并且对数据库sys有所有权限,那么建立连接代码如下:
//使用三个参数的方法
try{
String uri="jdbc:mysql;//192.3.4.5:3306/sys";
String user="root";
String password="1234";
con=DriverManager.getConnection(uri,user,pass);
}
catch(SQLException e){
System.out.println(e);
}
//使用一个参数的方法
try{
String uri="jdbc:mysql://192.3.4.5:3306/test?user=pinnsvin&password=pinnsvin";
con=DriverManger.getConnection(uri);
} catch(SQLException e){
System.out.println(e);
}
5.3.乱码解决
连接数据库支持中文编码
try{ Class.forName("com.mysql.jdbc.Driver");
}catch(Exception e){
System.out.print(“忘记把mysql数据库的JDBC驱动程序复制到JDK的拓展目录或tomcat*/common/lib中了");
}
try{
String uri="jdbc:mysql://127.0.0.1/test?user=pinnsvin&password=pinnsvin&characterEncoding=utf8";
con=DriverManager.getConnection(uri);
}
catch(SQLException e){
System.out.print(e);
}
5.4.操纵数据
1 查询
import java.sql.*;
public class JDBCDemo {
public static void main(String[] args) { //下面方法有不同的异常,我直接抛出一个大的异常
Connection con = null;
Statement stat = null;
ResultSet rs = null;
try{
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取数据库的连接对象
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sys", "root", "1234");
//3、定义sql语句
String sql = "select * from Student";
//4、获取执行sql语句的对象
stat = con.createStatement();
//5、执行sql并接收返回结果
rs = stat.executeQuery(sql);
//6、处理结果
while (rs.next()){ //循环一次,游标移动一行
System.out.println("id:" + rs.getString(1)); // 获取第一列的数据
System.out.println("name:" + rs.getString("name")); //获取字段为name的数据
System.out.println("age:" + rs.getInt(3)); // 获取第三列的数据
System.out.println("score:" + rs.getInt(4)); // 获取第四列的数据
System.out.println("-------------------");
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (con != null){ //避免空指针异常
//7、释放资源
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null){ //避免空指针异常
//7、释放资源
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){ //避免空指针异常
//7、释放资源
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2 添加
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) { //下面方法有不同的异常,我直接抛出一个大的异常
Connection con = null;
Statement stat = null;
try{
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取数据库的连接对象
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sys", "root", "123456789");
//3、定义sql语句
String sql = "insert into Student value('10004','李白',21,59)";
//4、获取执行sql语句的对象
stat = con.createStatement();
//5、执行sql并接收返回结果
int count = stat.executeUpdate(sql);
//6、处理结果
System.out.println(count);
}catch (Exception e){
e.printStackTrace();
}finally {
if (con != null){ //避免空指针异常
//7、释放资源
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null){ //避免空指针异常
//7、释放资源
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
3 修改
update Student set age = 20,score = 100 where id = '10002'
4 删除
delete from Student where id = '10001'
5.5预处理语句
Java提供了更高效的数据库操作机制,就是PreparedStatement对象,也就是预处理语句对象。
1.为什么使用预处理语句呢?
当向数据库发送一个SQL语句,数据库库中的SQL解释器负责将SQL语句生成底层的内部命令,然后执行该命令,完成有关的数据操作。如果不断的向数据库发送SQL语句就会增加数据库中SQL解释器的负担,影响执行速度。如果应用程序能针对连接的数据库,事先将SQL语句解释为底层的内部命令,然后直接然数据库执行这个命令,这样会降低解释器的压力,并且提高访问速度。
2.如何使用预处理语句?
使用Connection连接对象调用prepareStatement(String sql)方法对参数sql指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象pre中,pre可以调用下面的方法执行内部命令:
ResultSet executeQuery()
boolean execute()
int executeUpdate()
3.使用通配符
在对SQL进行预处理时可以使用通配符“?”来代替字段的值,必须在语句执行前设置通配符代表的值。
prepareStatement pre=con.prepareStatement("SELECT * FROM user WHERE age<?");
pre.setInt(1,18);//设置第一个通配符的值为18
5.6事务
1.什么是事务?
事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。事务是保证数据库中数据完整性与一致性的重要机制。
2.JDBC事务处理步骤
2.1.setAutoCommit(boolean autoCommit)方法
使用setAutoCommit(boolean autoCommit)方法关闭自动提交模式。
因为和数据库建立连接的对象con的提交模式是自动提交模式,即该连接con产生的Statement或PreparedStatement对象对数据库提交任何一个SQL语句操作会立即生效。为了能进行事务处理必须关闭con的自动提交模式(默认)。
con.setAutoCommit(false);
2.2.Commit()方法
con调用commit()方法可以让事务中的SQL语句全部生效。如果事务中任何一个SQL语句没有生效,就会抛出SQLException异常。
2.3.rollback()方法
在处理SQLException时,con必须调用rollback()方法,它的作用是:撤销引起数据发生变化的SQL语句操作,将数据库中的数据恢复到commit()方法执行之前的状态
6 JSP标准标签库--JSTL
6.1 JSTL全称及作用
1 JSTL简介
JSTL全名为JavaServer Pages Standard Tag Library。JSTL是由JCP(Java Community Process)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签函数库。
JSTL是一个标准的已制定好的标签库,可以应用于各种领域
JSTL所提供的标签函数库主要分为五大类:
核心标签库 (Core tag library)
I18N格式标签库 (I18N-capable formatting tag library)
SQL标签库 (SQL tag library)
XML标签库 (XML tag library)
函数标签库 (Functions tag library)
2 区别
在一个标准的JSP页面中可能会使用到如下的写法
<%= userList.getUser().getPhoneNumber() %>
使用JSTL搭配传统写法会变成这样
<c:out value="<%= userList.getUser( ).getPhoneNumber( ) %>" />
使用JSTL搭配EL,则可以改写成如下的形式
<c:out value="${userList.user.phoneNumber}" />
6.2 JSTL配置的方式
1 JSTL配置
JSTL 1.1必须在支持Servlet 2.4且JSP 2.0以上版本的Container才可使用
JSTL包括两个jar包:jstl.jar和standard.jar
演示在MyEclipse中添加JSTL
<%@ page contentType="text/html;charset=GB2312"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>测试你的第一个使用到JSTL的网页</title>
</head>
<body>
<c:out value="欢迎测试你的第一个使用到JSTL的网页" />
</br>
你使用的浏览器是:
</br>
<c:out value="${header['User-Agent']}" escapeXml="true" />
</br>
<c:set var="a" value="David O'Davies" />
<c:out value="${a}"/>
</body>
</html>
Web.xml
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tld/c.tld</taglib-location>
</taglib>
</jsp-config>
6.3 表达式操作常用的标签及用法
1 核心标签库
7 Servlet概述
7.1 Servlet
1 什么是 Servlet?
Servlet 是Java Server Applet的简称,称为小服务器程序,用Java编写的服务器端程序,主要功能为:交互式地浏览和修改数据,生成动态Web内容
Servlet 是运行在服务器端的用java语言写的应用程序 ,此程序在服务器上运行以处理客户端请求
用来完成B/S架构下,客户端请求的处理
Servlet在容器中运行
常见的servlet容器: tomcat、jetty、Resin等
7.2 Servlet的基本工作模式
<1>客户端请求该 Servlet;
<2>加载 Servlet 类到内存;
<3>实例化并调用init()方法初始化该 Servlet;
<4>service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions());
<5>destroy();
<6>加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet;
<7>Server 创建一个 Servlet的实例;
<8>第一个客户端的请求到达 Server;
<9>Server 调用 Servlet 的 init() 方法(可配置为 Server 创建 Servlet 实例时调用,在 web.xml 中 标签下配置 标签,配置的值为整型,值越小 Servlet 的启动优先级越高);
<10>一个客户端的请求到达 Server;
<11>Server 创建一个请求对象,处理客户端请求;
<12>Server 创建一个响应对象,响应客户端请求;
<13>Server 激活 Servlet 的 service() 方法,传递请求和响应对象作为参数;
<14>service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息;
<15>service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如 doGet() 或 doPost() 或程序员自己开发的新的方法;
<16>对于更多的客户端请求,Server 创建新的请求和响应对象,仍然激活此 Servlet 的 service() 方法,将这两个对象作为参数传递给它。如此重复以上的循环,但无需再次调用 init() 方法。一般 Servlet 只初始化一次(只有一个对象),当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法。
7.3 Servlet实现
1 编写servlet类
所有的 Servlet必须实现javax.servlet.Servletjavax.Servlet接口
通过扩展这两个类实现:
javax.servlet.GenericServletjavax.GenericServlet
跨协议的 ServletServlet
javax.servlet.HttpServletjavax.HttpServlet
HTTP ServletHTTP Servlet
2 Web.xml中进行配置
<servlet>
<servlet-name>clientservlet</servlet-name>
<servlet-class>chapter2.ClientServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>clientservlet</servlet-name>
<url-pattern>/clientservlet</url-pattern>
</servlet-mapping>
7.4 Servlet 的生命周期
生命周期的 3个方法为:
init()
在Servlet的生命周期中,仅执行一次init方法,是在服务器装入Servlet时执行的
缺省的init()方法设置了Servlet的初始化参数,并用它的ServletConfig对象参数来启动配置
service()
在调用service()方法之前,应确保已完成init()方法
service()方法是Servlet的核心。
每当一个客户请求一个HttpServlet对象,该对象的service()方法就被调用
缺省的服务功能是调用与Http请求方法相应的do功能
当一个客户通过HTML表单发出一个HTTP POST请求时,doPost()方法被调用
当一个客户通过HTML表单发出一个HTTP GET请求或者直接请求一个URL时,doGet()方法被调用
destroy()
在服务器执行reload时执行该方法
当关掉服务器或在指定的时间间隔过后调用destroy()方法