本帖最后由 小石姐姐 于 2018-5-23 15:58 编辑
笔记 JDBC
Java Data Base Connectivity ( Java数据库连接 ) 数据库驱动 连各个设备 ( 应用 ) 之间通信的桥梁 JDBC的开发步骤第一步 : 加载驱动第二步 : 获得连接第三步 : 基本操作第四步 : 释放资源工具类package JDBCUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtils {
private static final String driverClassName;
private static final String url;
private static final String username;
private static final String password;
static{
Properties properties= new Properties();
try {
properties.load(new FileInputStream("src/db.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
driverClassName=properties.getProperty("driverClassName");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
}
/**
* 注册驱动的方法
*/
public static void loadDriver(){
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获得连接的方法
*/
public static Connection getConnection(){
Connection conn = null;
try{
// 将驱动一并注册:
loadDriver();
// 获得连接
conn = DriverManager.getConnection(url,username, password);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
/**
* 释放资源的方法
*/
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}配置文件
dcName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web_test3
username=root
password=123查询多条数据
@Test
/**
* 查询操作
*/
public void demo4(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL:
String sql = "select * from user";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
// 执行SQL:
rs = pstmt.executeQuery();
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("nickname"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}查询一条记录在like模糊查询后面直接写 ? ,如何在设置参数哪里在写 % 或者 _
@Test
public void demo4(){
Connection conn = null;
statement stmt = null;
ResultSet rs = null;
try{
注册驱动:
Class.forName("com.mysql.jdbc.Driver");
获得连接:
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3","root","123");
执行操作:
创建执行SQL语句对象
stmt = conn.preparedStatement ();
编写SQL语句:
String sql = "select * from user where id=4"; [如果能确定查出一条记录,可以不用while循环,如果不确定用while循环也可以]
执行SQL语句:
rs = stmt.executeUpdate (sql);
//[可以在这里写循环]
if(num > 0){
syso(rs.getInt("id")+" ");
syso(rs.getString("username")+" ");
syso(rs.getString("password")+" ");
syso(rs.getString("nickame")+" ");
syso(rs.getString("age")+" ");
}
}catch(Execption e){
e.prinStackTrace()
} }finally{
标准资源释放代码;
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
rs = null;
}
}添加操作
@Test
/**
* 保存操作
*/
public void demo1(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?,?,?,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "eee");
pstmt.setString(2, "abc");
pstmt.setString(3, "旺财");
pstmt.setInt(4, 32);
// 执行SQL
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("保存成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}修改操作
@Test
/**
* 修改操作
*/
public void demo2(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "abc");
pstmt.setString(2, "1234");
pstmt.setString(3, "旺旺");
pstmt.setInt(4, 23);
pstmt.setInt(5, 6);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("修改成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}删除操作
@Test
/**
* 删除操作
*/
public void demo3(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "delete from user where id = ?";
// 预编译SQL
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setInt(1, 4);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("删除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}工具类测试
public void JDBCDemo3{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
获得连接
conn = JDBCUtils.getConntion();
创建执行SQL语句对象
stmt = conn.preparedStatement ();
编写SQL
String sql = "select * from user";
执行查询
re.stmt.executeQuery(sql);
遍历结果集
while(rs.next()){
syso(rs.getInt("id")+" ");
syso(rs.getString("username")+" ");
syso(rs.getString("password")+" ");
syso(rs.getString("nickame")+" ");
syso(rs.getString("age")+" ");
}
}catch(Exception e){
e.printStackTrace();
}finally{
释放资源
JDBCUtils.release(rs,stmt,conn);
}
}批量处理
API介绍DriverManager 驱动管理类 作用一注册驱动 Class.forName("com.mysql.jdbc.Driver"); [ 固定写法 ] 作用二获得连接 getConnection (url , user , password ) ; url : 与数据库连接的路径 user :与数据库连接的用户名 password:与数据库连接的密码 url 的写法 jdbc:mysql://localhost:3306/web_test3 jdbc :连接数据库的协议 mysql :是jdbc的子协议 localhost :连接的MySQL数据库服务器的主机地址 ( 连接是本机就可以写成localhost ) 如果连接不是本机的,就需要写上连接主机的IP地址 3306 :MySQL数据库服务器的端口号 web_test3 : Connection 数据库连接对象 作用一创建执行SQL语句的对象 名字 . preparedStatement ( "这里写SQL语句" ) ; [ 有返回值,用sql的那个接收,起个变量名字 ] 执行SQL语句对象 statement :执行SQL CallableStatement :执行数据库中存储过程 PreparedStatement :执行SQL对SQL进行预处理 , 解决SQL注入漏洞 [常用的] 作用二管理事务 setAutoCommit :指定事务管理 commit ( ) :提交 rollback ( ) :回滚 Statement 执行SQL语句 作用一执行SQL语句 boolean execute ( sql语句 ) 执行查询 , 修改 , 添加 , 删除的SQL语句 [ 返回true ] ResultSet executeQuery ( sql语句 ) 执行查询 ( 执行select语句 ) int executeUpdate ( sql语句 ) 执行修改 , 添加 , 删除的SQL语句 作用二执行批处理 addBatch :添加批处理 clearBatch :清除批处理 executeBatch :执行批处理 在的代码里实际用的Statement 是 PreparedStatement 的父接口 PreparedStatement : ps 执行查询: ResultSet rs = ps . executeQuery ( ) ; 执行增 , 删, 改 int row = ps . executeUpdate ( ) ; ResultSet 结果集 通过 select 语句的查询结果 结果集遍历 next ( ) :将光标移到下一行
while(rs.next()){
syso(rs.getInt("id")+" ");
syso(rs.getString("username")+" ");
syso(rs.getString("password")+" ");
syso(rs.getString("nickame")+" ");
syso(rs.getString("age")+" ");
}结果集获取 getXXX ( ) :方法通常都会有一个重载的方法 getXXX ( int columnlndex列号 ) :传入列号 getXXX ( String columnName列名 ) :传入列名 getObject ( String columnName ) :通用
while (rs.next){
rs.getXXX (String columnName列名) ;
XXX 是 int string 等等;
columnName默认使用列名,如果起了别名,就用别名
}JDBC资源释放 JDBC城西执行完之后,要释放资源,通常是 ResultSet , Statement , Connection Connection对象是非常稀有的. 这个对象一定要做到尽量晚创建,今早释放掉 将资源释放的代码写到 finally
finally{
标准资源释放代码;
if( rs != null ){
try{
rs.close();
}catch( SQLException e ){
e.printStackTrace();
}
rs = null;
}
}DBUtils的使用ResultSetHandler的实现类ArrayHandler 和 ArrayListHandler 了解就好!!!ArrayHandler将一条记录封装到一个数组当中,这个数组应该是Object [ ] ArrayListHandler将多条记录封装到一个装有Object数组的List集合中 重要!!!BeanHandler 将一条记录封装到一个JavaBean中 BeanListHandler 将多条记录封装到一个装有JavaBean的List集合中 错误解决办法实体类私有名字和数据类字段名不一致时,采用表字段别名的方式匹配封装 一个JavaBean的属性不是实体类里面的私有定义的,而是根据get/set方法来获取, 实体类里面,加上无参方法,因为JavaBean默认使用无参 商城会用到!!!MapHeadler 将一条记录封装到一个Map集合中,Map的key是列名,Map的value就是表中列的记录值 MapListHeadler 将多条记录封装到一个装有Map的List集合中 ColumnListHandler(了解) 将数据中的某列的值封装到List集合中 ScalarHandler(计数用) 将单个值封装 KeyedHandler(了解) 将多条记录封装到一个装有Map集合中的Map集合中,而且外面的Map的key是可以指定的 XML可扩展标记语言,用户自定义标签!!! 作用:传输 和 存取数据 ,软件的配置文件 XML作为配置文件的方式完成模拟Tomcat XML使用区分大小写,不能有空格,标签必须有结束 文档声明 通常出现在XML的第一行第一列的位置!!! < ?xml 属性名 ="属性值"属性名 ="属性值“。。。? > version :必须有 。 使用1.0版本 encoding :字符集,是使用浏览器打开的时候采用的默认的字符集的编码 standalone :描述XML文档是否需要依赖其他的文档 注释 <!-- 这是注释 --> 快捷键 :Ctrl + Shift + / 元素(标签) 名称中不能包含冒号(:) 属性 命名规则和元素一致 属性需要使用引号! 特殊字符和CDATA区 CDATA区【character Data】 格式: < ![ CDATA [ ] ] > 重点!!!XML解析方式 从XML文档中获得想要的数据(通过代码完成的) XML的解析方式( ): DOM解析:DOM:Document Object Model【能做增删改】 SAX解析:Simple Api for XML 优缺点针对这两种解析方式,不同的公司提供了不同的API的实现 JAXP :SUN公司提供的一套XML的解析的API JDOM :开源组织提供了一套XML的解析的API-jdom DOM4J :开源组织提供了一套XML的解析的API-dom4j pull :主要应用在Android手机端解析XML 了解!!!DOM4J解析XML步骤分析【第一步】导入 jar 包 .dom4j-1.6.1.jar 【第二步】创建解析器 【第三步】解析文档获得代表文档的Document对象 【第四步】获得根节点 【第五步】从根节点下查找其他的节点 代码实现重点!!!Xpachdom4j支持XPath的 jar 包 dom4j的XPath支持的API: List document . selectNodes ( String xPath ); Node document . selectSingleNode ( String xPath ); 代码实现了解!!!模拟Tomcat重点!!!XML约束 就是用来约束XML的文档中可以出现那些标签,标签是否有顺序,出现次数 用来规范XML的写法 约束的种类及区别 DTD 和 Schema 区别 : 1,DTD语法自称一体的,Schema语法就是XML的语法 2,Schema的语法就是XML的语法所有更容易被解析器所解析 3,Schema支持名称空间 4,Schema有比DTD更加强大的语义和语法的约束 了解!!!编写DTD约束XML文档 内部DTD :< ! DOCTYPE persons [ ] > 外部DTD 一种本地DTD :<!DOCTYPE persons SYSTEM ”unknown.dtd“> 一种网络DTD :<!DOCTYPE persons PUBLIC”//UNKNOWN/“ ”unknown.dtd“> DTD的语法 元素:
<!ELEMENT 元素名 元素类型 >
元素类型:
EMPTY:
ANY :
子元素
是否有序:使用逗号(,)或者竖线(|)表示
出现的次数:?:零次或一次 +:一次或多次 *零次或多次
PCDATA
属性:
<!ATTLIST 元素名称 属性名称 属性类型 属性约束 >
属性类型:
ID类型:表示属性值需要是唯一的
CDATA类型:普通的字符串
枚举:
属性约束:↓↓↓↓↓出现Parse的时候就是有地方解析错了 代码实现编写Schema约束XML文档.xsd后缀名 代码实现被约束的XML文档,代码实现
tomcat
一个Web项目需要通过tomcat服务器被其他人访问到
软件的架构
C / S 架构的软件 :
Client / Server 客户端和服务器端的软件。都需要安装在PC端安装的软件,比如QQ,迅雷
优点:效果炫 ,一部分代码写到客户端(速度快)
缺点:服务器端更新,客户端都需要更新
B / S 架构的软件 :
Browser / Server 浏览器端和服务端的软件,不需要安装到PC端,只需要有一个浏览器即可,比如 京东,网银。。。
优点:服务器更新,客户端浏览器不需要进行更新
缺点:效果不炫,所有的代码运行都在服务端,导致服务器压力过大
效果:使用HTML5,CSS3可以做出很炫效果
服务器压力:搭建服务器的集群,而且还有 AJAX 技术
Web的资源
静态资源:
HTML,CSS,JS,图片。。
动态资源:
PHP :
ASP :
Servlet / JSP :
服务器
硬件:其实就是一台配置很高的电脑
软件:必须在一台电脑上安装服务器软件,这台电脑成为Web服务器
常见Web服务器【中间件】
Apache :发布PHP的,LAMP:Linux,Apache,MySQL,PHP
IIS :发布ASP的
WebSphere :IBM公司研发,收费的大型服务器软件,支持EE所有的开发规范
WebLogic :BEA公司研发,收发的大型服务器软件,支持EE所有的开发规范
Tomcat :Apache组织研发,免费小型服务器软件,支持Servlet/JSP的开发规范
JBoos :
Web动态资源目录结构
Website
|-----静态资源
|-----WEB-INF【路径】【动态必须有】
|-----web.xml :必须的
|-----classes :有没有一样
|-----lib :有没有一样
Tomcat目录结构
Server.xml :tomcat 核心
bin :tomcat 的执行的文件
conf :tomcat 的配置文件
logs :tomcat 的运行的日志文件
lib :tomcat 运行的需要的jar包
temp :tomcat 产生临时文件存放的路径
webapps :tomcat 发布的web项目的路径
work :tomcat 运行JSP的时候,JSP翻译成Servlet的代码存放的路径
发布WEB项目到Tomcat中
1 ,把一个项目打包成 . war 包,然后在放入webapps下
配置 tomcat虚拟路径
2,tomcat\conf\Catalina\localhost:新建一个xxx.xml,写< Context docBase=""/>,访问路径:xxx
Tomcat常见问题
【没有配置 JAVA_HOME 引发 tomcat 一闪小时】
一定要配置 JAVA_HOME 环境变量
【端口号冲突的问题】
第一种:将占用端口的应用结束
netstat -ano
打开任务管理器把应用结束
第二种:修改自身应用的端口号
tomcat / comf / server.xml里面的port后面的端口号
HTTP协议
用来规定浏览器(客户端)与服务器(服务端)之间需要遵守的规则【数据传递】
规定了双方交换数据的格式
特点
基于请求和响应的模型,【现有请求后又响应,必须成对出现】【端口号:80】
HTTP请求部分
请求行
提交方式:
GET :提交的参数会显示到地址栏上,在请求行中地址后面,有大小限制,没有请求体
POST :提交的参数不会显示到地址栏上,在请求体中,没有大小限制,有请求体
提交路径:都是固定的
协议版本:都是固定的
请求头
都是键值对的形式显示,一般一个key对应一个value,也有个别的是一个key对应多个value
User-Agent :代表浏览器的类型。-----可以看浏览器是用什么进行编码的【比如IE使用URLEncdor】
Referer :代表的是网页的来源。-----防盗链
If-Modified-Since :通常与响应中的头Last-Modified一起使用查找本地缓存
请求体
就是POST提交方式的提交的参数
HTTP响应部分
响应行
协议版本
状态码
200 :成功
302 :重定向
304:查找本地缓存
404:访问资源不存在【检查路径】
500:服务器内部错误
状态码描述
响应头
键值对的形式,一个key对应一个value,也有一个key对应多个value
Last-Modified :与请求中的If-Modified-Since一起使用查找本地缓存
Content-Dispostion :文件下载的时候使用的一个头信息【下载的时候有用】
Location :重定向的跳转的路径
Refresh :定时刷新 / 定时跳转
响应体
显示到浏览器的内容
Servlet
运行在WEB服务器上的小的Java程序,用来接收和响应从客户端发送过来的请求,通常使用HTTP协议
SUN公司提供的动态页面开发技术
作用
处理客户端浏览器发送的请求,并且可以对请求做出响应
使用
编写一个类实现Servlet接口
方法service 为用户处理请求和响应的方法
ServletRequest req:请求
http://ip:port/projectName/地址串
如果要访问一个servlet,这个地址串跟web.xml中配置的url-pattern有关系
String request.getParameter(String name):
String [] request.getParameterValues(String name):
Map< String,String[]> request.getParameterMap():
ServletString getParameter(String name) :用于接收一个名称对应一个值的数据 String [] getParameterValues(String name ) :用于接收一个名称对应多个值的数据 Map getParameterMap() :用于接收表单中的所有的数据,Map的key是表单提交的名称,Map的value是提交参数的值 Enumeration getParameterName() :用于获取表单中提交的所有的 Servlet生命周期 就是一个对象从创建到销毁的过程 servlet 生命周期:servlet从创建到销毁的过程 何时创建:用户第一次访问Servlet创建Servlet的示例 何时销毁:当项目从服务器中移除的时候,或者关闭服务器的时候 默认第一次用户访问Servlet的时候,服务器就会创建一个Servlet实例,里面的init方法就会执行,之后的每一次请求都以多线程的方式访问service方法,在service方法内部会根据请求方式不同调用不同的doXXX方法,当Servlet从服务器中移除或者关闭服务器的时候,Servlet实例就会销毁,destroy方法就会执行,并且Servlet从头到尾只创建一次 Servlet相关配置优化 有一些资源需要初始化,这个时候很耗时 第一次访问的时候初始化资源(耗时的步骤)以后访问都无需在初始化 那么优化的时候把这个耗时的操作放到服务器启动的时候 配置 Servlet默认在第一次访问的时候创建,启动时创建好,进行对Servlet的配置: 在web . xml 中在 < servlet > < /servlet >标签中设置: < load-on-startup > 2 < /load-on-startup > :传入整数,越小优先级越高,从2开始 url-pattern的配置第一种: 完全路径匹配 :以 / 开始 eg:/ServletDemo4 或者 /aaa/ServletDemo5 第二种 目录匹配 :以 / 开始 需要以 * 结束 eg:/*或者 /aaa/ * 第三种 扩展名匹配 :以 * 开始 *.do或者 *.action 如果访问地址: 优先级 完全路径匹配 > 目录匹配 > 扩展名匹配 【 * 号可以匹配所有字符】【一次请求只有一次响应】 开发中路径的编写 相对路径:都是需要找位置相对关系 , 不能以/ 开始 ./ 当前路径 ../ 上一级目录 绝对路径:不需要找位置相对关系 , 以 / 开始的 【写绝对路径】 绝对路径中分为客户端路径和服务器端路径: 客户端路径一定要加工程名 /day09/ServletDemo6 服务器端路径不需要加工程名 /ServletDemo6 定时跳转页面 使用HTTP协议中的Refresh头信息 addHeader(String naem , String value); 针对一个key对应多个value的响应头 setheader(String name,String value); 针对一个key对应一个value的响应头 重要ServletContext能存取数据,【域对象】,有一个变量存起来,在别的地方也能获得到 1,用来获得全局初始化参数 2,用来获得文件的MIME的类型【文件上传下载的时候】 3,作为域对象存取数据 SetAttribute( Object object ) 【存数据】
getAttribute( String name ) 【取数据】
removeAttribute( String name ) 【移除数据】作用范围:整个web应有的范围【整个Web项目】 创建:服务器启动的时候,tomcat服务器为每个web项目创建一个单独ServletContext对象 销毁:服务器关闭的时候或者移除的时候 4,用来读取web项目下的文件 Enumeration :枚举 【想象成集合,遍历】 hasMoreElements() 用while遍历(括号里写前面的){ 这里面写 nextElement }
response读取Web工程下的文件 用绝对路径 getProperty:获取属性文件里面的值 ServletContext读取Web项目[有Servlet环境的]读取属性文件步骤 获得SerletContext ServletContext conntext = this.getServletContext(); 第一步: 获取路径; InputStream getResourceAsStream(String path) InputStream is = context.getResourceAsStream(属性文件的绝对路径); 第二步: 创建一个属性对象 Properties pp = new Properties(); 第三步: 属性对象使用load()方法获取路径 pp.load ( is ); 第四步: String a =pp.getProperty("driverClass"); .........url.......username.......password...... setArrribute(String name,Object value); 存数据 Object getAttribute(String name); 读数据【有返回值】 removeAttribute(String name) 移除数据 ServletContext读取全局初始化参数 getInitParameter(String name):获取名字 获得全部的参数名字: Enumeration< String > e = this.getServletContext().getInitParamterNames(); 遍历: while(e.hasMoreElements()){ String name = e.nextElement(); 获取value值 String value = this.getServletContext().getInitParameter( name ); } 编写工具类读取属性文件Properties【没有servlet环境的】步骤如下: 编写静态类,使用类的加载器来读取文件 类的加载器用来加载class文件,将class文件加载到内存 //传入fileName属性名,和key属性文件里面的key
public static String readFile(String key,String fileName){
InputStream is = ReadFileUtils.class.getClassLoader().getResourceAsStream(fileName);
Properties PP = new Properties();
pp.load(is);
String value = pp.getProperty(key);
return value;
} String driverClass = pp.getProperty("driverClass"); String url = pp.getProperty("url"); String username = pp.getProperty("username"); String password = pp.getProperty("password"); Response响应对象 从服务器向浏览器输出内容 setStatus(int sc):设置状态码【响应行】 file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180516111706.png?lastModify=1526886402 文件下载的核心思想IO流的 读 / 写 inpuptStream in = new FileInputStream(“服务器上的路径”);【读】 Outputstream os = response.getOutputStream ( ) ; 【写】 模板代码读,写
int len = 0;
byte [] b = new byte[1024];
while((len = is.read(b))!=-1){
os.write(b,0,len);
}
is.close();file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180516151920.png?lastModify=1526886402 页面响应的方法: getOutputStream(); getWriter ( ) ; 这两个方法是互斥的 做出响应的时候只能使用其中的一种流响应 输出中文乱码的处理: 字节流:【文件下载】response. getOutputStream().write("hello Response....".getBytes()); 设置浏览器默认打开的编码 resposne.setHeader(“Content-Type”,“text;charset=UTF-8”); 设置中文字节取出的时候编码 “中文”.getBytes ( "UTF-8" ); 字符流: response.getWriter().println("Hello Writer Response"); response的字符流的缓冲区的默认的编码是ISO-8859-1根本不支持中文 设置浏览器打开的时候的编码 resposne.setHeader(“Content-Type”,“text;charset=UTF-8”); 设置response的缓冲区的编码 response.setCharacterEncoding(“UTF-8”); 简化的写法:response.setContentType( "text/html;charset=UTF-8" ); request request代表用户的请求 Request的API获得客户端信息: 获得请求的方式 getMethod(); 获得请求的路径 getRequestURL(); 获得客户机相关的信息IP地址 getRemoteAddr(); 获得工程名 getContextPath(); 获得表单参数 : String request. getParameter ( String name ) String[] request. getParameterValues ( String name ) Map< String ,String[] > request. getParameterMao (); 域对象:请求乱码的解决 POST: request.setCharacterEncoding(“UTF-8 ”);【设置在接收参数之前】 GET: String name = new String (request.getParameter("需要被编码的").getBytes("ISO-88599"),"UTF-8"); Request作为域对象存取数据 方法 setAttribute(String name,String value); Object getAttribute( String name ); removeAttribute ( String name ) ; 作用范围 一次请求的范围 创建和销毁: 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象 销毁:当服务器对这次请求做出了响应之后 重定向和转发的区别(redirect和forward的区别) 重定向:【地址栏会发生变化】【两次请求两次响应】【需要加工程名】【可以跳转任意网站】【存数据不能取到】 response.sendRedirect ( "客户端路径" ); 转发:【地址栏不变】【一次请求一次响应】【不需要加工程名】【只能在服务器内部进行转发】【能存取数据】 request.setAttribute ( "name","张三" );【存数据】 request.getRequestDispatcher ( "服务器路径" ).forward ( request , response );【转发】 会话技术 用户打开浏览器,访问很多网页,到最后关掉,其过程称之为一次会话,私有的数据,保存在会话技术 Cookie方法 将数据保存到客户端浏览器 向浏览器保存数据:HttpServletResponse有一个方法 void addCookie(Cookie cookie); response . addCookie (coo ); 获得浏览器带过来的Cookie:HttpServletRequest有一个方法: Cookie [ ] get Cookies ( ) ; cookie [ ] cookis = request . getCookies ( ) ; 创建一个Cookie对象: Cookie(String name , String value); Cookie coo = new Cokie(“指定名字”,“给什么值”); 获得Cookie的名称和值 getName();getValue(); 设置Cookie的有效域名 setDomain(String domain); 设置Cookie的有效路径【删除持久性的Cookie】 setPath(String path); coo.setPath ( ) 设置Cookie的有效时间【等多长时间,在规定时间操作,时间重置,接着等】 setMaxAge(int age); coo.setMaxAge ( 单位是秒 ) Cookie的分类会话级别的Cookie:默认的Cookie,关闭浏览器Cookie就会销毁 持久级别的Cookie:可以设置Cookie的有效时间,那么关闭浏览器Cookie还会存在,手动销毁持久性Cookie.setMaxAge ( 0 ) ----前提是有效路径必须一致 删除持久性的Cookie Cookie cookie = new Cookie(“跟前面名称一样”,null); cookie . setPath ("跟前面路径一样") ; cookie . setMaxAge ( 0 ) ; response . addCookie ( cookie ) ; response . sendRedirect ( "跳转的路径" ) ; Cookie存中文 编码 Cookie cookie = new Cookie ( "aa" , URLEncoder . encode ( "中文" , "UTF-8" ) ) ; response . addCookie ( cookie ) ; file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180517165717.png?lastModify=1526886418 解码 String a = URLDecoder . decode ( 获取的值,“UTF-8” ); file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180517165721.png?lastModify=1526886418 Session 将数据保存到服务器端 JSP Java Server Pages(Java服务器端页面)。JSP = Java代码 + HtML的元素 + JSP内置东西 JSP执行过程 JSP会被编译成Servlet 在JSP里面写代码 < %! Java代码 % > :翻译成类中的成员部分,定义成员变量,成员方法,定义类,Servlet是线程不安全,尽量少在类中定义成员属性!!【基本不用这个】 < % Java代码 % > :翻译成类的service方法内部的内容,定义变量,定义类,直接写代码块【可以写循环】 < %= Java代码 % > :翻译成service方法内部的out . print ( ) 【在页面打印了】 会话技术 用户打开浏览器,访问很多网页,到最后关掉,其过程称之为一次会话,私有的数据,保存在会话技术 Cookie方法 将数据保存到客户端浏览器,有大小和个数的限制 向浏览器保存数据:HttpServletResponse有一个方法 void addCookie(Cookie cookie); response . addCookie (coo ); 获得浏览器带过来的Cookie:HttpServletRequest有一个方法: Cookie [ ] get Cookies ( ) ; cookie [ ] cookis = request . getCookies ( ) ; 创建一个Cookie对象: Cookie(String name , String value); Cookie coo = new Cokie(“指定名字”,“给什么值”); 获得Cookie的名称和值 getName();getValue(); 设置Cookie的有效域名 setDomain(String domain); 设置Cookie的有效路径【删除持久性的Cookie】 setPath(String path); coo.setPath ( ) 设置Cookie的有效时间【等多长时间,在规定时间操作,时间重置,接着等】 setMaxAge(int age); coo.setMaxAge ( 单位是秒 ) Cookie的分类会话级别的Cookie:默认的Cookie,关闭浏览器Cookie就会销毁 持久级别的Cookie:可以设置Cookie的有效时间,那么关闭浏览器Cookie还会存在,手动销毁持久性Cookie.setMaxAge ( 0 ) ----前提是有效路径必须一致 删除持久性的Cookie Cookie cookie = new Cookie(“跟前面名称一样”,null); cookie . setPath ("跟前面路径一样") ; cookie . setMaxAge ( 0 ) ; response . addCookie ( cookie ) ; response . sendRedirect ( "跳转的路径" ) ; Cookie中文 编码 Cookie cookie = new Cookie ( "aa" , URLEncoder . encode ( "中文" , "UTF-8" ) ) ; response . addCookie ( cookie ) ; file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180517165717.png?lastModify=1526886437 解码 String a = URLDecoder . decode ( 获取的值,“UTF-8” ); file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180517165721.png?lastModify=1526886437 Session【HTTPSession】【域对象】 将数据保存到服务器端,没有大小和个数的限制,执行原理:基于Cookie 获得Session request . getSession ( ) ; HttpSession session = request . getSession ( ) ; 存数据 .session.setAttribute ( String name , Object value ) ; Object value = session . getAttribute ( String name ); 移除数据 removeAttribute( String name ); 创建: 服务器端第一次调用getSession ( ) 的时候创建 session 销毁:【三种】 第一种:session过期【默认30分钟】 【在web.xml里面】
<session-config>
<session-timeout>这写时间,单位:分钟</session-timeout>
</session-config> 第二种:非正常关闭服务器直接销毁 ,正常关闭session保存到硬盘里, 第三种:手动调用session . invalidate ( ) ; 作用范围: 多次请求【一次会话】【转发和重定向都能获得Session里面的值】 【根本原因:存SessionID的cookie默认是会话级别的】 登陆的核心 【要把用户信息保存到Session里面,任何在别的页面获取Session里面用户的值,判断Session里面用户信息等不等与null】 JSP Java Server Pages(Java服务器端页面)。JSP = Java代码 + HtML的元素 + JSP内置东西 JSP执行过程 JSP会被编译成Servlet类,编译这个Servlet的类,生成class文件,得到执行,并且不用配置web.xml 在JSP里面写代码【脚本】 < %! Java代码 % > :翻译成类中的成员部分,定义成员变量,成员方法,定义类,Servlet是线程不安全,尽量少在类中定义成员属性!!【基本不用这个】 < % Java代码 % > :翻译成类的service方法内部的内容,定义变量,定义类,直接写代码块【可以写循环】 < %= Java代码 % > :翻译成service方法内部的out . print ( ) 【在页面打印了,代码后面不能加分号】 JSP的东西注释 < !-- 注释 -- > :HTML注释【存在于生成的HTML中】 <//单行,//多行,/ 两个星/文档注释> :Java代码注释** 【源码中也有翻译成Servlet后注释也存在,但是当执行完JSP后生成HTML后,注释就消失了】 < %-- 注释 --% > :JSP注释 【只存在与源代码,翻译成Servlet后,JSP的注释就消失了】 指令【3大指令】 语法 < %@指令的名称 属性名称=“属性值” 属性名称=“属性值”....等等% > page指令: < %@ page % > :设置JSP的【通过属性设置JSP参数】 errorPage :设置错误友好页面的提示【路径不用加工程名,下面一起】 isErrorPage :通过这个设置显示JSP的错误信息【上面的一起使用】 设置全局的错误友好页面,在web.xml设置:
< error-page >
< error-code > 404 < /error-code >
< location > 404.jsp < /location >
< /error-page >
//写一个404的JSP的页面,然后有错误就跳转到这个404.jspinclude指令: 静态包含,指示JSP包含其他页面的,其他页面不需要前后,只写内容就好, < %@include file = "页面路径" % > taglib指令: 指示JSP引入标签库 < %@ taglib url="标签的rul的路径" prefix=“标签的别名”% > 内置对象【9大内置对象】 在JSP中可以直接使用的对象,在< %在这里面用,内置对象 . 方法% > 内置对象 真实对象 里面的方法,使用真实对象在API里面查 request HTTPServletRequest getParameter () ,setAttribute () response【域对象】 HttpServletResponse setHeader () ; getOutputStream session 【域对象】 HttpSession setAttribute () ;getAttribute () application ServletContext setAttribute () ;getAttribute () page Object toString () ;wait () pageContext【域对象】PageContext setAttribute () ;getAttribute () config ServletConfig getServletName();getServletContext() out JspWriter wtite () ;print () exception Throwable getMessage () ; getCause () page内置对象 :真实对象是Object,就是JSP翻译成Servlet后的类的引用 out内置对象 :out和response.getWriter不是同一个对象 out 真实对象是JapWriter,response获得Writer是PrintWriter响应只能是response做 pageContext内置对象【技能拔高的点】 < %= pageContext . findAttribute ("被查找的名称") %> :查找 获得其他的8个内置对象【getXXX方法获得】 :编写通用性代码或者框架的时候 向JSP的四个域中存取数据 PageScope :当前页面中有效 pageContext PageContext RequestScope :一次请求范围 request HttpServletRequest SessionScope :一次会话范围 session HttpSession ApplicationScope :应用范围 application ServletContext 向其他三个域范围存值【图第一个是往自己里面存值】 file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180519165518.png?lastModify=1526886437 取出值【图第一个是取自己里面的值】 file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180519165620.png?lastModify=1526886437 动作标签【一系列的】 作用:简化代码 < jsp: forward / > :用于页面转发 < jsp: forward page="转发的路径" >< /jsp: forward > < jsp: include / > :用于页面包含(动态包含) < jsp: include page=“被包含路径” >< /jsp: include > < jsp: param / > :用于带有路径的标签下,传递参数 静态包含和动态包含的区别【< %@include % > 和 < jsp:include >的区别】 静态包含:相当于源代码的拷贝,只会翻译成一个Java类,有一个执行结果 动态包含:各自分别去翻译,各自执行,最终包含的是执行的结果
EL 简化JSP的代码,简化尖括号 < % % > 语法:$ {EL表达式} 四个方面功能获取数据【 必须放在JSP的四个域里,然后才能获取,以什么名字存到域中,就以什么名字取出来,存的什么类型,取出来就是什么类型 】 数组,List集合: [ ] ------基本用来遍历 map,Java对象: . . 属性 获取单个值数据 ${ pageScope.name } -----取出指定域里面的单个值
${ name } -----取出域从小到大查找,然后取出单个值
name的类似findAttribute("name")先从page域中查找,没找到去request域中查找,没找到去session域中查找,没找到就去application域中找,都没找到返回" " 空,啥也不显示获取数组数据
String [] arrs = {"哈哈","呵呵","嘿嘿"};
pageContext.setAttribute("arrs",arrs); -----存入到域中
${ arrs } -----直接全部取出获取List集合数据
List<String> list = new ArrayList<String>();
list.add("哈哈");
list.add("呵呵");
list.add("嘿嘿");
pageContext.setAttribute("list",list); -----存入到域中
${ list }
${ list[0] } -----[]用于有下表的数据(数组,list集合)获取Map集合数据
Map<String,String> map = new HashMap<String,String>();
map.put("aaa","哈哈");
map.put("bbb","呵呵");
map.put("ccc","嘿嘿");
pageContext.setAttribute("map",map); -----存入到域中
${ map.aaa } -----点(.)用于有属性的数据(map,对象)
mao的特殊情况
存入: map.put("ddd.eee","嗯嗯");
取出数据: ${ map["ddd.eee"] }获取对象数据
User user = new User (1,"aaa","123") ----需要先创建以恶搞User类
pageContext.setAttribute("user",user); -----存入到域中
${ user.id } -----获取id获取对象的集合数据
User user1 = new User (1,"aaa","123") ----需要先创建一个User类 User user2 = new User (2,"bbb","123")
User user3 = new User (3,"ccc","123")
List<User> user = new ArrayList<User>();
pageContext.setAttribute("user",user); -----存入到域中
${ user1[0].id } - ${ user1[1].name } - ${ user1[2].sex }
${ user2[0].id } - ${ user2[1].name } - ${ user2[2].sex }
${ user3[0].id } - ${ user3[1].name } - ${ user3[2].sex }执行运算算数运算
pageContext.setAttribute("n1",20); -----存入到域中
pageContext.setAttribute("n2",10); -----存入到域中
${ n1+n2 } ---- +,-,*,/ 都这样写逻辑运算
${ n1 < n2 } - ${ n1 lt n2 } ----- less than 小于
${ n1 > n2 } - ${ n1 gt n2 } ----- great than 大于
${ n1 <= n2 } - ${ n1 le n2 } ----- less equal 小于等于
${ n1 >= n2 } - ${ n1 ge n2 } ----- great equal 大于的等于
${ n1 == n2 } - ${ n1 eq n2 } ----- equal 等于关系运算
${ n1 < n2 && n3 < n4 } --- ${ n1 < n2 and n3 < n4 } --- &&
${ n1 < n2 || n3 < n4 } --- ${ n1 < n2 or n3 < n4 } --- ||
${ !(n1 < n2) } --- ${ not(n1 < n2) } --- !() not()三元运算执行
${ n1 < n2 ? "正确":"错误" }empty运算
${ user == null } --- ${ empty user } ---是否 为空(empty)
${ user != null } --- ${ not empty user } ---是否 不为空(not empty)操作web开发的常用对象 pageScope,requestScope,sessionScope,applicationScope ---获取JSP域中的数据 ${ 用什么名字存的,这里就用什么名字取出来 } ---取数据 param ,paramValues --接收请求的参数【用不到】
${ param.id } ---比如 param里面有id,直接.(点)获取就好
${ paramValues.hobby } ---直接取出数组
${ paramValues.hobby[0] } ---数组取出单个值 header ,headerValues ---获取请求头信息【用不到】
${ header["User-Agent"] } ---特殊情况
${ header.写你想获取的的名字 } initParam ---获取全局初始化参数【用不到】
前提需要 web.xml 配置了一个
${ initParam.username } ----去除了username的全局初始化参数cookie ---Web开发中的cookie
${ cookie.history.value } ---获取cookie里面的history的value(值)
${ cookie固定的.cookie的名字是啥,中间写啥,value固定的 }pageContext ----Web开发中的pageContext
${ pageContext.request.remoteAddr } -----获取IP地址
${ pageContext.request.contextPath } -----获取工程名字,比如(day11) 调用Java中方法:------很少用 JSTLcore(核心标签)fmt(国际标签)xml(XML标签)sql(SQL标签)fn(JSTL提供EL函数库) core(核心标签)
引标签库:<%@ taglib url="http://java.sun.com/jsp/jst1/core prefix="c" %>
<c:set var ="n1" value="30" scope="page"></c:set> ---往page域里面存入名字叫n1
<c:set var ="n2" value="20" scope="page"></c:set>
<c:if test="${ n1 < n2 }"> n1小于n2 </c:if>
<c:if test="${ n1 >= n2 }"> n1大于等于n2 </c:if> --因为没有else,所以下一个if,需要从新写一个JSTL的常用标签
<c:out value="${ city }" default="北京"></c:out> ------city有值输出city的值,没有输出北京
<c:out value="<h1>标题1</h1>" escapeXml="false"></c:out>< c:if >判断
<c:set var ="n1" value="30" scope="page"></c:set> ---往page域里面存入名字叫n1
<c:set var ="n2" value="20" scope="page"></c:set>
<c:if test="${ n1 < n2 }"> n1小于n2 </c:if>
因为这个if没有else,所以别的判断,只能在写一个<c:if></c:if>
<c:if test="${ n1 < n2 }" var="flag" scope="page"> n1小n2 </c:if>【不要这样写】
把判断的结果,放到page域里面,名字是flag
<c:if test="S{ flag }"> n1小于n2 </c:if> ---判断上面的【不要这样写】遍历< c:forEach >var 是变量,items是等待遍历的对象,begin是那个开始,end是到多少,step是+多少,varStatus里面有两个 一个index下标索引,另一个count遍历到第几个了 遍历数组
String [] arrs ={"哈哈","呵呵","嘿嘿"}; ---创建数组
pageContext.serAttribute("arrs",arrs); ---放到page域里面
<c:forEach var="i" items="${ arrs }"> </c:forEach> ---遍历数组遍历List集合
List list = new ArrayList();
list.add("哈哈");
list.add("呵呵"); items表示待遍历的
list.add("嘿嘿");
pageContext.serAttribute("list",list); ---放到page域里面
<c:forEach var="i" items="${ list }"> ${ i } </c:forEach> ---遍历List集合Map集合遍历
Map<String,String> map = new HashMap<String,String>();
map.put("aaa","哈哈");
pageContext.serAttribute("map",map); ---放到page域里面
<c:forEach var="entry" items="${ map }"> ---遍历Map
${ entry.key } -- ${ entry.value } ---取出key 和 value
</c:forEach>遍历从1到10
<c:forEach var="i" begin="1" end="10" step="2"> ${ i } </c:forEach>遍历从100到300还根据条件变颜色
<c:forEach var="i" begin="100" end="300" step="5" varStatus="status">
<c:if test="${ status.count % 3 == 0 }">
<font color="red">S{ i }</font>
</c:if>
<c:if test="${ status.count % 3 != 0 }">
S{ i }
</c:if>EL的函数库操作字符串的
${ fn:contains("Hello World","Hello") } ----包不包含hello
${ fn:length("HelloWorld") } ---字符串的长度
${ fn:toLowerCase("ABCDE") } ---大写转小写
${ fn:split("a-b-c-d","-") } ---根据-切分,取出来是个数组,然后遍历一个动态网页 创建一个商品列表页面 创建一个表格, MVC开发模式:JavaBean + JSP + Servlet,就是MVC设计模式 M:Model 模型层 JavaBean V:View 视图层 JSP C:Controller 控制层 Servlet file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180520171532.png?lastModify=1526886450 file:///C:/Users/Administrator/Desktop/%25E5%259B%25BE%25E7%2589%2587/%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20180520151852.png?lastModify=1526886450 接收&封装
//接收全部数据数据
Map<String,String[]> map = request.getParameterMap();
//创建对象
User user = new User();
//封装全部数据数据
BeanUtils.populate(user,map);Servlet:接收数据 Servlet:创建对象 Servlet:封装数据 service:调用业务处理层 Dao:调用Dao,并返回处理完的结果 Servlet 转发到JSP
|