目录
通信模型
共享资源文件
——调用区别
控制浏览器三要素
服务器 与 表文件
Http网络协议包
——Http请求协议包
——Http响应协议包
网站内部结构
IDEA创建网站步骤
Servlet规范
——Servlet接口开发步骤
——Servlet对象生命周期
HttpServletResponse
HttpServletRequest
请求对象和响应对象生命周期
设置默认欢迎资源文件
Http状态码
多个Servlet的调用规则
——重定向
——请求转发
多个Servlet之间的数据共享
——ServletContext接口
——Cookie类
——HttpSession接口
————HttpSession 和 Cookie 区别
——HttpServletRequest接口
监听器接口
——ServletContextListener接口
——ServletContextAttributeListener接口
过滤器接口
恶意访问
通信模型
C/S通信模型
- C ,client software,客户端软件
- S ,server software,服务器软件
适用场景:普遍用于个人娱乐市场(如微信,淘宝)
优点:安全性高,可以降低服务端计算机的压力
缺点:更新较为繁琐,并且需要增加客户降低服务成本
B/S通信模型
- B ,browser,浏览器
- S ,server software,服务端软件
适用场景:既包括个人娱乐也包括企业日常活动
优点:不需要增加客户来降低服务成本,不需要更新浏览器
缺点:无法对服务端计算机资源文件进行有效保护,服务端运行压力大
共享资源文件
- 只要能通过网络进行传输的文件,都叫做共享资源文件
Http服务器下的共享资源文件分类
静态资源文件:
- 文件内容是固定的
- 文件存放的是命令,而这些命令只能在浏览器中编译和执行(.html/.css/.js)
动态资源文件:
- 文件存放的是命令,而且命令不能在浏览器中编译执行,只能在服务端计算机编译执行(.class)
调用区别
静态文件调用:
- Http服务器直接通过输出流将文件以二进制发送给浏览器
动态文件调用:
- Http服务器需要创建当前class文件的实例对象,对象调用对应方法去处理
控制浏览器三要素
- 控制浏览器请求地址
- 控制浏览器请求方式
- 控制浏览器请求参数
服务器
- 服务器是一种软件,不是硬件也不是计算机
表文件
- 一种以.frm结尾的一种文件,存于服务端计算机硬盘上
Http网络协议包
- 网络协议包是一组有规律的二进制数据,在这组数据中每一个空间专门存放特定信息,这样接收方可以到固定空间得到对应信息
网络协议包:ip地址,端口号,资源文件名
常见网络协议包:
- TFP网络协议包
- Http网络协议包
基于B/S的通信模型下使用的都是 Http网络协议包
Http请求协议包
- 分为4个空间
请求行:[
url:请求地址
method:请求方式
]
请求头:[
请求参数信息(GET方式)
Cookie
]
空白行:[
没有任何内容(用于分隔请求体,请求头)
]
请求体:[
请求参数信息(POST方式)
]
Http响应协议包
- 分为4个空间
状态行:[
Http状态码
]
响应头:[
content-type:指定浏览器用指定的编译器将二进制数据进行解析
展示不同类型的文件
Cookie
location
]
空白行:[
没有任何内容(用于分隔请求体,请求头)
]
响应体:[
被访问的静态资源文件内容
被访问的静态资源文件命令
被访问的动态资源文件运行结果
***都以二进制形式存在***
]
网站内部结构
src文件夹: 存放动态资源文件的Java文件
web文件夹:
存放静态资源文件
WEB-INF文件夹:
lib文件夹:存放网站运行时的jar包(mysql驱动)
web.xml文件夹:存放网站的核心配置文件(.xml)
IDEA创建网站步骤
- 在项目上点击鼠标右键,选择Add Framework Support,然后选择Web application
- 选择对应的Tomcat服务器(如果没有建立Tomcat服务器则新建一个),选择Deployment,按+按钮给Tomcat添加artifact
Servlet规范
- 属于JAVA EE规范中的一种
作用:
- 指定动态资源文件开发步骤
- 指定Http服务器调用动态资源文件规则
- 指定Http服务器管理动态资源文件实例对象规则
Servlet接口开发步骤
-
继承HttpServlet类(HttpServlet是抽象类并且实现了Servlet),使之实现为Servlet接口
-
重写HttpServlet父类的doGet和doPost两个方法
(因为父类HttpServlet中的service会调用doGet和doPost这两个方法)
@Override
public void doGet(HttpServletRequest req,HttpServletResponse resp)
throws ServletException {
}
HttpServletRequest,HttpServletResponse 都来自于servlet-api.jar包中
- 将Servlet接口实现类信息注册到Tomcat中
<servlet>
<servlet-name>NAME</servlet>
<servlet-class>com.power</servlet> <!--写入Servlet的路径-->
<servlet>
<servlet-mapping>
<servlet-name>NAME</servlet>
<url-pattern>/one</url-pattern> <!--给NAME取一个 url 简短别名,并且必须以'/'开头-->
<servlet-mapping>
Servlet对象生命周期
Servlet的实例化对象不需要开发人员来创建,而是由Http服务器自动生成
- 默认情况:在收到请求时HTTP自动创建实例化对象
- 手动配置的情况下:
<servlet>
<servlet-name>NAME</servlet>
<servlet-class>com.power</servlet>
<load-on-startup>10<load-on-startup><!--填写一个大于0的整数即可-->
<servlet>
- 在Http服务器运行期间,一个Servlet接口实现类只能被创建出一个对象
- 在Http服务器关闭时,销毁所有实例化对象
HttpServletResponse
- 负责将doGet/doPost方法的执行结果写入到响应体中交给浏览器
1.通过响应对象,获取输出流
PrintWriter out=resp.getWriter();
2.通过输出流,将执行结果以二进制形式写入输出流(这个流不需要关闭)
out.Write(result); //这里面是写入的是asc码
out.print(result); //这个更常用
使用resp.setContentType("text/html;charset=utf-8")进行设置
resp.sendRedirect(result);
//设置响应头中的location属性为result(网址重定向)
HttpServletRequest
String url = req.getRequestURL().toString();
//获取url
String method = req.getMethod();
//获取请求方式
String uri = req.getRequestURI();
//获取URI
Enumeration paramNames = req.getParameterNames();
//获取 请求头 中所有请求参数名,返回的是枚举对象
while(paramNames.hasMoreElements()){
String paramName = (String)paramNames.nextElement();
//获取单个变量名
request.getParameter(paramName);
//通过变量名获取变量值
}
GET方法发送请求是Tomcat来负责解码,用的是UTF-8
POST方法发送请求是请求对象来负责解码,用的是ISO-8859-1
在发送请求前,可以用req.setCharacterEncoding(“utf-8”)来解决
请求对象和响应对象生命周期
-
http服务器接收到以个请求协议包时,会自定生成一个请求对象和一个响应对象
-
在http服务器推送响应协议包前,会把请求对象和响应对象销毁
设置默认欢迎资源文件
- 规则位置:web/WEB-INF/web.xml
- 规则命令:
<welcome-file-list>
<welcome-file>login.html</welcome-file>
<welcom-file-list>
- 如果存在自定义的默认欢迎文件,这自带的默认欢迎文件会失效
默认欢迎文件也可以是动态资源文件,使用动态资源文件时使用servlet的别名,并且开头的 / 要去掉
Http状态码
- 通过状态码通知浏览器如何处理这个结构
- 通过状态码向浏览器解释不能提供该服务的原因
分类
- 100 — 599 分为 五个大类
100 | 通知浏览器该资源文件不是一个独立资源文件,接受后需要向Http服务器索要其他资源文件 |
---|---|
200 | 该资源文件是一个独立的资源文件 |
302 | 使用resp.sendRedirect()来重定位地址,使用的就是302状态码,Tomcat看到里面是一个地址,响应体却是空的。因此将302状态码写入状态行,而浏览器读取时,不会读取响应体内容,而是根据地址直接发起二次请求 |
404 | 没有定位到被访问的资源文件 |
405 | 已经定位到被访问的资源文件,但是对于Servlet的请求方式不能处理 |
500 | 已经定位到被访问的资源文件,请求方式也可以处理,但是由于Java异常导致处理失败 |
多个Servlet的调用规则
重定向
- 将上一次请求工作完毕后,下一次请求的地址写入到响应头的location中,Tomcat在发送过程中写入302状态码,交给浏览器,浏览器自动进入下一请求地址,减少了客户的操作量
- 一定会经过过滤器
实现代码:
resp.sendRedirect();
请求方式
- GET
优点
- 可以访问任意网页
缺点
- 重定向需要在浏览器和服务端之间多次往返,耗费时间
请求转发
- 上一次请求完毕后,通过 当前请求对象 代替 浏览器,向服务器发送请求,申请下一次请求,服务器接到请求后,自动调用下一请求
- 不会经过过滤器
实现代码:
当前请求对象生成资源文件申请报告对象
RequestDispatcher report = req.getRequestDispatcher("/资源文件名");
将报告对象发给服务器
report.forward(当前请求对象,当前响应对象);
缩写
req.getRequestDispatcher("/资源文件").forward(当前请求对象,当前响应对象);
请求方式
- 根据用户发送的请求行中的请求方式
优点
- 浏览器与服务器之间的往返次数少,加快了服务速度
缺点
- 只能调用当前网站下的资源文件地址,不能填写网站名
多个Servlet之间的数据共享
- 每一个网站有且只有一个全局作用域对象,在服务器开启时生成,在网站关闭时销毁
ServletContext接口
- 如果两个Servlet来自同一网站,则可以实现数据共享 ServletContext对象
- 一 般称作全局作用域对象
- 存在于servlet-api.jar中
实现
ServletContext application = req.getServletContext();
索要全局作用域对象
application.setAttribute("key",数据);
向全局作用域对象添加数据,本质是一个Map集合
application.getAttribute("key1");
向全局作用域获取数据
application.removeAttribute("key1");
删除共享数据
Cookie类
- 如果两个Servlet来自同一网站,并且为用一个浏览器/用户提供服务,则可以实现数据共享
- 将Cookie写入响应头交给浏览器,下一次再次访问同一网站时,浏览器无条件将之前的Cookie写入请求头中
- 存在于servlet-api.jar中
实现
Cookie cookie = new Cookie("key","value");
创建cookie对象,一个cookie对象只能放一个键值对,而且value一定是String类型
resp.addCookie(cookie);
将cookie对象写入响应头中交给浏览器
cookie.getName(); 读取key
cookie.getValue(); 读取value
默认情况下,浏览器关闭,cookie就会被销毁
在手动设置下,可以将cookie放在客户端计算机上,同时指定存活时间
cookie.setMaxAge(60); 设置在硬盘中存活1分钟
HttpSession接口
- 如果两个Servlet来自同一网站,并且为用一个浏览器/用户提供服务,则可以实现数据共享 HttpSession对象
- 一般称作会话作用域对象
- 存在于servlet-api.jar中
HttpSession 和 Cookie 区别
Cookie
- 存放在客户端计算机
- 数据类型只能是String
- 一个Cookie只能存储一个共享数据
HttpSession
- 存放在服务器计算机
- 数据类型可以是任意类型
- 一个HttpSession可以存放任意数量共享数据
实现
HttpSession session = req.getSession();
索要当前用户在服务端的会话
session.setAttribute("key",共享数据)
将数据写入会话中
session.getAttribute("key");
从会话中获取数据
Enumeration Names = session.getAttributeNames();
利用枚举类型获取会话中所有的key
在创建HttpSession对象时,Tomcat会自动为当前对象生成一个编码
存储在Cookie中,key为JSessionId
getSession() 和 getSession(false)
getSession() 会在当前用户没有对应的JSessionId时,为其创建一个
而 getSession(false) 则返回一个null
由于Tomcat并不能知道用户会在什么时候关闭浏览器,因此Tomcat为每一个HttpSession对象设置一个默认30分钟的 空闲时间,当空闲时间到达时,则会销毁对象
手动设置空闲时间
<session -config>
<session-timeout>5</session-timeout>
</session -config> 最大空闲时间为5分钟
HttpServletRequest接口
- 如果两个Servlet通过 请求转发 方式调用,彼此共享一个请求协议包,一个请求协议包对应一个请求对象,从而利用请求对象实现数据共享
- 当请求对象在实现 数据共享功能 时,通常将请求对象称为 请求作用域对象
req.setAttribute("key",共享数据);
向请求作用域对象中添加数据
req.getRequestDispatcher("/ServletName").forward(req,resp);
请求转发给另一Servlet
req.getAttribute("key");
获取数据
监听器接口
- 存在于servlet-api.jar包下的接口,共有8个接口
- 用于监控 作用域对象生命周期变化时刻 及 作用域对象共享数据变化时刻
实现步骤:
- 根据实际情况,选择对应的监听器接口
- 重写监听器接口(监听事件处理方法)
- 在web.xml中将接口注册到Http服务器
ServletContextListener接口
- 检测全局作用域对象 初始化时刻 及 销毁时刻
public void contextInitialized(ServletContextEvent sce){
ServletContext application = sce.getServletContext(); 获取全局对象
} 全局作用域对象 初始化 时调用
public void contextDestroyed(ServletContextEvent sce){
} 全局作用域对象被 销毁 时调用
<listener>
<listener-class>/ListenerName</listener-class>
</listener>
<!---注册监听器接口实现类--->
ServletContextAttributeListener接口
- 检测全局作用域对象 共享数据变化时刻
public void contextAdd(ServletContextAttributeEvent scae){
} 添加共享数据时触发
public void contextReplaced(ServletContextAttributeEvent scae){
} 更新共享数据时触发
public void contextRemove(ServletContextAttributeEvent scae){
} 删除共享数据时触发
过滤器接口
- 存在于servlet-api.jar包下
- 拦截Http服务器,帮助Http服务器检测请求的合法性
- 拦截Http服务器,对请求进行增强操作
实现步骤:
- 实现 Filter 接口
- 重写 Filter 接口中的 doFilter 方法
- 在web.xml中将接口注册到Http服务器
public void doFilter(ServletRequest servletRequest,ServletResponse
servletResponse, FilterChain filterChain)
throws IOException,ServletException{
//对所有的请求重新编译,使用utf-8字符集,称为增强
servletRequest.setCharacterEncoding("utf-8");
//请求合法,把请求对象、响应对象交还给服务器,称为放行
filterChain.doFilter(servletRequest,servletResponse);
//请求不合法,过滤器代替服务器拒绝请求
略
}
注册到xml文件
<filter>
<filter-name>OneFilter</filter-name>
<filter-class>FilterPath</filter-class>
</filter>
<filter-mapping>
<filter-name>OneFilter</filter-name>
<url-pattern>/urlName</url-pattern>
</filter-mapping>
Filter拦截地址格式
<url-pattern>/urlName</url-pattern>
只能是一个具体文件
<url-pattern>/urlName/*</url-pattern>
某文件夹下所有资源文件
<url-pattern>*.jpg</url-pattern>
任意文件夹下所有jpg文件
<url-pattern>/*</url-pattern>
任意文件
恶意访问
- 通过地址栏直接索要静态资源文件的方式,称为恶意访问
可以在LoginServlet通过时,创建一个HttpSession,表明是合法用户,若访问某静态资源文件时无HttpSession对象,则为恶意访问,可以拦截访问
缺点: 会使网站代码冗余,并且不能对静态资源有效保护
采用过滤器改善
HttpServletRequest request = (HttpServletRequest)servletrequest;
request.getSession();
//getSession()方法只能在HttpServletRequest对象下调用,因此做向下转型
使用过滤器很有可能把所有资源文件都禁止访问了,而登录页面和默认页面应该无条件放行,因此使用
if(uri.indexof("login") != -1 || "/默认页面/".equals(uri))
可以将包含了login的页面和默认页面放行
(因此在命名有关登录操作的页面或文件,都应该包含login字符串)