1.常见的状态码:
404:资源不存在;
200:一切正常;(一般看不见)
403:权限不足;
300/301:页面重定向(跳转);
500:服务器内部错误;(代码有误)
其他编码:需要积累;
2.jsp:在html中嵌套的java代码;
3.在项目/WEB-INF/web.xml中设置 默认的 初始页面:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
4.虚拟路径:
方式一:
将web项目配置到webapps以外的目录
conf/server.xml中配置
host标签中:
docBase:实际路径;
path:虚拟路径;(绝对路径、相对路径)
需要重启;
方式二:
tomcat\conf\Catalina\localhost中新建“项目名.xml”中新增一行:
<Context docBase="F:\tomcat\webapps\helloworld" path="/helloworld" />
5.虚拟主机:(不常用)
通过www.test.com访问本机;
配置conf/server.xml文件
<Engine name="Catalina" defaultHost="www.test.com">
<Host appBase="F:\tomcat\webapps\helloworld" name="www.test.com">
<Context docBase="F:\tomcat\webapps\helloworld" name="/"/>
</Host>
</Engine>
在C:\Windows\System32\drivers\etc\host中
增加
127.0.0.1 www.test.com
流程:www.test.com->host找映射关系->server.xml找Enginede defaultHost->通过“/”映射到F:\tomcat\webapps\helloworld
6.客户端访问服务端,JSP执行流程:
第一次访问:服务端jsp翻译成java(Servlet文件),java编译成class文件;
第二次访问:直接访问class文件;(如果服务端代码修改了,将会在访问时重新翻译、编译)
jsp和servlet可以相互转换;
因为第一次请求服务端会有翻译和编译的过程,因此比较慢,后续访问可以直接访问class,因此比较快,但是如果服务端修改了代码,则再次访问时会重新的翻译和编译;
7.在Eclipse中创建的Web项目:
浏览器可以直接访问WebContent中的文件,但是WEB-INF中的文件,无法通过客户端(浏览器)直接访问,只能通过请求转发来访问;
注意:并不是任何的内部跳转都能访问WEB-INF;原因是跳转有2种方式:请求转发、重定向;
部署tomcat,在server是面板新建一个tomcat实例,再在该实例中部署项目(右键-add)
注意:一般建议将eclipse中的tomcat与本地的配置信息保持一致:将eclipse中的tomcat设置为托管模式:【第一次】创建tomcat实例之后,双击该实例,选择Server Location的第二项;
8.统一字符集编码
a.编码分类:
设置jsp文件的编码(jsp文件中的怕个Encoding属性):jsp->java;
设置浏览器读取jsp文件的编码(jsp文件中content属性);
一般需要将上述设置成一致的编码,推荐使用UTF-8;
文本编码:
将整个eclipse文件中的文件统一设置;(推荐)
设置某一个项目
设置单独文件
9.JSP的页面元素:
脚本Scriptlet
<%
局部变量、java语句(需要分号)
%>
<%!
全局变量、定义方法
%>
<%=
输出表达式(无需分号)
%>
一般而言,修改web.xml、配置文件、java需要重新启动tomcat服务,但是如果修改了Jsp/html/css/js,不需要重启;
注意:out.println()不能回车;要想回车:“<b/>”(相当于方法的输出结果在HTML文件中,HTML文件中有回车,但是在网页中并不会回车)
10.JSP的页面指令:
page指令
<%@ page...%>
page指令的属性:
language:jsp页面使用的脚本语言(java代码);import:导入类;pageEncoding:jsp文件自身编码;contentType:浏览器解析jsp的编码;
11.jsp页面元素注释:
html注释:<!-- -->(在页面通过浏览器查看源码可以观察到)
java注释:// /*... */
jsp注释:<%-- --%>
12.JSP九大内置对象(自带的,不需要new也能使用的对象)
out:输出对象,向客户端输出内容;
request:请求对象;存储“客户端向服务端发送的请求信息”;
request对象常见方法:
String getParameter(String name):根据请求的字段名key(input标签的name属性),返回字段值value(input标签的value属性值);
String[] getParameterValues(String name):根据请求的字段值key,返回多个字段值value(常见的checkbox:多选按钮);
setCharacterEnoding(“编码格式utf-8”):设置post方式的请求编码;(默认编码:tomcat7及以前默认iso-8859-1,tomcat8以后改为了utf-8)
getRequestDispatcher().forward(request,response):请求转发的方式跳转页面;
ServerContext getServerContext():获取项目的ServletContext对象;
示例:注册
register.jsp(注册页),show.jsp(展示页)
http://localhost:8888/MyJspProject/show.jsp?uname=zs&upwd=123&uage=23&uhobbies=%E8%B6%B3%E7%90%83&uhobbies=%E7%AF%AE%E7%90%83&uhobbies=%E4%B9%92%E4%B9%93%E7%90%83
连接/文件?参数名1=参数值1 & 参数名2=参数值2 & 参数名3=参数值3;
get提交方式:method="get" 和 地址栏 、超链接(<a href=“xx”>) 请求方式 都默认属于get提交方式
get与post请求方式的区别:
a. get方式 在地址栏显示 请求信息(但是地址栏能够容纳的 信息有限,4-5KB;如果请求数据存在大文件,图片等 会出现地址栏无法容纳全部的数据而出错);post不会显示;
b. 文件上传操作,必须是post;
推荐使用post;
统一请求的编码 request
get方式请求 如果出现罗马,解决:
a.统一每一个变量的 编码 (不推荐)
new String(旧编码,新编码);
b.修改server.xml,一次性的 更改tomcat默认get提交方式的编码(utf-8)
建议 使用tomcat, 首先在server.xml中 统一get方式的编码.. URIEnocding="UTF-8"
response:响应对象
提供的方法:
void addCookie(Cookie cookie);服务端向客户端增加cookie对象
void sendRedirect(String location) throws IOException;页面跳转的一种方式(重定向)
void setContentType(String type);设置服务端相应的编码(设置服务端的contentType类型)
示例:登录
login.jsp->check.jsp ->success.jsp
请求转发 重定向
地址栏是否改变 不变(check.jsp) 改变(success.jsp)
是否保留第一次请求时的数据 保留 不保留
请求的次数 1 2
跳转发生的位置 服务端 客户端发出的第二次跳转
session:会话(服务端)session存储在服务端、session是在同一个用户(客户)请求时共享;
a.浏览网站:开始-关闭
b.购物:浏览、付款、退出
c.电子邮件:浏览、写邮件、退出
session机制:
客户端第一次请求服务端时,服务端会产生一个session对象(用于保存该客户的信息)并复制;并且每个session对象 都会有一个唯一的sessionId(用于区分其他session);服务端又会 产生一个cookie,并且 该cookie的name=JSESSIONID,value=服务端sessionId的值;然后 服务端会在 响应客户端的同时 将该cookie发送给客户端,至此 客户端就有 一个cookie(JSESSIONID);因此 客户端的cookie就可以和服务端的session一一对应(JSESSION-sessionID)
客户端第二次/n次请求服务端时:服务端会先用客户端cookie中的JSESSIONID 去服务端的session中匹配sessionId,如果匹配成功(cookie JSESSIONID和session sessionId),说明此用户 不是第一次访问,无需登录;
例子:
客户端: -顾客 (客户端)
服务端:存包处 -商场(服务端)
顾客第一次存包:商场 判断此人是否 之前已经存过包(通过你手里是否有钥匙);如果是新顾客(没钥匙),分配一个钥匙 给该客户;钥匙 会和 柜子 一一对应;
第二次/n次 存包:商场 判断此人是 之前已经存过包(通过你手里是否有钥匙);如果是老顾客(有钥匙),则不需要分配;该顾客手里的钥匙 会和 柜子 自动一一对应;
session方法:
String getId():获取sessionId;
boolean isNew():判断是否 新用户(第一次访问)
void invalidate():使session失效(退出登录、注销)
void setAttribute()
Object getAttribute()
void setMaxInacttiveInterval(秒):设置最大有效 非活动时间
int getMaxInactiveIinterval():获取最大有效 非活动时间
cookie和session的区别:
session cookie
保存位置 服务端 客户端
安全性 较安全 较不安全
保存的内容 Object String
Cookie(客户端,不是内置对象):Cookie是由 服务端生成的,在发送给客户端保存;相当于 本地缓存的作用:客户端(hello.mp4,zs/abc)->服务端(hello.mp4,zs/abc);作用提高访问服务端的效率,但是安全性较差;
客户端在第一次请求服务端时,如果服务端发现 此请求没有JSESSIONID,则会创建一个 name=JSESSIONID的cookie;
cookie:
a.不是内置对象,要使用必须new
b.但是,服务端会 自动生成一个(服务端自动new一个cookie) name=JSESSIONID的cookie 并返回给客户端;
Cookie:name=value;
javax.servlet.http.Cookie
public Cookie(String name,String value):产生Cookie
String getName():获取name
String getValue():获取value
void setMaxAge(int expiry):最大有效期(秒)
服务端准备Cookie:
response.addCookie(Cookie cookie)
页面跳转(转发,重定向)
客户端获取Cookie:request.getCookies();
a.服务端增加cookie:response对象;客户端获取cookie:request对象;
b.不能直接获取某一个单独对象,只能一次性将 全部的cookie拿到;
通过F12可以发现 除了自己设置的Cookie对象外,还有一个name为JSESSIONID的cookie
建议cookie只保存 英文数字,否则需要进行编码、解码
使用Cookie实现 记住用户名 功能
application:全局对象 获取路径
String getContextPath();虚拟路径
String getRealPath(“虚拟路径”);绝对路径;
pageContext:JSP页面容器
config:配置对象(服务器配置信息)
page:当前JSP页面对象(相当于java中的this)
exception:异常对象
out:输出对象
四种范围对象(小->大)
pageContext:JSP页面容器(page对象);当前页面有效(页面跳转后无效);
request:请求对象;同一次请求有效(请求转发后有效;重定向后无效);
session:会话对象;同一次会话有效(无论怎么跳转,都有效;关闭/切换浏览器后无效;从 登录->退出 之间 全部有效);
appliation:全局对象;全局有效(整个项目运行期间都有效;切换浏览器仍有效);关闭服务、其他项目 无效;如果想多个项目共享、重启后仍然有效:可通过JNDI技术;
1.以上4个范围对象,通过setAttribute()赋值,通过setAttribute()取值;
2.以上范围对象,尽量使用最小的范围;因为 对象的范围越大,造成的性能损耗越大;
以上4个对象共有的方法:
Object getAttribute(String name):根据属性名,获取属性值
void setAttribute(String name,Object obj):设置属性值(新增,修改),如果不存在则创建,如果存在则修改;
void removeAttribute(String name):根据属性名,删除对象
13.JDBC:
Java DataBase Connectivity 可以为多种关系型数据库DBMS 提供统一的访问
JDBC API 主要功能:
三件事,具体是通过以下类/接口实现:
DriverManager:管理JDBC驱动
Connection:连接(通过DriverManager产生)
Connection产生操作数据库的对象:Statement对象:createStatement();PreparedStatement对象:prepareStatement(sql);CallableStatement对象:prepareCall();
Statement(PreparedStatement):增删改查(通过Connection产生)
Statement操作数据库:增删改:executeUpdate();查询:executeQuery();
PreparedStatement操作数据库:增删改:executeUpdate();查询:executeQuery();赋值操作:setXxx();
PrepareStatement(继承自Statement)与Statement在使用时的区别:
1.Statement:sql;executeUpdate(sql);
2.PreparedStatement:sql(可能存在占位符:?);在创建PrepareStatement对象时,将sql预编译prepareStatement(sql);executeUpdate();setXxx()替换占位符?;
推荐使用PreparedStatement:原因如下:
1.编码更加简便(避免了字符串的拼接)
String name=“zs”;int age=23;
stmt:
String sql=“insert into student(stuno,stuname) values(‘“+name+”’,“+age+”)”;
stmt.executeUpdate(sql);
pstmt:
String sql=“insert into student(stuno,stuname) values(?,?)”;
pstmt=connection.prepareStatement(sql);//预编译SQL
pstmt.setString(1,name);
pstmt.setInt(2,age);
2.提高性能(因为 有预编译操作,预编译只需要执行一次)
需要重复增加100条(批量处理)
String name=“zs”;int age=23;
stmt:
String sql=“insert into student(stuno,stuname) values(‘“+name+”’,“+age+”)”;
stmt.executeUpdate(sql);
pstmt:()
String sql=“insert into student(stuno,stuname) values(?,?)”;
pstmt=connection.prepareStatement(sql);//预编译SQL
pstmt.setString(1,name);
pstmt.setInt(2,age);
3.安全(可以有效防止sql注入)(sql注入:将客户输入的内容 和 开发人员的SQL语句 混为一体)
stmt:存在被sql注入的风险(例如输入 :用户名:任意值 ‘ or 1=1 --; 密码:任意值;)
CallableStatement:调用数据库中的 存储过程/存储函数(通过Connection产生)(connection.prepareCall(参数:存储过程或存储函数名);参数格式:存储过程(无返回值return,用Out参数替代):{call 存储过程名(参数列表)};存储函数(有返回值return):{?=call 存储函数名(参数列表)})
JDBC调用存储过程的步骤:
a.产生 调用存储过程的对象(CallableStatement) cstmt=connection.prepareCall(“...”);
b.通过setXxx()处理 输出参数值 cstmt.setInt(1,30);
c.通过registerOutParameter(...)处理输出参数类型
d.cstmt.execute()执行
e.接收 输出值(返回值)getXxx()
JDBC调用存储函数:与调存储过程的区别:
在调用时,注意参数:“{?=call addTwoNumfunction (?,?)}”
ResultSet:返回的结果集(next():1.下移;2.判断下移之后的元素是否有数据,如果有数据:true,如果无数据:false)(previous():向上,同next();getXxx(字段名/位置):获取具体的字段值)(上面的Statement等产生)
JDBC访问数据库的具体步骤:
a.导入驱动(导入jar包),加载具体的驱动类(Class.forName(“oracle.jdbc.OracleDriver”);)
b.与数据库建立连接(Connection connection=DriverManager.getConnection(URL,UNAME,UPWD);)
c.发送SQL,执行(增删改、查)(增删改:Statement stmt=connection.createStatement();int cout=stmt.executeUpdate(sql);)(查:Statement stmt=connection.createStatement();)
d.处理结果集(查询)(ResultSet rs=stmt.executeQuery(sql);while(rs.next()){rs.getInt(“字段名1”);rs.getString(“字段名2”);})
JDBC中,除了Class.forName() 抛出ClassNotFoundException,其余方法全部抛SQLException;
数据库驱动
驱动jar 具体驱动类 连接字符串(数据库名、ip地址、端口号、名字)
Oracle ojdbc-x.jar oracle.jdbc.OracleDriver jdbc:oracle:thin:@localhost:1521:ORCL
MySQL mysql-connector-java-x.jar com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/数据库实例名
SqlServer sqljdbc-x.jar com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:microsoft:sqlserver:localhost:1433;databasename=数据库实例名
使用jdbc操作数据库时,如果对数据库进行了更换,只需要替换:驱动、具体驱动类、连接字符串、用户名、密码;
处理CLOB/BLOB类型
处理稍大型数据:
a.存储路径(通过JDBC存储文件路径,然后 根据IO操作处理);
b.
CLOB:大文本数据(小说->数据)
存:先通过pstmt 的? 代替小说内容(占位符),再通过pstmt.setCharacterStream(2,reader,(int)file.length()); 将上一步的? 替换为 小说流,注意第三个参数需要时Int类型;
取:通过Reader reader=rs.getCharacterStream(“NOVEL”);将clob类型的数据 保存到Reader对象中,将Reader通过Writer输出即可;
BLOB:二进制
与CLOB步骤基本一致,区别:getBinaryStream(...)getBinaryStream(...)
14.JSP访问数据
JSP就是在html中嵌套的java代码,因此java代码可以写在jsp中(<%...%>)
导包操作:java项目:1.jar复制到工程中;2.右键该jar:build path ->add to build path
web项目:jar复制到WEB-INF/lib
15.JavaBean(简化代码、提高代码复用)
刚才我们将 jsp中 登录操作的代码 转移到了LoginDao.java; 其中LoginDao类 就称之为JavaBean。
JavaBean的作用:
a.减轻jsp复杂度
b.提高代码复用(以后任何地方的 登录操作,都可以通过调用LoginDao实现)
JavaBean(就是一个java类)的定义:满足以下2点,就可以称之为JavaBean
a.public 修饰的类,public 无参构造
b.所有属性(如果有) 都是private,并且提供set/get(如果boolean 则get 可以替换成is)
使用层面,Java分为2大类:
a.封装业务逻辑的JavaBean(LoginDao.java封装了登录逻辑) 用于操作封装数据的JavaBean;
b.封装数据的JavaBean(实体类,Student.java Person.java)对应于数据库中的一张表;
16.MVC设计模式:
M:Model,模型:一个功能。(用JavaBean实现)
V:View,视图:用于展示、以及与用户交互。(使用html、js、css、jsp、jquery等前端技术实现)
C:Controller,控制器:接收请求,将请求跳转到模型进行处理;模型处理完毕后,再将处理的结果返回给 请求处。(可以用jsp实现,但是一般建议使用Servlet实现控制器)
17.Servlet:
Java类必须符合一定的 规范:
a.必须继承 javax.servlet.http.HttpServlet
b.重写其中的doGet()或doPost()方法
doGet():接收 并处理 所有get提交方式的请求
doPost():接收 并处理 所有post提交方式的请求
c.编写web.xml中的servlet映射关系(纯手工方式)
Servlet要想使用,必须配置
Servlet2.5:web.xml(纯手工方式)
Servlet3.0:@WebServlet(不需要再web.xml中配置,但 需要在Servlet类的定义处之上编写 注解@WebServlet(“url-pattern的值”))
匹配流程:请求地址 与@WebServlet中的值 进行匹配,如果匹配成功,则说明 请求的就是该注解所对应的的类;
Web.xml:“/”代表项目根路径
Jsp中的:“/”代表服务器根路径
Servlet流程:
请求-><url-pattern>->根据<servlet-mapping>中的<servlet-name>去匹配 <servlet>中的<servlet-name>,然后寻找到<servlet-class>,最终将请求交由<servlet-class>执行。
Servlet生命周期(5个阶段):加载、初始化:init(),该方法会在Servlet被加载并实例化的以后执行,第一次访问servlet时会被执行(只执行这一次;可以修改为tomcat启动时自动执行);服务:service()->doGet()和doPost();销毁:destroy(),被系统回收时执行,关闭tomcat服务时,执行一次;卸载;
eclipse中在src创建一个servlet,然后重写的doGet()、doPost()就可以。 (doGet()、doPost()只需要编写一个)
18.三层架构
与MVC设计模式的目标一致:都是为了 解耦合、提高代码复用;
区别,二者对醒目理解的角度不同。
三层组成:
表示层(URL,User Show Layer;视图层)
前台:对应于MVC中的View:用于和用户交互、界面的显示(jsp、 js、 html 、css、 jQuery等web前端技术)
代码位置:WebContent
后台:对应于MVC中的Controller,用于 控制跳转、调用业务逻辑层(servlet(springMVC 、Structs2))
位于xxx.servlet包中
Servlet:一个Servlet对应于一个功能,因此 如果有增删改查(查询单个、查询全部)5个功能,则需要创建5个Servlet;
业务逻辑层(BLL,Business Logic Layer;service层)
接收表示层的请求 调用
组装数据访问层,逻辑性的操作(增删改查,删:查+删)
一般位于:xxx.service包(也可以称为:xxx.manager,xx.bll)
数据访问层(DAL,Data Access Layer;Dao层)
直接访问数据库的操作,原子性的操作(增删改查)
一般位于xxx.dao包
三层间的关系:
上层 将请求传递给下层,下层处理后 返回给上层
上层依赖于下层,依赖:代码的理解,就是持有成员变量 或者理解为: 有A的前提 是必须先有B(必须现有了数据库,才可能会存在DAO层,DAO依赖于数据库)
三层优化
加入接口
建议面向接口开发:先接口->再实现类
service、dao加入接口
接口与实现类的命名规范
接口:interface, 起名 I实体类Service
I实体类Dao
实现类:implements, 起名 实体类ServiceImpl
实体类DaoImpl
以后使用接口/实现类时,推荐写法:
接口 x=new 实现类();
DBUtil 通用的数据库帮助类,可以简化Dao层的代码量
帮助类 一般建议写在 xxx.util包
方法重构:将多个方法 的共同代码 提炼出来,单独写在一个方法中,然后引入该方法即可;
19.分页
要实现分页,必须知道 某一页的 数据 从哪里开始 到哪里结束
分页实现:(5个变量(属性))
1.数据总数 (查数据库,select count(1)...)
2.页面大小(每页显示的数据条数) (用户自定义)
3.总页数 (程序自动计算)
4.当前页(页码) (用户自定义)
5.当前页的对象集合(实体类集合) (查数据库,分页SQL)
oracle的分页查询语句:
select * from(select rownum r,t.* from(select s.* from student s order by sno asc) t ) where r>=(n-1)*10+1 and r <=n*10;
20.文件上传:
a.在Apache下载Commons fileupload.jar包和Commons io.jar包,然后引入jar包;
b.代码
前台jsp:
<input type="file" name="name"/>
表单提交方式必须为post
在表单中必须增加一个属性entype=“multipart/form-data”
后台servlet:
request.setCharacterEncoding(“utf-8”);
response.setCharacterEncoding(“utf-8”);
response.setContentType(“text/html;charset=utf-8”);
注意的问题:上传的目录 有时会被删除;
1.如果修改代码,则在tomcat重新启动时,会被删除
原因是:当修改代码的时候,tomcat会重新编译一份class并且重新部署(重新创建各种目录)
2.如果不修改代码,则不会被删除
原因是:没有修改代码,class仍然是之前的class
因此,为了防止 上传目录丢失:a.虚拟路径 b.直接更换上传目录 到非tomcat目录;
限制上传:
类型、大小;注意对文件的限制条件 写在parseRequest之前;
21.文件下载:不需要任何依赖jar
a.请求(地址a 表单from),请求servlet;
b.servlet通过文件的地址 将文件转为输入流 读到servlet中;
c.通过输出流 将 刚才已经转为输入流的文件 输出给用户;
注意:下载文件 需要设置2个 响应头;
解决下载文件名中文乱码问题:
edge:URLEcoder.encode(fileName,“UTF-8”)
Firefox:给文件名 加:前缀(=?UTF-8?B)、String构造方法、Base64.encodebase64、后缀(?=);
22.EL:Expression Language,可以替代JSP页面中的java代码;
传统的 在JSP中用java代码显示数据的弊端: 类型转换、需要处理null、代码掺杂 ->EL
EL示例:${requestScope.student.address.schoolAddress};${域对象.域对象中的属性.属性.属性.级联属性}
EL操作符:
点操作符: --使用方便
中括号操作符[“”/‘’/ ]: --功能强大:可以包含特殊字符(. 、 -),获取map属性,获取数组元素,获取变量值;
EL表达式的隐式对象(不需要new 就能使用的对象, 自带的对象)
a.作用域访问对象(EL域对象):pageScope < requestScope < sessionScope < applicationScope
如果不指定域对象,则默认会根据 从小到大的顺序 依次取值;
b.参数访问对象:获取表单数据(超链接中传的值: a.jsp?a=b&c=d,地址栏中的值:a.jsp?a=b&c=d)(${param}相当于request.getParameter()、${paramValues}相当于request.getParameterValues())
c.JSP隐式对象:pageContext
在jsp中可以通过pageContext 获取其他的jsp隐式对象;因此 如果要在EL中使用JSP隐式对象,就可以通过pageContext间接获取,例如${pageContext.request}相当于通过get
Request()方法获取request对象;可是使用此方法,级联获取方法(同样方法获取其余对象及属性);即${pageContext.方法名去掉get和()并且将首字母小写}
23.JSTL:比EL更强大
需要引入2个jar包:jstl.jar standard.jar
引入tablib:<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix="c"%> 其中prefix=“c”:前缀
核心标签库:通用标签库、条件标签库、迭代标签库
a.通用标签库
<c:set>赋值
i:在某个作用域之中(4个范围对象),给某个变量赋值;<c:set var=“变量名” value=“变量值” scope=“4个范围的作用域”/>相当于<%request.setAttribute(“name”,“zhangsan”);%>
ii:在某个作用域之中(4个范围对象):
给某个对象的属性赋值;<c:set target=“${requestScope.student}” property=“sname” value=“zxs”/>(此种写法,不能指定scope属性)
给map对象赋值;<c:set target=“${requestScope.countries}”(对象) property=“cn”(对象的属性) value=“中国”(赋值)/>
注意:<c:set/>可以给不存在的变量赋值;(但是不能给不存在的对象赋值)
<c:out>方式:<c:out value="${requestScope.countries}">显示
<c:remove>方式:<c:remove var=“a” scope=“request”>删除属性
选择:
if(boolean)单重选择
<c:if test=“${10>2}” var=“result” scope=“request”>
真
${requestScope.result}
</c:if>
if...else if... 多重选择
<c:choose>
<c:when test=“${requestScop.role=='老师'}”>老师代码...</c:when>
<c:when test=“${requestScop.role=='学生'}”>学生代码...</c:when>
<c:when test=“${requestScop.role=='...'}”>...代码...</c:when>
<c:otherwise>其他代码...</c:when>
</c:choose>
注意:在使用test=“” 一定要注意后面是否有空格;
例如: test="${10>2}" true
test="${10>2} " 非true(false)
循环:循环(迭代标签库)
for(int i=0;i<5;i++)
<c:forEach begin="0" end="5" step="1" varStatus=“status”>${status.index} 内容...</c:forEach>
for(String str:names)
<c:forEach var=“str” items=“${requestScope.names}”>${str}</c:forEach>
23.过滤器:
通配符
dispatcher请求方式:
REQUEST(常用):拦截HTTP请求get post
FORWARD(常用):之拦截 通过 请求转发方式的请求
INCLUDE:只拦截通过request.getRequestDispatcher(“”).include()、通过<jsp:include page="..."/>此种方式发出的请求
ERROR:只拦截<error-page>发出的请求
过滤器中deFileter方法参数:ServletRequest
在servlet中的方法参数:HttpServletRequest
过滤器链
可以配置多个过滤器,过滤器的先后顺序 是由<filter-mapping>的位置决定
24.监听器
开发步骤:
a编写监听器,实现接口
b配置web.xml(个别不需要配置,例如:HttpSessionBindingListener、HttpSessionActivationListener)
监听对象(主要三个对象):request、session、application
a.监听对象的创建和销毁:
request:ServletRequestListener
session:HttpSessionListener
application:ServletContextListener
每个监听器 各自提供了2个方法:监听开始、监听结束的方法
servletContext在servlet容器启动时 自动创建;
b.监听对象中属性的变更
request:ServletRequestAttributeListener
session:HttpSessionAttributeListener
application:ServletContextAttributeListener
25.session的钝化和活化:
钝化:内存->硬盘
活化:硬盘->内存
session对象的四种状态:
监听绑定和解绑:HttpSessionBindingListener 不需要配置web.xml
a.session.setAttribute(“a”,xxx) 对象a【绑定】到session中
b.session.removeAttribute(“a”) 对象a从session中【解绑】
监听session对象的钝化、活化:HttpSessionActivationListener 不需要配置web.xml
c.钝化
d.活化
如何钝化、活化:配置tomcat安装目录/conf/context.xml
钝化、活化本质 就是序列化、反序列化:序列化、反序列化需要实现Serializable接口
总结:钝化、活化 实际执行 是通过context.xml中进行配置 而进行。HttpSessionActivationListener只是负责 在session钝化 和 活化时 予以监听。
26.Ajax:异步js 和xml
异步刷新:如果网页中某一个地方需要修改,异步刷新可以使:只刷新该需要修改的地方,而页面中其他地方 保持不变。例如:百度搜索框、视频点赞;
实现:
js:XMLHttpRequest对象
XMLHttpRequest对象的方法:
open(方法名(提交方式get/post),服务器地址,true):与服务器建立连接
send():
get:send(null)
post:send(参数值)
setRequestHeader(header,value):
get:不需要设置此方法
post需要设置:
a.如果请求元素中包含了 文件上传 setRequestHeader(“Content-Type”,“multiparty/form-data”)
b.如果不包含 文件上传 setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”)
XMLHttpRequest对象的属性:
readyState:请求状态 只有状态为4 代表请求完毕
status:响应状态 只有200 代表响应正常
onreadystatechange:回调函数
responseText:响应格式为String
responseXML:响应格式为XML
jQuery:推荐方式
$.ajax({
url:服务器地址,
请求方式:get/post,
data:请求数据,
success:function(result,testStatus){
},
error:function(xhr,errorMessage,e){
}});
$.get(
服务器地址,请求数据,function(result){
},
预期返回值类型(string/xml)
);
$.post(
服务器地址,请求数据,function(result){
},
预期返回值类型(string/xml/json)
);
$(xxx).load(
服务器地址,请求数据,function(result){
},
预期返回值类型(string/xml/json)
);
load:将服务端的返回值 直接加载到$(xxx)所选择的元素中;
$.getJSON(
服务器地址,JSON格式的请求数据{“mobile”,$mobile},function(result){
}
)