08Servlet
来源:互联网 发布:师洋淘宝店截图 编辑:程序博客网 时间:2024/05/16 01:34
Servelet
单机程序
网络程序-主机终端
网络程序-两层CS架构: 客户端+DB
网络程序-三层CS架构:客户端+应用服务器+db
网络程序-BS架构:B/S:Browser+Web Server + db
sun指定的一种用来扩展web服务器功能的组件规范
在servelet之前可以使用CGI(common gateway interface)程序扩展web服务
终端:chmod +x *sh 获取权限
开启:./startup.sh 不行试试sh startup.sh
关闭: ./shutdown.sh sh shutdown.sh
1.新项目,maven项目,war包
2.deployment...
3.导包:项目属性-》targeted runtimes-》勾选apache..
4.java文件放在java Resource,网页文件如注册页面reg.html,不需要重新配置web.xml的,
那么reg.html放在src的webapp下,
注意
注意
注意
不是在WEB-INF下,而是webapp下。webapp也就是项目根目录
5.add服务器到tomcat
maven中下一个包,其相关的包都会下载下来,而不需要自己一个一个下载
比如:hevean有几十个包
导入servlet包2种方法:
1)maven的pom搜javaee,选javaee javaee-api
或者:
2)
tomcat目录下的lib:servlet
eclipse内右侧servlet右键,属性,Targeted runtimes
右侧勾选Apache Tomcat,ok
src/main/resources内放自己写的配置文件
在java Resources的src/main/java建包
新建包,同时需要选择父类,选择HttpServlet-javax.servlet.http
新建TimeServlet.java后需要重写父类方法。右键,source-》Override..
选择:
service(HttpServletRequest,HttpServletResponse)
servlet:server let 服务的小片段
// TODO Auto-generated method stub 待完成
类名:一个对象,正名
别名是为了引用方便
<!-- 1.配置Servlet类,给它取一个别名。 -->
<servlet>
<servlet-name>time</servlet-name>
<servlet-class>web.TimeServlet</servlet-class>
</servlet>
<!-- 2.通过别名引用一个类,给它设置一个网络访问路径(网名),它必须以/开头。 -->
<servlet-mapping>
<servlet-name>time</servlet-name>
<url-pattern>/ts</url-pattern>
</servlet-mapping>
上面web.xml写完后,tomcat右键add_remove.左侧服务器add到右侧
这时servlet1将会被拷贝到之前在tomcat上双击配置的第二个的设置
也就是tomcat的安装目录
500:拼写错误,类名写错
405:方法声明有误
404:找不到资源
该了代码需要:tomcat右键publish
java能不能做网页:就是用servlet
php/python/java都是服务端程序
静态是网页是HTML,动态网页也是HTML,但是动态是用java拼的
回顾:JDBC/SQL的事务的4个协议:???????????????????/
————————————————————————————————————————————————————
## 4.对开发者的要求
#### 4.1 不需要我们做的事情
-浏览器和服务器通信的过程已经由他们实现了
-请求数据的打包(3部分)由浏览器实现了
-响应数据的打包(3部分)由浏览器实现了
### 4.2需要我们做的事情
-请求及响应的业务数据由开发者提供
-使用request处理请求数据,使用response处理响应数据
》》》学会使用request和response
迭代器是23中设计模式之一。
设计模式:
哪里用到了迭代器模式:JDBC的ResultSet,Iterator,Enumeration
迭代器基本都是while
响应数据包组成:
状态行:HTTP/1.1 200 OK 中的数字200表示成功,否则是404或者500等
reg.html不需要在web.xml配置
req.getParameter("") 取单个
如:
String user = req.getParameter("username");
req.getParameterValues("");
如:
String[] interests = req.getParameterValues("interest");
————————————————————————————————————————
<body>
<!-- action中路径的声明方式:
1.完整路径
http://localhost:8080/servlet2/reg
2.绝对路径
规则:/项目名/访问路径
举例:/servlet2/reg
3.相对路径
当前网页和目标网页的相对关系
当前:/servlet2/reg.html
目标:/servlet2/reg
相对路径是reg
上级写../
注意:绝对路径以/开头,相对路径不以/开头
-->
<form action = "reg" >
<p>账号:
。。。。。。。。。
。。。。。。。。。
request/response本次请求结束就会被销毁
//1.1--请求行request line
req.getMethod();
req.getServletPath();
req.getProtocol();
get和post请求的区别:
GET:通过路径发送数据,通过路径传参
缺点:参数传递过程中能够被看到,隐私性差
可以传少量数据
》》所有的请求默认都是get请求
POST:不是通过路径(请求行)传参,而是用实体内容(实体内容:具体的业务)传参
参数在传递过程中不可见,隐私性好
传递的数据大小不受限制
》》当form上增加了mothod="post"
## 4.如何选择?
查询时用get,一般查询条件较少
保存/提交时用post,此时数据较多
## 5.可以通过浏览器观察请求方式
-f12
-打开network
!!!!!!!!!
网上传输只能用byte不能用字符串,字节可以不需要指定编码,字符串需要指定字符集编码
_______________________________________________
mysql:show variables like "$char"
_______________________________________________
原来:
1 html页面表单form的action提交的对象就是web.xml的url-pattern
两者如果不一致就报404错。次分析在课件day01.html
2 注意缓存的问题,更改后使用HTML应该多次刷新后再试。如果路径名的后面还是之前的当然还是会
报错的。比如之前的action="aaa",改了之后而且web.xml也对应改了之后要注意看浏览器路径名是否
还是之前的 localhost:8080/项目名/aaa/
3 重启tomcat
访问静态网页路径:项目名/静态网页名.html ,如http://localhost:8080/svt/zhuce.html
访问动态的:项目名/url-pattern名 如:http://localhost:8080/svt/reg
————————————————————————————————————————————
day01
序列化:如果需要把数据存到硬盘或者网络传输都需要序列化
补充内容:
JavaBean:满足如下规范的类就叫bean
--必须要有包pacakage
--必须要有默认构造器
--必须要实现序列化接口
--通常有get/set方法
》》建议初学者将所有的类都满足规范
真正应用中dao需要实现一个接口
实现类写法:EmpDaoImpl
面试常用:preparedStatement和statement的区别
DBUtil如何分页:
不能返回结果集。因为DBUtil,管理连接,连接后才进行操作,获取结果集等等。之后就关闭
连接。刚给出结果集就关闭连接,则获取到的结果集什么都没有
因此,需要放到集合再关闭连接关闭回收资源如结果集
//1. 接收浏览器传过来的数据
//2. 查询数据库,增删改
//3. 返回响应信息
浏览器一旦提示保存,说明是格式错了,浏览器无法解析:如下text写成test
res.setContentType("test/html ; charset=utf-8");
tomcat下的部署的代码,也就是运行时的代码
workspace的是源代码
两者的结构不一样
开发还是在包模式下开发,也就是src/main/java
看则可以在src下看,因为src下也有
五。servlet访问路径的配置方式
## 1.精确匹配(/hi)
- 只有/hi这个名字可以访问此Servlet
- 此Servlet只能处理一个请求
## 2.通配符(/*)
- 所有的名字都可以访问此Servlet
- 此Servlet能处理一切请求
——如:<url-pattern>/*</url-pattern>
## 3.后缀(*.hi)
- 所有以hi为后缀的名字都可以访问此Servlet
- 此Servlet能处理多个请求
——如:<url-pattern>*.duang</url-pattern>
实际工作中第3中更灵活:如下:
do.hi
dept.hi
emp.hi
异常抛给服务器,而不是浏览器。浏览器只是请求
六:使用一个Servlet处理多个请求
Servlet的生命周期:
new:从无到有
init():已有,初始化
1.tomcat一已启动就实例化对象
2.然后调用无参的默认构造器初始化
3.调用service()
tomcat要求要有默认构造器,必须是无参的
如果要传参,就只能init()
几时销毁?
————————————————————————————————————
1.默认情况下,第一次访问servlet时tomcat会创建它
2.可以修改为,启动tomcat时,tomcat就创建servlet
3.第1(new)/2(init())/4 destroy()执行一次,第3步(service())执行多次
4.每个类型的servlet都只有单(个实)例
maven的包拷贝到tomcat的该项目的lib目录下
注意:手动部署导包的话,包不会自动导到tomcat的lib目录下
DBUtil就满足两种模式:
多例的生产模式:不断创建连接
单列模式:??????????????
———————————————————————————————————————————————
day03:
ServeltContext
分页:
怎么调用*.properties:--->properties
访问xml用什么技术:--->dom4j
处理动态网页用什么技术:--->j2ee的servlet
连接数据库用什么技术:--->JDBC
ServletConfig和ServletContext对web.xml的作用相当于dom4j
一个SCT对应多个Servlet
一个SCF对应一个Servlet
很多都要用参数就用SCT
SCT/SCF的底层就是dom4j,非必要使用的,可以 不用,但是使用了更方便
一。config和context---------------->>>>>>>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
## 1.对比
共同点:都能读取web.xml中的参数
- config和Servlet是1对1的关系
- context和Servlet是1对多的关系
》都是为Servlet服务的
## 2.config
- 假设开发一个网页游戏,当在线人数超出限制时要排队
- 最大在线人数MaxOnline可配置
- 只在登录(LoginServlet)时验证是否超出限制
》想要给某一个Servlet预置参数用config
## 3.context
- 软件都有各种查询功能,一般都支持分页
- 分页需要已知:当前页,每页显示多少条size
- 其中size一般可配置
- 多个查询功能都要使用size,使用context预置比较合理
》想要给多个Servlet预置参数用context
换一个servlet就换一个config
tomcat启动时启动n个Servlet,共用context
## 4.context特殊的用途
- 提示:之前使用config和context读取的都是常量
- context还可以读写变量。而config只能读取常量
专门建一个类用来做初始化
context在所有的servlet之前就已经创建
<load-on-startup>1</load-on-startup>可以先初始化后创建。数字1为最高优先级
InitServlet.init() 该类不需要重写service方法,不处理业务,只是初始化
————————————————————————————————————————————
Servlet上下文:理解为Servlet环境/
特点:
- 惟一性(一个Web应用对应一个servlet)
- 一直存在(只要容器不关闭,应用没有被卸载删除,servlet上下文就一直存在
————————————————————————————————————————————
二。Servlet线程安全问题:
## 1.什么时候有线程安全问题
### 局部变量:
- 局部变量存储于栈内
- 每个线程都有自己的栈针
》同时修改局部变量没有问题
### 成员变量
- 成员变量存储在堆内
- 多个线程共享同一份成员变量
》同时,并发修改同一个成员变量有问题
## 2.如何解决:
——————————————————————————————————————————————————————
>>>>>>>>>>>>>>>>>>>JSP<<<<<<<<<<<<<<<<<<
Servlet拼网页很麻烦,参考FindEmpServlet.java
Servlet有什么用?
---->处理HTTP协议。动态拼接网页
JSP?----->作用同Servlet。
Servlet:创建类,类中写标签。
JSP:在标签内写java。如,复制美工的静态网页,再在里面写java
JSP注释:
<!-- --> 不忽略java
<%-- --%> 万能注释,忽略java
语法规则:
表达式:
<%= %>
小脚本:
<% %>
page指令:
<%@page contentType="image/gif" %>
作用相当于Servlet的response.setContentType("image/gif");
JSP默认是text,可以不写。但是用图片等的时候需要写
jsp运行原理:详情看课件图片
找到jsp后翻译成Servlet
pageEncoding在翻译的时候被调用用
jsp里面能直接使用array,date等。因为是内置对象,也就是隐含对象(*)
jsp生成的java文件中就是在jsp代码前先声明变量
面试题:
请列举9个JSP隐含对象以及类型:
tomcat每一个项目只有一个context
注意:
JSP的开头的import导包不能用分号;结尾!!!!!!!!!!!!!!!
——————————————————————————————————————————————
Day05
转发:
Spring和SpringMVC是包含关系
# 一。开发模式
##
Model1:java套标签,标签套java,耦合度高
使用一个组件(要么servlet要么JSP)处理请求,处理业务,显示数据
没有公司用Model1,过时的
## 2.Model 2(面试题,极为重要!!!!!!)
把之前的一个组件干的事变成两个组件干
>>>>>------MVC-----<<<<<
引入了MVC设计模式对代码解藕。80s就有了,java中只是sun引入而已。
MVC是经典的设计模式,是代码的分层思想。
M--Model,业务层,用来处理业务
V--View,视图层,用来显示数据
C--Controller,控制层,用来调度,是业务层和视图层的桥梁
该模式可以对代码解藕,便于团队开发以及维护
————————————————————————————————————
FindEmpServlet.service(req,res)
jsp生成的对象是只有的:EmpListServlet.service(req.res)
实际上就是把req和res参数传给jsp生成的类Servlet的service()
声明变量
write标签
保留脚本
print表达式
————————————————————————————————————
Servlet调用了jsp生成的那个类,然后把req和res传给它
jsp不会乱调用其他的类,只有调用9个隐式对象
以后不要直接访问jsp,而应该访问作为Controller的Servlet。
在项目jsp2的员工查询案例中,不能再像之前那么访问emp_list.jsp了,而跟之前的之前学servlet那样访问servlet
而且,回忆下,在web.xml不是已经做了配置了吗?在之前(day04)刚用jsp时都不需要配置web.xml的
之前的jsp中直接写java业务代码,数据不可控
Model2的MVC中,业务直接在java中写,jsp只将业务结果显示,如案例中的emp_list.jsp只把接收到的查询结果显示出来
————————————————————————————————————————————————————
//1.接收参数
//2.查询所有的员工
EmpDao dao = new EmpDaoImpl();
List<Emp> list = dao.findAll();
// /webapp/emp_list.jsp
//将请求转发给jsp,让它继续处理
//把数据存到request。转发时通过request给对方
req.setAttribute("emps",list); //为什么是用Attribute?是跟ServletContext一样意思?
//当前: /jsp2/findEmp
//目标路径: /jsp2/emp_list.jsp
req.getRequestDispatcher("emp_list.jsp").forward(req,res); //取到转发器。把req和res给jsp
Forward:通知服务器,让服务器去转发
request和response是一个对象,放在堆中。
FindEmpServlet调用request和response,然后把处理好的业务数据给回request和response,然后
通知服务器转发。服务器再根据目的地找emp_list.jsp,把jsp翻译成java,然后request和response开始转发给
jsp的java,最后输出
————————————————————————————————————————————————————
面试题:转发和重定向的区别:
相同点:都是解决web组件之间的跳转问题
web组件:Servlet或JSP
区别:
--两者相互依赖时用转发
转发的特点:
--1.一次请求。也就是只有一个request
--2.地址不变
--3.服务器的A和B共用一个request,它们可以通过request共享数据
--4.只能将请求转发给项目内部的组件
重定向:
--1.二次请求
--2.地址会改变
--3.服务端的A和B使用不同的request,不能通过request共享数据
--4.可以将请求重定向到项目外部的组件
何时用转发或重定向?
--查询时用转发
--增删改后重定向到查询
——————————————————————————————————————————————
day6 7 8 是补充。2天 day09半天
先讲day09,EL表达式/JSTL在实际中很常用。
明天和下周一做项目
然后讲day 6 7 8
req
EL底层用到了类反射机制,因此jsp中不再需要import了
EL的第一个作用:获取bean属性,也就是javabean属性。
什么是javabean:
补充内容:
JavaBean:满足如下规范的类就叫bean
--必须要有包pacakage
--必须要有默认构造器
--必须要实现序列化接口
--通常有get/set方法
案例如下
告知这个类的名字是什么,就能自己去找
如告知stu类,getName
<servlet>
<servlet-name>findStudent</servlet-name>
<servlet-class>web.FindStudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>findStudent</servlet-name> //这里如果上下不一致,tomcat的Server也会开不起来
<url-pattern>/findStudent</url-pattern>
</servlet-mapping>
————————————————————————————————————
<!-- request.getAttribute("stu").getName() --> request.getAttribute("stu")获取的是Object
需要强转
<p>姓名:${stu.name }</p>
<!-- request.getAttribute("stu").getAge() -->
<p>年龄:${stu["age"] }</p>
<!-- request.getAttribute("stu").getId() -->
<p>课程:${stu.course.id }</p>
这里的id相当于自动补充了前面的get,组成getId()方法,当然不是属性,因为属性是私有的,当然不能访问,如Course类如下:
---->>
//Bean的属性id
//1.透过get方法所看到的属性
//2.去掉get然后首字母小写所获得的词
public Integer getId() {
return courseId;
}
————————————————————————————————————————————————
<!--
EL默认从下面4个对象中依次取值,这些对象都是隐含对象(内置对象),它们是EL的取值范围:
按照顺序取值,如果下面4个中都没有,就返回null
page->request->session->application
也可以明确指定取值的范围:
sessionScope.stu.name
requestScope.stu.name
-->
EL表达式的+号只能求和,不能拼接字符串
——————————————————————————————————————————————
用JSTL需要导包。需要pom里面搜索:
JSTL,
jstl jstl 1.2 jar
包下的META-INF下的tld实际是xml的标签,c-..是核心的标签库
如果是maven导包的,会自动拷贝到tomcat目录的lib下
如果是自己网页下载的,需要手动拷贝到tomcat/wtpwebapps/项目/WEB-INF/lib下
<short-name>c</short-name> 用的时候就是用这个短名
<uri>http://java.sun.com/jsp/jstl/core</uri> 这不是网址,是名字
然后在自己的jsp页面开头就这样:
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!doctype html>
服务器只会调用无参的
PageContext是一个管理者,可以调用另外的8个内置对象
tld的1-6都可以照抄
<validator>验证可以不写
自定义的tld要放在webapp/WEB-INF目录下
——————————————————————————————————————————
netctoss资费计费系统项目:
新建maven项目,导包:
1.导包:jstl
选择:jstl 1.2
2.导包:ojdbc
选择:com.oracle ojdbc14
10.2.0.4.0jar
3.导包:commons-dbcp
选择:commons-dbcp commons-dbcp的
commons-dbcp:1.4
DBUtil的config_properties文件不能放在项目的根目录下,而是必须放到
resource,只有这里项目部署的时候在会编译到正确位置
为何用ThreadLocal:
多次访问数据库,在查询过程中需要遍历,同时又要增删改等等,
如转账,查,取,查...
costDao.find()
EmpDao.update()
两者共用一个连接,因此DBUtil连接数据库就用ThreadLocal
学习云笔记的时候能加深对ThreadLocal的理解
如一注册就送一个笔记本,就可以在笔记本上记录数据
一个事务一个连接
log4j:记日志
选中代码,然后alt+shift+m就能自动加入到新方法中
获取路径名的4种方法:
Servlet
???????
find.jsp为何放到WEB-INF目录下?
java项目中WEB-INF里面的项目会被保护,不能直接被访问
而PHP则需要程序员自己写方法保护
netctoss_v1
--images
--style
--WEB-INF
图片放到项目根目录下了,jsp里面引入图片为何不是../images/01.jpg而是变成同级目录的路径images/01.jpg
答:因为访问的是动态网页,浏览器不知道有jsp。
地址栏是这样访问的:http://localhost:8080/netctoss_v1/findCost.do
也就是说访问的是findCost.do,而findCost.do是在项目netctoss_v1目录下的,这时候还没jsp的事。详细可以
查看浏览器的请求,最先请求的是findCost.do
重定向的使用:在项目EmpManager
日期如何插入数据库?序列呢?
就算是add页面也一并满足MVC模式,用MVC模式的话则全部都满足,方便后期扩展需求,如统一记录日志,敏感词,登录状态等,而不需要针对某个页面特殊处理重写一遍
表单提交的3要求:
1.目标和发送方式
2.name
3.设置value
谁访问目标,谁就在那个位置
<!--
表单元素form有如下两个提交方式:
1.onsubmit事件
该事件通过submit按钮自动触发
2.submit()方法
通过js调用这个方法
-->
连接里面不能直接写方法,必须先声明
<a href="javascript:">
//注意没有s,submit是方法
<a href="javascript:document.forms[0].submit();">
获取表单元素有哪些方法:
1. ByName是表单空间才能用
2. ById
3. ByTagName
4. 根据层次节点查询
document.forms[0].submit()"得到的是form数组,
等价于document.getElementBy??
登录页面之所以没反应,主要在
1.表单的username和password重复了,已经有name=""的情况下还加了name="adminCode"和name="password"
2.表单提交代码多处写错
<a href="javascript:document.forms[0].submit();">
中的document多了s,
submit少了()
——————————————————————————————————————————————————————
浏览器给servlet传参:location.href="toDeleteCost.do?id=${c.costId}";但是是get方法的,不是post
el的功能:
1.获取bean的属性
2.取到数据可以直接运算
3.直接获取请求参数: 在jsp上写:value=${param.adminCode}
el取到数据如果是空的,不会返回null,而是返回“”,这样对servlet不影响
解决登录页面账号密码错误的情况下账号和密码清空的情况,
在jsp的账号和密码的input上加value值,如下:
<input name="adminCode" value="${param.adminCode }"
<input name="password" value="${param.password }"
如果单纯设置value会在框内显示出值,明显不合理。但是用el就没问题
可以存数据的:
request--》登录一个request,查询一个request,一旦登录成功就销毁登录的request.请求来了,创建,请求走了就销毁
config--》任何一个servelt都是单例的,tomcat一启动就new然后init(可以改成先初始化再new),service()可以有多个,一旦tomcat关闭就destory()。一个servlet只有一个config,如果一个请求用一个servlet呢?如FindeServlet,AddServlet,LoginServlet,这时候就没法访问不同servlet的config
context---》一个项目只有一个context。多个浏览器多用户访问,则同一个context会被覆盖
————————————————————————————————————————
jsp4_Cookies_Session项目:
Cookie没有无参的构造方法,只有2个参数的构造方法,如下:
//将其存入cookie
//Cookie中只能存一份数据,而且只能存字符串
有多个就只能new多个Cookie
Cookie c = new Cookie(要存的数据的名字,来源值)
Cookie默认是看不到的
————————————————————————————————————————
public class LoginServlet
//接收参数
String code = req.getParameter("code");
//将其存入cookie
//Cookie中只能存一份数据,而且只能存字符串
Cookie c1 = new Cookie("code",code);
//将Cookie发送给浏览器,他会自动保存
res.addCookie(c1);
}
cookie的值可以修改,如获取name,setValue,但是记得改了之后再用addCookie()重新发送一遍
——————————————————————————————
public class IndexServlet
//获取浏览器传入的所有cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null){
res.setContentType("text/html;charset=utf-8");
PrintWriter out = res.getWriter();
for(Cookie c : cookies){
out.println(c.getName()+": "+c.getValue());
}
out.close();
}
——————————————————————————————————————————————
cookie默认存在内存中,秒数是负数,也可以存到硬盘上,如浏览器的“记住账号:
用方法:
void Cookie.setMaxAge(int seconds);
秒数如果是0则存到内存中,即刻删除
编码:
Cookie c2 = new Cookie("city",URLEncoder.encode("北京","utf-8"));
_______________________________________________________________________________________________
req.getContextPath()
浏览器出现这样是因为前一个milo的cookie对main目录有效,而后一个lvbu则对整个项目有效,两者并不冲突,不是
同一个目录因此不会覆盖,跟是否都写在硬盘上没关系。而访问cost目录的find则只能显示lvbu,因为lvbu对整个项目有效,
因此find能够访问lvbu,却不能访问milo
code: milo city: 北京 code: lvbu
Cookie的方法:
new Cookie(浏览器获取的字符串,源数据) //创建
addCookie(c1) //发送
setMaxAge(int seconds)//设置生存时间
Cookie c2 = new Cookie("city",URLEncoder.encode("北京","utf-8")); //编码
URLDecoder.decode("","")
setPath(req.getContextPath())//修改生效路径
cookie只能存字符串的原因:因为要在网上传输,给浏览器用的,只能是字符串
限制:
。可以被用户禁止
。会将状态保存在浏览器端,不安全。重要数据需要encryption
。只能保存少量的数据,大约4kb
。个数有限制
。只能保存字符串
————————————————————————————————————————
快捷键:
看大纲:ctrl+o
自动装入方法:alt+shift+m
——————————————————————————————————————————————
账号可保存在客户端的cookie,但是密码不行
Cookie的三个规则:
生存时间
有效路径
——————————————————————————————————————————————
logo栏设置:
<!-- <span><%request.getCookies();%></span> 然后遍历也可以 -->
<!-- EL的默认取值范围是page,request,session,application
EL也可以从cookie中获取数据,语法:
cookie.参数名.value
-->
<span>${adminCode}</span> 应该改成:
<span>${cookie.adminCode.value}</span>
————————————————————————————————————————————————
Session一使用服务器就自动new,而Cookie是自己手动new的
服务器把session装到request,然后把request给LoginServlet。servlet发给服务器,服务器发给浏览器一个Cookie id如101
1。 服务器自动创建cookie
2。 服务器将sid存入cookie
3。 服务器自动将cookie发送给浏览器
浏览器再次访问服务器,服务器发现有了cookie,就不再创建了,因此也不返回sid,而是根据浏览器提供的id 101去找session(前提是session还没释放该id)
找到session后放入request,发给登录页面的servlet
一个浏览器一个cookie,session也是一个浏览器一个,sesstion保存时间一般半小时
session给浏览器一个cookie,浏览器把cookie
虽然给进session的是String类型的code,但是session返回给浏览器的是Object类型,需要强转。session因为不是在网络上传输的,因此什么类型都可以
————————————————————————————————————————————————
javaEE目录结构:
Servlet的目录结构:
WebApp
--WEB-INF用户不能直接看到的文件夹
|-web.xml web部署描述文件
|-url与Servlet对应关系
包括需要权限的也是放在WEB-INF下
n%8 和 n&7都是对8取余,有什么区别:
15%8=7
18%8=2
...[0 , 8)
不管任何数对8取余都不超过8
模运算其实就是二进制的与运算。
n=20=00010100
m=7 =00001111
-------------------
与运算就是截取后面的位数,如8则截取低三位,最大余数是7
DMS项目非常重要!!!!!!!!!!
把DMS项目的逻辑架构做成思维导图
复习与或非/原码/反码/补码/以及浮点数格式化
HttpSession s = request.getSession(boolean flag);
true:有则使用,没有session则new
false:有则使用,没有,或虽然有sessionId但是没有session对象也是返回null,不会new。通常也不会设置为false
立即删除Session对象--》当退出或者注销的时候用:
Session.invalidate()
session默认生存时间是30分钟,tomcat也有检查时间,检查session周期
<session-config>
<session-timeout>30</session-timeout>
</session-config>
假如该用户10分钟没操作,但是还没达到生存时间30分钟,这时候就使用钝化,将session写入到硬盘,先释放内存,
因此session对象需要实现序列化
session依赖于cookie,当cookie被禁用了,session就不能用了
但是如果需要使用怎么办?使用url重写。在url上带上sessionId
<%-- <span><%request.getCookies();%></span> 然后遍历也可以 --%>
<!-- EL的默认取值范围是page,request,session,application
EL也可以从cookie中获取数据,语法:
cookie.参数名.value
-->
<%-- <span>${cookie.adminCode.value}</span> --%> cookie是特殊的,特殊对待
<span>${adminCode }</span> session是EL的默认取值范围page,request,session,application之一
string有一个忽略大小写的方法
code:用户输入的验证码
imgcode:系统生成的验证码
code.equalsIgnoreCase(imgcode)
发送给浏览器的类型可以查看tomcat的web.xml,里面有各种类型,如text/html,image/png
java对png的处理比对jpg好
读写属性3
setAttribute/getAttribute
.属性名 .id/.class/.? 如.id=要设置的值
???????
login登录页面中更改验证码
<td><img src="createImg.do" alt="验证码" title="点击更换" onclick="this.setAttribute('src','createImg.do');"/></td>
上一句的验证码点击对部分浏览器有效,火狐就不行,被认为源和目的一样,可以做以下改动
<td><img src="createImg.do" alt="验证码" title="点击更换" onclick="this.setAttribute('src','createImg.do?x='+Math.random());"/></td>
互联网公司对js更重视
_____________________________________________________________________________________________________________
cookie和session的作用(术语)
。HTTP协议是无状态协议(服务器默认没有记住浏览器)
。cookie和session是用来管理状态的(让服务器记住浏览器)
》状态:服务器记住浏览器的证明(就是一种数据)
——————————————————————————————————————————————————
过滤器/监听器:
Filter类实现的接口是javax.servlet的filter而不是其他
<filter-mapping>
<filter-name>log</filter-name>
<!-- 该Filter可以过滤哪些请求路径 -->
<!-- <url-pattern>/addCost</url-pattern> -->
<url-pattern>/*</url-pattern> 代表过滤所有请求
<!-- 注意:多个filter之间的调用顺序以filter-mapping的顺序为准 -->
LoginFilter就看session,如果session有adminCode说明已经登录成功了
filter的强大之处在于不需要更改业务代码
—————————————————————————————————————— //通过账号判断用户是否登录
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
//以session为依据,获取session
//可以把request强转成HttpServletRequest
//对参数转型,便于使用,原来的ServletRequest不好用
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
HttpSession session = req.getSession();
if(adminCode==null){
//未登录,重定向到登录
res.sendRedirect(req.getContextPath()+"/toLogin.do");
}else{
//已登录,请求继续
chain.doFilter(req,res);
}
HttpServletRequest继承自ServletRequest
ServletRequest接口。javaEE提供接口
HttpServletRequest继承ServletRequest
RequestFacade实现了HttpServletRequest,有tomcat提供的实现,其他的服务器厂商的实现类不同,但是继承了接口,都适用该接口,更换了非tomcat服务器也能正常使用该接口
声明父类型,实际传入子类型
都是声明接口,是为了方便不同厂商提供不同的实现类以实现该接口
——————————————————————————————————————————————
监听器能监听到Servlet的创建/销毁的事件
只有3个事件:
request/session/context
ServletRequestListener
--
--
HttpSessionListener
--
--
ServletContextListener
--
--
写一个类,实现该接口,然后配置
————————————————————————————————————————
ServletRequest和HttpServletResponse和HttpSession返回值类型:
Interface ServletRequest:
java.lang.String getParameter(java.lang.String name)
java.lang.Object getAttribute(java.lang.String name)
void setAttribute(java.lang.String name, java.lang.Object o)
Interface HttpServletResponse:
void sendRedirect(java.lang.String location)
Interface HttpSession:
java.lang.Object getAttribute(java.lang.String name)
void invalidate()
void setAttribute(java.lang.String name, java.lang.Object value)
jsp作用域对象:
request/session/application的作用域
request:只在单次请求中。如login和index是两个请求.request也有多个页面使用同一个请求的,如filter,?,?
session:同一个客户端,同一个浏览器.浏览器进程,只要当前页面没有被关闭(没有被程序强制清除),不管怎么跳转都是有效的
application:数据在不同的客户端中共享,服务器,只要服务器没有重启(没有被程序强制清除),数据就有效
page:只在当前jsp页面有效
从小到大:
page<request<session<application
转发是用request还是response?还是都能用?区别是?
重定向呢?
--转发使用getRequestDispatcher,因此只有request,而重定向才是response
req.setAttribute("error","密码错误");
req.getRequestDispatcher("WEB-INF/main/login.jsp").forward(req,res);
void sendRedirect(java.lang.String location)
Sends a temporary redirect response to the client using the specified redirect location URL.
res.setContentType("text/html;charset=UTF-8");
jQuery对象的访问方法?
each()
each(callback) 就像循环
$("Element").length;元素的个数,是个属性
$("Element").size();也是元素的个数,不过带括号的是方法
$("Element").get();某个元素在页面的集合,以数组的形式存储
$("Element").get(index);功能上和上面的相同,index表示第几个元素,数组的下标
$("Element").get().reverse();把得到的数组方向反转
$("Element").index($("Element2"));元素2在元素1中的索引值是
单机程序
网络程序-主机终端
网络程序-两层CS架构: 客户端+DB
网络程序-三层CS架构:客户端+应用服务器+db
网络程序-BS架构:B/S:Browser+Web Server + db
sun指定的一种用来扩展web服务器功能的组件规范
在servelet之前可以使用CGI(common gateway interface)程序扩展web服务
终端:chmod +x *sh 获取权限
开启:./startup.sh 不行试试sh startup.sh
关闭: ./shutdown.sh sh shutdown.sh
1.新项目,maven项目,war包
2.deployment...
3.导包:项目属性-》targeted runtimes-》勾选apache..
4.java文件放在java Resource,网页文件如注册页面reg.html,不需要重新配置web.xml的,
那么reg.html放在src的webapp下,
注意
注意
注意
不是在WEB-INF下,而是webapp下。webapp也就是项目根目录
5.add服务器到tomcat
maven中下一个包,其相关的包都会下载下来,而不需要自己一个一个下载
比如:hevean有几十个包
导入servlet包2种方法:
1)maven的pom搜javaee,选javaee javaee-api
或者:
2)
tomcat目录下的lib:servlet
eclipse内右侧servlet右键,属性,Targeted runtimes
右侧勾选Apache Tomcat,ok
src/main/resources内放自己写的配置文件
在java Resources的src/main/java建包
新建包,同时需要选择父类,选择HttpServlet-javax.servlet.http
新建TimeServlet.java后需要重写父类方法。右键,source-》Override..
选择:
service(HttpServletRequest,HttpServletResponse)
servlet:server let 服务的小片段
// TODO Auto-generated method stub 待完成
类名:一个对象,正名
别名是为了引用方便
<!-- 1.配置Servlet类,给它取一个别名。 -->
<servlet>
<servlet-name>time</servlet-name>
<servlet-class>web.TimeServlet</servlet-class>
</servlet>
<!-- 2.通过别名引用一个类,给它设置一个网络访问路径(网名),它必须以/开头。 -->
<servlet-mapping>
<servlet-name>time</servlet-name>
<url-pattern>/ts</url-pattern>
</servlet-mapping>
上面web.xml写完后,tomcat右键add_remove.左侧服务器add到右侧
这时servlet1将会被拷贝到之前在tomcat上双击配置的第二个的设置
也就是tomcat的安装目录
500:拼写错误,类名写错
405:方法声明有误
404:找不到资源
该了代码需要:tomcat右键publish
java能不能做网页:就是用servlet
php/python/java都是服务端程序
静态是网页是HTML,动态网页也是HTML,但是动态是用java拼的
回顾:JDBC/SQL的事务的4个协议:???????????????????/
————————————————————————————————————————————————————
## 4.对开发者的要求
#### 4.1 不需要我们做的事情
-浏览器和服务器通信的过程已经由他们实现了
-请求数据的打包(3部分)由浏览器实现了
-响应数据的打包(3部分)由浏览器实现了
### 4.2需要我们做的事情
-请求及响应的业务数据由开发者提供
-使用request处理请求数据,使用response处理响应数据
》》》学会使用request和response
迭代器是23中设计模式之一。
设计模式:
哪里用到了迭代器模式:JDBC的ResultSet,Iterator,Enumeration
迭代器基本都是while
响应数据包组成:
状态行:HTTP/1.1 200 OK 中的数字200表示成功,否则是404或者500等
reg.html不需要在web.xml配置
req.getParameter("") 取单个
如:
String user = req.getParameter("username");
req.getParameterValues("");
如:
String[] interests = req.getParameterValues("interest");
————————————————————————————————————————
<body>
<!-- action中路径的声明方式:
1.完整路径
http://localhost:8080/servlet2/reg
2.绝对路径
规则:/项目名/访问路径
举例:/servlet2/reg
3.相对路径
当前网页和目标网页的相对关系
当前:/servlet2/reg.html
目标:/servlet2/reg
相对路径是reg
上级写../
注意:绝对路径以/开头,相对路径不以/开头
-->
<form action = "reg" >
<p>账号:
。。。。。。。。。
。。。。。。。。。
request/response本次请求结束就会被销毁
//1.1--请求行request line
req.getMethod();
req.getServletPath();
req.getProtocol();
get和post请求的区别:
GET:通过路径发送数据,通过路径传参
缺点:参数传递过程中能够被看到,隐私性差
可以传少量数据
》》所有的请求默认都是get请求
POST:不是通过路径(请求行)传参,而是用实体内容(实体内容:具体的业务)传参
参数在传递过程中不可见,隐私性好
传递的数据大小不受限制
》》当form上增加了mothod="post"
## 4.如何选择?
查询时用get,一般查询条件较少
保存/提交时用post,此时数据较多
## 5.可以通过浏览器观察请求方式
-f12
-打开network
!!!!!!!!!
网上传输只能用byte不能用字符串,字节可以不需要指定编码,字符串需要指定字符集编码
_______________________________________________
mysql:show variables like "$char"
_______________________________________________
原来:
1 html页面表单form的action提交的对象就是web.xml的url-pattern
两者如果不一致就报404错。次分析在课件day01.html
2 注意缓存的问题,更改后使用HTML应该多次刷新后再试。如果路径名的后面还是之前的当然还是会
报错的。比如之前的action="aaa",改了之后而且web.xml也对应改了之后要注意看浏览器路径名是否
还是之前的 localhost:8080/项目名/aaa/
3 重启tomcat
访问静态网页路径:项目名/静态网页名.html ,如http://localhost:8080/svt/zhuce.html
访问动态的:项目名/url-pattern名 如:http://localhost:8080/svt/reg
————————————————————————————————————————————
day01
序列化:如果需要把数据存到硬盘或者网络传输都需要序列化
补充内容:
JavaBean:满足如下规范的类就叫bean
--必须要有包pacakage
--必须要有默认构造器
--必须要实现序列化接口
--通常有get/set方法
》》建议初学者将所有的类都满足规范
真正应用中dao需要实现一个接口
实现类写法:EmpDaoImpl
面试常用:preparedStatement和statement的区别
DBUtil如何分页:
不能返回结果集。因为DBUtil,管理连接,连接后才进行操作,获取结果集等等。之后就关闭
连接。刚给出结果集就关闭连接,则获取到的结果集什么都没有
因此,需要放到集合再关闭连接关闭回收资源如结果集
//1. 接收浏览器传过来的数据
//2. 查询数据库,增删改
//3. 返回响应信息
浏览器一旦提示保存,说明是格式错了,浏览器无法解析:如下text写成test
res.setContentType("test/html ; charset=utf-8");
tomcat下的部署的代码,也就是运行时的代码
workspace的是源代码
两者的结构不一样
开发还是在包模式下开发,也就是src/main/java
看则可以在src下看,因为src下也有
五。servlet访问路径的配置方式
## 1.精确匹配(/hi)
- 只有/hi这个名字可以访问此Servlet
- 此Servlet只能处理一个请求
## 2.通配符(/*)
- 所有的名字都可以访问此Servlet
- 此Servlet能处理一切请求
——如:<url-pattern>/*</url-pattern>
## 3.后缀(*.hi)
- 所有以hi为后缀的名字都可以访问此Servlet
- 此Servlet能处理多个请求
——如:<url-pattern>*.duang</url-pattern>
实际工作中第3中更灵活:如下:
do.hi
dept.hi
emp.hi
异常抛给服务器,而不是浏览器。浏览器只是请求
六:使用一个Servlet处理多个请求
Servlet的生命周期:
new:从无到有
init():已有,初始化
1.tomcat一已启动就实例化对象
2.然后调用无参的默认构造器初始化
3.调用service()
tomcat要求要有默认构造器,必须是无参的
如果要传参,就只能init()
几时销毁?
————————————————————————————————————
1.默认情况下,第一次访问servlet时tomcat会创建它
2.可以修改为,启动tomcat时,tomcat就创建servlet
3.第1(new)/2(init())/4 destroy()执行一次,第3步(service())执行多次
4.每个类型的servlet都只有单(个实)例
maven的包拷贝到tomcat的该项目的lib目录下
注意:手动部署导包的话,包不会自动导到tomcat的lib目录下
DBUtil就满足两种模式:
多例的生产模式:不断创建连接
单列模式:??????????????
———————————————————————————————————————————————
day03:
ServeltContext
分页:
怎么调用*.properties:--->properties
访问xml用什么技术:--->dom4j
处理动态网页用什么技术:--->j2ee的servlet
连接数据库用什么技术:--->JDBC
ServletConfig和ServletContext对web.xml的作用相当于dom4j
一个SCT对应多个Servlet
一个SCF对应一个Servlet
很多都要用参数就用SCT
SCT/SCF的底层就是dom4j,非必要使用的,可以 不用,但是使用了更方便
一。config和context---------------->>>>>>>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
## 1.对比
共同点:都能读取web.xml中的参数
- config和Servlet是1对1的关系
- context和Servlet是1对多的关系
》都是为Servlet服务的
## 2.config
- 假设开发一个网页游戏,当在线人数超出限制时要排队
- 最大在线人数MaxOnline可配置
- 只在登录(LoginServlet)时验证是否超出限制
》想要给某一个Servlet预置参数用config
## 3.context
- 软件都有各种查询功能,一般都支持分页
- 分页需要已知:当前页,每页显示多少条size
- 其中size一般可配置
- 多个查询功能都要使用size,使用context预置比较合理
》想要给多个Servlet预置参数用context
换一个servlet就换一个config
tomcat启动时启动n个Servlet,共用context
## 4.context特殊的用途
- 提示:之前使用config和context读取的都是常量
- context还可以读写变量。而config只能读取常量
专门建一个类用来做初始化
context在所有的servlet之前就已经创建
<load-on-startup>1</load-on-startup>可以先初始化后创建。数字1为最高优先级
InitServlet.init() 该类不需要重写service方法,不处理业务,只是初始化
————————————————————————————————————————————
Servlet上下文:理解为Servlet环境/
特点:
- 惟一性(一个Web应用对应一个servlet)
- 一直存在(只要容器不关闭,应用没有被卸载删除,servlet上下文就一直存在
————————————————————————————————————————————
二。Servlet线程安全问题:
## 1.什么时候有线程安全问题
### 局部变量:
- 局部变量存储于栈内
- 每个线程都有自己的栈针
》同时修改局部变量没有问题
### 成员变量
- 成员变量存储在堆内
- 多个线程共享同一份成员变量
》同时,并发修改同一个成员变量有问题
## 2.如何解决:
——————————————————————————————————————————————————————
>>>>>>>>>>>>>>>>>>>JSP<<<<<<<<<<<<<<<<<<
Servlet拼网页很麻烦,参考FindEmpServlet.java
Servlet有什么用?
---->处理HTTP协议。动态拼接网页
JSP?----->作用同Servlet。
Servlet:创建类,类中写标签。
JSP:在标签内写java。如,复制美工的静态网页,再在里面写java
JSP注释:
<!-- --> 不忽略java
<%-- --%> 万能注释,忽略java
语法规则:
表达式:
<%= %>
小脚本:
<% %>
page指令:
<%@page contentType="image/gif" %>
作用相当于Servlet的response.setContentType("image/gif");
JSP默认是text,可以不写。但是用图片等的时候需要写
jsp运行原理:详情看课件图片
找到jsp后翻译成Servlet
pageEncoding在翻译的时候被调用用
jsp里面能直接使用array,date等。因为是内置对象,也就是隐含对象(*)
jsp生成的java文件中就是在jsp代码前先声明变量
面试题:
请列举9个JSP隐含对象以及类型:
tomcat每一个项目只有一个context
注意:
JSP的开头的import导包不能用分号;结尾!!!!!!!!!!!!!!!
——————————————————————————————————————————————
Day05
转发:
Spring和SpringMVC是包含关系
# 一。开发模式
##
Model1:java套标签,标签套java,耦合度高
使用一个组件(要么servlet要么JSP)处理请求,处理业务,显示数据
没有公司用Model1,过时的
## 2.Model 2(面试题,极为重要!!!!!!)
把之前的一个组件干的事变成两个组件干
>>>>>------MVC-----<<<<<
引入了MVC设计模式对代码解藕。80s就有了,java中只是sun引入而已。
MVC是经典的设计模式,是代码的分层思想。
M--Model,业务层,用来处理业务
V--View,视图层,用来显示数据
C--Controller,控制层,用来调度,是业务层和视图层的桥梁
该模式可以对代码解藕,便于团队开发以及维护
————————————————————————————————————
FindEmpServlet.service(req,res)
jsp生成的对象是只有的:EmpListServlet.service(req.res)
实际上就是把req和res参数传给jsp生成的类Servlet的service()
声明变量
write标签
保留脚本
print表达式
————————————————————————————————————
Servlet调用了jsp生成的那个类,然后把req和res传给它
jsp不会乱调用其他的类,只有调用9个隐式对象
以后不要直接访问jsp,而应该访问作为Controller的Servlet。
在项目jsp2的员工查询案例中,不能再像之前那么访问emp_list.jsp了,而跟之前的之前学servlet那样访问servlet
而且,回忆下,在web.xml不是已经做了配置了吗?在之前(day04)刚用jsp时都不需要配置web.xml的
之前的jsp中直接写java业务代码,数据不可控
Model2的MVC中,业务直接在java中写,jsp只将业务结果显示,如案例中的emp_list.jsp只把接收到的查询结果显示出来
————————————————————————————————————————————————————
//1.接收参数
//2.查询所有的员工
EmpDao dao = new EmpDaoImpl();
List<Emp> list = dao.findAll();
// /webapp/emp_list.jsp
//将请求转发给jsp,让它继续处理
//把数据存到request。转发时通过request给对方
req.setAttribute("emps",list); //为什么是用Attribute?是跟ServletContext一样意思?
//当前: /jsp2/findEmp
//目标路径: /jsp2/emp_list.jsp
req.getRequestDispatcher("emp_list.jsp").forward(req,res); //取到转发器。把req和res给jsp
Forward:通知服务器,让服务器去转发
request和response是一个对象,放在堆中。
FindEmpServlet调用request和response,然后把处理好的业务数据给回request和response,然后
通知服务器转发。服务器再根据目的地找emp_list.jsp,把jsp翻译成java,然后request和response开始转发给
jsp的java,最后输出
————————————————————————————————————————————————————
面试题:转发和重定向的区别:
相同点:都是解决web组件之间的跳转问题
web组件:Servlet或JSP
区别:
--两者相互依赖时用转发
转发的特点:
--1.一次请求。也就是只有一个request
--2.地址不变
--3.服务器的A和B共用一个request,它们可以通过request共享数据
--4.只能将请求转发给项目内部的组件
重定向:
--1.二次请求
--2.地址会改变
--3.服务端的A和B使用不同的request,不能通过request共享数据
--4.可以将请求重定向到项目外部的组件
何时用转发或重定向?
--查询时用转发
--增删改后重定向到查询
——————————————————————————————————————————————
day6 7 8 是补充。2天 day09半天
先讲day09,EL表达式/JSTL在实际中很常用。
明天和下周一做项目
然后讲day 6 7 8
req
EL底层用到了类反射机制,因此jsp中不再需要import了
EL的第一个作用:获取bean属性,也就是javabean属性。
什么是javabean:
补充内容:
JavaBean:满足如下规范的类就叫bean
--必须要有包pacakage
--必须要有默认构造器
--必须要实现序列化接口
--通常有get/set方法
案例如下
告知这个类的名字是什么,就能自己去找
如告知stu类,getName
<servlet>
<servlet-name>findStudent</servlet-name>
<servlet-class>web.FindStudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>findStudent</servlet-name> //这里如果上下不一致,tomcat的Server也会开不起来
<url-pattern>/findStudent</url-pattern>
</servlet-mapping>
————————————————————————————————————
<!-- request.getAttribute("stu").getName() --> request.getAttribute("stu")获取的是Object
需要强转
<p>姓名:${stu.name }</p>
<!-- request.getAttribute("stu").getAge() -->
<p>年龄:${stu["age"] }</p>
<!-- request.getAttribute("stu").getId() -->
<p>课程:${stu.course.id }</p>
这里的id相当于自动补充了前面的get,组成getId()方法,当然不是属性,因为属性是私有的,当然不能访问,如Course类如下:
---->>
//Bean的属性id
//1.透过get方法所看到的属性
//2.去掉get然后首字母小写所获得的词
public Integer getId() {
return courseId;
}
————————————————————————————————————————————————
<!--
EL默认从下面4个对象中依次取值,这些对象都是隐含对象(内置对象),它们是EL的取值范围:
按照顺序取值,如果下面4个中都没有,就返回null
page->request->session->application
也可以明确指定取值的范围:
sessionScope.stu.name
requestScope.stu.name
-->
EL表达式的+号只能求和,不能拼接字符串
——————————————————————————————————————————————
用JSTL需要导包。需要pom里面搜索:
JSTL,
jstl jstl 1.2 jar
包下的META-INF下的tld实际是xml的标签,c-..是核心的标签库
如果是maven导包的,会自动拷贝到tomcat目录的lib下
如果是自己网页下载的,需要手动拷贝到tomcat/wtpwebapps/项目/WEB-INF/lib下
<short-name>c</short-name> 用的时候就是用这个短名
<uri>http://java.sun.com/jsp/jstl/core</uri> 这不是网址,是名字
然后在自己的jsp页面开头就这样:
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!doctype html>
服务器只会调用无参的
PageContext是一个管理者,可以调用另外的8个内置对象
tld的1-6都可以照抄
<validator>验证可以不写
自定义的tld要放在webapp/WEB-INF目录下
——————————————————————————————————————————
netctoss资费计费系统项目:
新建maven项目,导包:
1.导包:jstl
选择:jstl 1.2
2.导包:ojdbc
选择:com.oracle ojdbc14
10.2.0.4.0jar
3.导包:commons-dbcp
选择:commons-dbcp commons-dbcp的
commons-dbcp:1.4
DBUtil的config_properties文件不能放在项目的根目录下,而是必须放到
resource,只有这里项目部署的时候在会编译到正确位置
为何用ThreadLocal:
多次访问数据库,在查询过程中需要遍历,同时又要增删改等等,
如转账,查,取,查...
costDao.find()
EmpDao.update()
两者共用一个连接,因此DBUtil连接数据库就用ThreadLocal
学习云笔记的时候能加深对ThreadLocal的理解
如一注册就送一个笔记本,就可以在笔记本上记录数据
一个事务一个连接
log4j:记日志
选中代码,然后alt+shift+m就能自动加入到新方法中
获取路径名的4种方法:
Servlet
???????
find.jsp为何放到WEB-INF目录下?
java项目中WEB-INF里面的项目会被保护,不能直接被访问
而PHP则需要程序员自己写方法保护
netctoss_v1
--images
--style
--WEB-INF
图片放到项目根目录下了,jsp里面引入图片为何不是../images/01.jpg而是变成同级目录的路径images/01.jpg
答:因为访问的是动态网页,浏览器不知道有jsp。
地址栏是这样访问的:http://localhost:8080/netctoss_v1/findCost.do
也就是说访问的是findCost.do,而findCost.do是在项目netctoss_v1目录下的,这时候还没jsp的事。详细可以
查看浏览器的请求,最先请求的是findCost.do
重定向的使用:在项目EmpManager
日期如何插入数据库?序列呢?
就算是add页面也一并满足MVC模式,用MVC模式的话则全部都满足,方便后期扩展需求,如统一记录日志,敏感词,登录状态等,而不需要针对某个页面特殊处理重写一遍
表单提交的3要求:
1.目标和发送方式
2.name
3.设置value
谁访问目标,谁就在那个位置
<!--
表单元素form有如下两个提交方式:
1.onsubmit事件
该事件通过submit按钮自动触发
2.submit()方法
通过js调用这个方法
-->
连接里面不能直接写方法,必须先声明
<a href="javascript:">
//注意没有s,submit是方法
<a href="javascript:document.forms[0].submit();">
获取表单元素有哪些方法:
1. ByName是表单空间才能用
2. ById
3. ByTagName
4. 根据层次节点查询
document.forms[0].submit()"得到的是form数组,
等价于document.getElementBy??
登录页面之所以没反应,主要在
1.表单的username和password重复了,已经有name=""的情况下还加了name="adminCode"和name="password"
2.表单提交代码多处写错
<a href="javascript:document.forms[0].submit();">
中的document多了s,
submit少了()
——————————————————————————————————————————————————————
浏览器给servlet传参:location.href="toDeleteCost.do?id=${c.costId}";但是是get方法的,不是post
el的功能:
1.获取bean的属性
2.取到数据可以直接运算
3.直接获取请求参数: 在jsp上写:value=${param.adminCode}
el取到数据如果是空的,不会返回null,而是返回“”,这样对servlet不影响
解决登录页面账号密码错误的情况下账号和密码清空的情况,
在jsp的账号和密码的input上加value值,如下:
<input name="adminCode" value="${param.adminCode }"
<input name="password" value="${param.password }"
如果单纯设置value会在框内显示出值,明显不合理。但是用el就没问题
可以存数据的:
request--》登录一个request,查询一个request,一旦登录成功就销毁登录的request.请求来了,创建,请求走了就销毁
config--》任何一个servelt都是单例的,tomcat一启动就new然后init(可以改成先初始化再new),service()可以有多个,一旦tomcat关闭就destory()。一个servlet只有一个config,如果一个请求用一个servlet呢?如FindeServlet,AddServlet,LoginServlet,这时候就没法访问不同servlet的config
context---》一个项目只有一个context。多个浏览器多用户访问,则同一个context会被覆盖
————————————————————————————————————————
jsp4_Cookies_Session项目:
Cookie没有无参的构造方法,只有2个参数的构造方法,如下:
//将其存入cookie
//Cookie中只能存一份数据,而且只能存字符串
有多个就只能new多个Cookie
Cookie c = new Cookie(要存的数据的名字,来源值)
Cookie默认是看不到的
————————————————————————————————————————
public class LoginServlet
//接收参数
String code = req.getParameter("code");
//将其存入cookie
//Cookie中只能存一份数据,而且只能存字符串
Cookie c1 = new Cookie("code",code);
//将Cookie发送给浏览器,他会自动保存
res.addCookie(c1);
}
cookie的值可以修改,如获取name,setValue,但是记得改了之后再用addCookie()重新发送一遍
——————————————————————————————
public class IndexServlet
//获取浏览器传入的所有cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null){
res.setContentType("text/html;charset=utf-8");
PrintWriter out = res.getWriter();
for(Cookie c : cookies){
out.println(c.getName()+": "+c.getValue());
}
out.close();
}
——————————————————————————————————————————————
cookie默认存在内存中,秒数是负数,也可以存到硬盘上,如浏览器的“记住账号:
用方法:
void Cookie.setMaxAge(int seconds);
秒数如果是0则存到内存中,即刻删除
编码:
Cookie c2 = new Cookie("city",URLEncoder.encode("北京","utf-8"));
_______________________________________________________________________________________________
req.getContextPath()
浏览器出现这样是因为前一个milo的cookie对main目录有效,而后一个lvbu则对整个项目有效,两者并不冲突,不是
同一个目录因此不会覆盖,跟是否都写在硬盘上没关系。而访问cost目录的find则只能显示lvbu,因为lvbu对整个项目有效,
因此find能够访问lvbu,却不能访问milo
code: milo city: 北京 code: lvbu
Cookie的方法:
new Cookie(浏览器获取的字符串,源数据) //创建
addCookie(c1) //发送
setMaxAge(int seconds)//设置生存时间
Cookie c2 = new Cookie("city",URLEncoder.encode("北京","utf-8")); //编码
URLDecoder.decode("","")
setPath(req.getContextPath())//修改生效路径
cookie只能存字符串的原因:因为要在网上传输,给浏览器用的,只能是字符串
限制:
。可以被用户禁止
。会将状态保存在浏览器端,不安全。重要数据需要encryption
。只能保存少量的数据,大约4kb
。个数有限制
。只能保存字符串
————————————————————————————————————————
快捷键:
看大纲:ctrl+o
自动装入方法:alt+shift+m
——————————————————————————————————————————————
账号可保存在客户端的cookie,但是密码不行
Cookie的三个规则:
生存时间
有效路径
——————————————————————————————————————————————
logo栏设置:
<!-- <span><%request.getCookies();%></span> 然后遍历也可以 -->
<!-- EL的默认取值范围是page,request,session,application
EL也可以从cookie中获取数据,语法:
cookie.参数名.value
-->
<span>${adminCode}</span> 应该改成:
<span>${cookie.adminCode.value}</span>
————————————————————————————————————————————————
Session一使用服务器就自动new,而Cookie是自己手动new的
服务器把session装到request,然后把request给LoginServlet。servlet发给服务器,服务器发给浏览器一个Cookie id如101
1。 服务器自动创建cookie
2。 服务器将sid存入cookie
3。 服务器自动将cookie发送给浏览器
浏览器再次访问服务器,服务器发现有了cookie,就不再创建了,因此也不返回sid,而是根据浏览器提供的id 101去找session(前提是session还没释放该id)
找到session后放入request,发给登录页面的servlet
一个浏览器一个cookie,session也是一个浏览器一个,sesstion保存时间一般半小时
session给浏览器一个cookie,浏览器把cookie
虽然给进session的是String类型的code,但是session返回给浏览器的是Object类型,需要强转。session因为不是在网络上传输的,因此什么类型都可以
————————————————————————————————————————————————
javaEE目录结构:
Servlet的目录结构:
WebApp
--WEB-INF用户不能直接看到的文件夹
|-web.xml web部署描述文件
|-url与Servlet对应关系
包括需要权限的也是放在WEB-INF下
n%8 和 n&7都是对8取余,有什么区别:
15%8=7
18%8=2
...[0 , 8)
不管任何数对8取余都不超过8
模运算其实就是二进制的与运算。
n=20=00010100
m=7 =00001111
-------------------
与运算就是截取后面的位数,如8则截取低三位,最大余数是7
DMS项目非常重要!!!!!!!!!!
把DMS项目的逻辑架构做成思维导图
复习与或非/原码/反码/补码/以及浮点数格式化
HttpSession s = request.getSession(boolean flag);
true:有则使用,没有session则new
false:有则使用,没有,或虽然有sessionId但是没有session对象也是返回null,不会new。通常也不会设置为false
立即删除Session对象--》当退出或者注销的时候用:
Session.invalidate()
session默认生存时间是30分钟,tomcat也有检查时间,检查session周期
<session-config>
<session-timeout>30</session-timeout>
</session-config>
假如该用户10分钟没操作,但是还没达到生存时间30分钟,这时候就使用钝化,将session写入到硬盘,先释放内存,
因此session对象需要实现序列化
session依赖于cookie,当cookie被禁用了,session就不能用了
但是如果需要使用怎么办?使用url重写。在url上带上sessionId
<%-- <span><%request.getCookies();%></span> 然后遍历也可以 --%>
<!-- EL的默认取值范围是page,request,session,application
EL也可以从cookie中获取数据,语法:
cookie.参数名.value
-->
<%-- <span>${cookie.adminCode.value}</span> --%> cookie是特殊的,特殊对待
<span>${adminCode }</span> session是EL的默认取值范围page,request,session,application之一
string有一个忽略大小写的方法
code:用户输入的验证码
imgcode:系统生成的验证码
code.equalsIgnoreCase(imgcode)
发送给浏览器的类型可以查看tomcat的web.xml,里面有各种类型,如text/html,image/png
java对png的处理比对jpg好
读写属性3
setAttribute/getAttribute
.属性名 .id/.class/.? 如.id=要设置的值
???????
login登录页面中更改验证码
<td><img src="createImg.do" alt="验证码" title="点击更换" onclick="this.setAttribute('src','createImg.do');"/></td>
上一句的验证码点击对部分浏览器有效,火狐就不行,被认为源和目的一样,可以做以下改动
<td><img src="createImg.do" alt="验证码" title="点击更换" onclick="this.setAttribute('src','createImg.do?x='+Math.random());"/></td>
互联网公司对js更重视
_____________________________________________________________________________________________________________
cookie和session的作用(术语)
。HTTP协议是无状态协议(服务器默认没有记住浏览器)
。cookie和session是用来管理状态的(让服务器记住浏览器)
》状态:服务器记住浏览器的证明(就是一种数据)
——————————————————————————————————————————————————
过滤器/监听器:
Filter类实现的接口是javax.servlet的filter而不是其他
<filter-mapping>
<filter-name>log</filter-name>
<!-- 该Filter可以过滤哪些请求路径 -->
<!-- <url-pattern>/addCost</url-pattern> -->
<url-pattern>/*</url-pattern> 代表过滤所有请求
<!-- 注意:多个filter之间的调用顺序以filter-mapping的顺序为准 -->
LoginFilter就看session,如果session有adminCode说明已经登录成功了
filter的强大之处在于不需要更改业务代码
—————————————————————————————————————— //通过账号判断用户是否登录
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
//以session为依据,获取session
//可以把request强转成HttpServletRequest
//对参数转型,便于使用,原来的ServletRequest不好用
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
HttpSession session = req.getSession();
if(adminCode==null){
//未登录,重定向到登录
res.sendRedirect(req.getContextPath()+"/toLogin.do");
}else{
//已登录,请求继续
chain.doFilter(req,res);
}
HttpServletRequest继承自ServletRequest
ServletRequest接口。javaEE提供接口
HttpServletRequest继承ServletRequest
RequestFacade实现了HttpServletRequest,有tomcat提供的实现,其他的服务器厂商的实现类不同,但是继承了接口,都适用该接口,更换了非tomcat服务器也能正常使用该接口
声明父类型,实际传入子类型
都是声明接口,是为了方便不同厂商提供不同的实现类以实现该接口
——————————————————————————————————————————————
监听器能监听到Servlet的创建/销毁的事件
只有3个事件:
request/session/context
ServletRequestListener
--
--
HttpSessionListener
--
--
ServletContextListener
--
--
写一个类,实现该接口,然后配置
————————————————————————————————————————
ServletRequest和HttpServletResponse和HttpSession返回值类型:
Interface ServletRequest:
java.lang.String getParameter(java.lang.String name)
java.lang.Object getAttribute(java.lang.String name)
void setAttribute(java.lang.String name, java.lang.Object o)
Interface HttpServletResponse:
void sendRedirect(java.lang.String location)
Interface HttpSession:
java.lang.Object getAttribute(java.lang.String name)
void invalidate()
void setAttribute(java.lang.String name, java.lang.Object value)
jsp作用域对象:
request/session/application的作用域
request:只在单次请求中。如login和index是两个请求.request也有多个页面使用同一个请求的,如filter,?,?
session:同一个客户端,同一个浏览器.浏览器进程,只要当前页面没有被关闭(没有被程序强制清除),不管怎么跳转都是有效的
application:数据在不同的客户端中共享,服务器,只要服务器没有重启(没有被程序强制清除),数据就有效
page:只在当前jsp页面有效
从小到大:
page<request<session<application
转发是用request还是response?还是都能用?区别是?
重定向呢?
--转发使用getRequestDispatcher,因此只有request,而重定向才是response
req.setAttribute("error","密码错误");
req.getRequestDispatcher("WEB-INF/main/login.jsp").forward(req,res);
void sendRedirect(java.lang.String location)
Sends a temporary redirect response to the client using the specified redirect location URL.
res.setContentType("text/html;charset=UTF-8");
jQuery对象的访问方法?
each()
each(callback) 就像循环
$("Element").length;元素的个数,是个属性
$("Element").size();也是元素的个数,不过带括号的是方法
$("Element").get();某个元素在页面的集合,以数组的形式存储
$("Element").get(index);功能上和上面的相同,index表示第几个元素,数组的下标
$("Element").get().reverse();把得到的数组方向反转
$("Element").index($("Element2"));元素2在元素1中的索引值是
0 0
- 08Servlet
- 08 JSP&Servlet监听器
- Servlet
- servlet
- Servlet
- servlet
- Servlet
- servlet
- servlet
- Servlet
- Servlet
- servlet
- Servlet
- servlet
- servlet
- servlet
- Servlet
- servlet
- 猴子选大王
- 排序算法系列二之快速排序
- 字符串对齐
- golang实现简单文件服务器
- 基于Netty5.0中级案例一之Netty与Web
- 08Servlet
- 凤凰网实习生面试
- C++函数指针
- JVM知识点
- Codeforces Round #403 (Div. 2) B. The Meeting Place Cannot Be Changed 三分
- Java程序员必须知道的两个有关Eclipse设置
- (转)Eclipse快捷键
- 09Spring
- Java编程思想-第一章 1.1-1.4 读书笔记