Web基础之Servlet
Servlet
Servlet : server applet,直译服务小程序。那Servlet到底是什么呢?
Servlet说白了其实就是一个接口,接口的作用是什么?规范呗,这个接口规定了下面三个问题:
- 初始化时做什么
- 接收到请求时做什么
- 销毁时做什么
因此在Servlet中只添加业务逻辑,具体如何监听、用什么端口等由容器(如Tomcat)完成,servlet不关心也不需要关心。
Servlet在容器中的配置
在Tomcat中有两种方式配置Servlet,一种是在xml中配置,另一种是使用注解:
Xml配置Servlet:
<!--配置Servlet的类路径-->
<servlet>
<servlet-name>DemoServlet</servlet-name><!--servlet名-->
<servlet-class>com.heima.servlet.DemoServlet</servlet-class><!--类全名-->
</servlet>
<!--配置Servlet的映射路径-->
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name><!--映射Servlet名-->
<url-pattern>/demoServlet</url-pattern><!--访问路径-->
</servlet-mapping>
servlet 3.0 注解配置:
//直接在类名上使用注解:
@WebServlet(name = "Servlet", urlPatterns = "/1")
//或者省略模式:
@WebServlet("/1")//注解默认赋值给value,即urlPatterns
xml与注解优缺点分析:
xml优缺点:
- 优点:耦合性低,容易编辑,配置比较集中,方便修改,在大业务量的系统里面,通过xml配置会方便后人理解整个系统的架构
- 缺点:比较繁琐,类型不安全,配置形态丑陋,配置文件过多的时候难以管理,并且IDE不能检测配置的正确性
注解优缺点:
- 优点:方便,简洁,配置信息和 Java 代码放在一起,有助于增强程序的内聚性。
- 耦合性高,分散到各个class文件中,所以不宜维护
xml与注解应该通过合适的场景进行选择,快速开发时优先选用注解。
Servlet生命周期
Servlet对象在第一次被访问时由Tomcat容器创建,并且一个Servlet对象只会被创建一次,创建时调用init方法,在Tomcat关闭时销毁,销毁时调用destory方法。
Servlet可以配置为在Tomcat启动时直接创建,即在xml中添加<load-on-startup>number</load-on-startup>
number的大小为优先级:
- number取值小于0或不配置:被访问时才去加载;
- number取值为0时:最先被加载;
- number取值大于0时:数值越小Servlet越优先加载;
Servlet的实现类还可以在构造方法中说明被创建时做什么
GenericServlet
为了简化Servlet接口,GenericServlet提供了除service方法外的平庸实现。继承GenericServlet后只需要重写service即可。
HTTPServlet
HTTPServlet继承GenericServlet,专门用来处理HTTP请求,可以区分get和post方法,并针对不同的请求作出不同的响应。
简单来说,接口定义了规则,抽象类提供了模板,子类进行具体实现。
路径映射规范
不同的匹配方式均可访问到该Servlet:
匹配方式 | - | 描述 |
---|---|---|
完全匹配 | /user/login |
资源路径为/user/login时可以访问 |
目录匹配 | /user/* |
资源路径中含有/user目录均可访问 |
后缀名匹配 | *.do |
资源路径中以.do结尾的均可访问 |
缺省路径 | / |
访问的路径找不到,就会去找缺省路径 |
缺省时会在项目根目录寻找index.html文件。
开发中一般使用全路径配置。
注解在xml中对应的属性:
属性名 | 类型 | 描述 |
---|---|---|
name |
String | 指定Servlet的name属性,等价于<servlet-name> 。如果没有显示指定,则该Servlet的取值即为类的全限定名。 |
value |
String[] | 该属性等价于 urlPatterns 属性,两个属性不能同时使用。 |
urlPatterns |
String[] | 指定一组Servlet的URL匹配模式,等价于<url-pattern> 标签 |
loadOnStartup |
int | 指定Servlet的加载顺序,等价于<load-on-startup> 标签 |
initParams |
WebInitParam[] | 指定一组Servlet初始化参数,等价于<init-param> 标签 |
asyncSupported |
boolean | 声明Servlet是否支持异步操作模式,等价于<async-supported> 标签 |
description |
String | 该Servlet描述信息,等价于<description> 标签 |
displayName |
String | 该Servlet的显示名,通常配合工具使用,等价于<display-name> |
HTTP协议
HTTP:无状态的应用层协议。
主要的两种请求方式:
- Get:
- 没有请求体
- 提交数据的方式为在URL后拼接:
url?name1=value1&name2=value2
- Post:
- 有请求体
- 提交数据方式为在请求体中:
name1=value1&name2=value2
HttpServletRequest
浏览器的请求信息都封装在HttpServletRequest这个对象中。
常用API:
方法 | 说明 |
---|---|
String getMethod() |
获取请求方式的类型 |
StringBuffer getRequestURL() |
获取客户端发出请求完整URL |
String getRemoteAddr() |
获取IP地址 |
String getProtocol() |
获取当前协议的名称和版本 |
String getParameter(String name) |
获取指定name的value值 |
String[] getParameterValues(String name) |
获取指定name的value值数组(比如多选框) |
Map<String, String[]> getParameterMap() |
获取所有的数据封装到map中 |
请求头信息:
方法 | 作用 |
---|---|
String getHeader(String name) |
根据请求头的k关键字获取请求头信息 |
Enumeration getHeaderNames() |
返回此请求包含的所有头信息的枚举 |
getHeader中的关键字:
请求头key | 请求头value |
---|---|
referer | 浏览器通知服务器,当前请求来自何处,如果是直接访问,则不会有这个头。常用于:防盗链 |
If-modified-Since | 浏览器通知服务器,本地缓存的最后变更时间。与另一个响应头组合控制浏览器页面的缓存。 |
cookie | 与会话有关技术,用于存放浏览器缓存的cookie信息。 |
user-agent | 浏览器通知服务器,客户端浏览器与操作系统相关信息 |
connection | 保持连接状态。Keep-Alive 连接中,close 已关闭 |
host | 请求的服务器主机名 |
content-length | 请求体的长度 |
content-type | 如果是POST请求,会有这个头,默认值为application/x-www-form-urlencoded,表示请求体内容使用url编码 |
accept | 浏览器可支持的MIME类型。文件类型的一种描述方式。 |
mime格式 | 浏览器请求数据的类型,例如: text/html ,html文件 text/css,css文件 text/javascript,js文件 image/*,所有图片文件 |
accept-encoding | 浏览器通知服务器,浏览器支持的数据压缩格式。如:GZIP压缩 |
accept-language | 浏览器通知服务器,浏览器支持的语言。各国语言(国际化i18n) |
POST请求提交数据乱码问题:
原因:tomcat接收post请求数据采用的编码是ISO-8859-1,而我们的整个编码环境都是UTF-8。所以会导致乱码。
Servlet中获取数据前,将request编码设置为UTF-8:request.setCharacterEncoding("UTF-8")
;
request生命周期
每次请求都会创建一个新对象,请求完成、响应结束后request和response对象就销毁。
request域
request实现类中使用了一个Map来存储属性:
方法 | 说明 |
---|---|
void setAttribute(String name, Object o) |
往request域中设置值 |
Object getAttribute(String name) |
从request域中取值 |
void removeAttribute(String name) |
从request域中移除值 |
request.getAttribute(name)
:从rquest域对象中取值request.getParameter(name)
:从rquest中获取请求数据
作用范围:一次请求和响应之间。
请求转发
RequestDispatcher getRequestDispatcher(String path)
获取请求转发器(request对象方法)void forward(ServletRequest request, ServletResponse response)
传递request和response对象(转发器方法)
- 转发是服务器内部的跳转行为;
- 从一个Servlet转发到另一个资源(静态或动态),能够实现跳转,但是浏览器地址栏地址没有发生改变。因为对浏览器来说本质上就只有一次请求;
- 请求转发共享request域中的数据;
一个简单的登录功能执行顺序:
类分布:
servlet类接收请求后获取用户名和密码,封装为User并调用UserService类的方法验证登录,UserService方法调用Dao层的UserDao,Dao使用数据库工具类进行查询最后一步步返回。
HttpServletResponse
常见状态码:
状态码 | 状态码描述 | 说明 |
---|---|---|
200 | OK | 请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。 |
302 | Move temporarily | 重定向,请求的资源临时从不同的 URI响应请求。 |
304 | Not Modified | 从缓存中读取数据,不从服务器重新获取数据 |
404 | Not Found | 请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除。 |
403 | Forbidden | 服务器已经理解请求,但是拒绝执行它 |
405 | Method Not Allowed | 请求行中指定的请求方法不能被用于请求相应的资源 |
500 | Internal Server Error | 服务器内部错误。通常程序抛异常 |
HttpServletResponse常用API:
API | 描述 |
---|---|
setStatues(int code) |
设置状态码(响应行) |
setHeader(key,value) |
设置响应头(响应方式) |
常见响应方式:
响应头Key | 响应头value |
---|---|
refresh |
页面刷新,例如:3;url=www.baidu.com //三秒刷新页面到www.baidu.com |
content-type |
设置响应数据的类型(MIME类型)和编码格式 例如:text/html;charset=UTF-8 text/plain;charset=utf-8 (这个可以解决乱码) |
location |
指定响应的路径,需要与状态码302配合使用,完成重定向。 (value为URL) |
content-disposition |
通知浏览器以附件形式解析正文,例如:attachment;filename=xx.zip 。 |
- 转发和重定向:
【实现原理】转发在服务器内部发送,重定向是服务器操作浏览器发送请求
【请求次数】转发只有一次请求,重定向会有两次请求
【地址栏地址】转发不变,重定向后地址栏地址会变为第二次请求的地址 - 转发和重定向的作用:
【转发】完成跳转,共享request域对象(数据)
【重定向】完成跳转
重定向简写方式:response.sendRedirect("url");
设置响应体:
方法 | 说明 |
---|---|
java.io.PrintWriter getWriter() | 用于向浏览器输出字符数据。【字符流--给浏览器响应数据】 |
ServletOutputStream getOutputStream() | 用于向浏览器输出二进制数据。【字节流--文件下载】 |
ServletContext域对象
ServletContext域的作用范围为整个web项目
常用方法:
setAttribute(key, value)
getAttribute(key, value)
removeAttribute(key, value)
getRealPath(fileName)
getMimeType(fileName)
cookie&session
cookie存储在客户端,session存储在服务器,现在一般都是联合使用,使用cookie保存JSESSIONID,然后再服务器查询session。
Cookie
常用方法:
- 构造方法:
Cookie(name,value)
- 获取name值:
getName()
- 获取value值:
getValue()
- 设置cookie值:
setValue(value)
- ========================
- 发送cookie:
response.addCookie(cookie)
- 获取所有cookie:
Cookie[] getCookies = rquest.getCookies()
如果存在中文乱码可以使用java.net包下的URLDecoder类:
//先编码
URLEncoder.encode(cookie,"utf-8");//编码后会得到类似这样的编码值:%E6%9D%8E%E5%9B%9B
//再解码
URLDecoder.decode(cookie,"utf-8");//即可得到正确的值:李四
存活时间:
Cookie默认存活时间为会话级,也就是关闭浏览器后cookie消失。(如果CHrome中 启动时
设置为从上次的继续
则Cookie不会消失)
Cookie到期后会自动删除(浏览器行为)(服务器的时间和时区设置可能影响Cookie,对Chrome、IE而言,Cookie的有效时间段是理解为客户端的时间与服务器端时间的间隔,对于FireFox而言,Cookie的有效时间完全由服务器端的时间决定)
可以通过void setMaxAge(int seconds)
设置cookie的最大存活时间。默认为-1
,即会话结束后消失(关闭浏览器),设置为0时立即删除cookie。
有效路径
cookie可以通过setPath(String path)
设置cookie的有效路径,设置过后,在访问该路径及其子路径的时候会带上该cookie。一般情况下设置有效路径为/
或者不设置
删除Cookie
删除需要设置值为空:""
,设置最大存活时间为0,设置有效路径为原路径,然后在响应中添加这个Cookie。
session
常用API:
方法 | 使用示例 | 说明 |
---|---|---|
getSession() |
request.getSession() | 获取当前session |
void setAttribute(String name,Object value) |
session.setAttribute("loginUser",user) | 将一个对象与一个名称关联之后存储到session中 |
Object getAttribute( String name) |
session.getAttribute("loginUser") | 通过名称获取session中的数据 |
void removeAttribute(String name) |
session.removeAttribute("loginUser") | 根据指定名称删除session中的数据 |
String getId() |
String sessionId = session.getId() | 获取session的id |
invalidate() |
ression.invalidate() | 使当前session失效 |
session在第一次调用getSession()
时由Tomcat创建,并存在三种销毁方式:
- session手动销毁:
session.invilidate()
; - 过期销毁:session默认存活时间--30min
- 非正常关闭tomcat
Servlet很重要,但本文都只是些皮毛而已
更新Filter、Listener
Web基础之Filter、Listener
Filter过滤器
作用:对请求和响应进行拦截、放行、增强
接口方法:
destroy()
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
init(FilterConfig filterConfig)
分别是初始化、过滤、销毁。
使用XML配置的过滤器执行顺序按照XML从上到下,使用注解配置的过滤器按照实现了的类名顺序。
执行顺序:过滤器1前 -> 过滤器2前 -> Servlet -> 过滤器2后 -> 过滤器1后
过滤器生命周期和Servlet有些不一样:
- 当Web应用被加载时,Filter被Tomcat创建
- 当Web应用被卸载时,Filter被Tomcat销毁
- Filter只被创建一次,Filter线程不安全
Listener监听器
三种作用域:
作用域 | 接口名 | 作用范围 | 生命周期 |
---|---|---|---|
请求域 | HttpServletRequest | 一个用户的一次请求 | 在服务器接收到HTTP请求时就创建了 在服务器处理结束HTTP请求时就被销毁了 |
会话域 | HttpSession | 一个用户的所有请求 | 在第一用户请求服务器时被创建 服务器关闭、Session过期、手动销毁被销毁 |
上下文域 | ServletContext | 所有用户的所有请求 | 在服务器加载时/启动时被创建 在服务器卸载时/关闭时被销毁 |
八大监听器:
Servlet context events
Lifecycle(作用域监听) *
上下文域创建和销毁
javax.servlet.ServletContextListener
Changes to attributes(作用域内属性监听)*
上下文域属性增删改的操作
javax.servlet.ServletContextAttributeListener
HTTP session events
Lifecycle
会话域创建和销毁
javax.servlet.http.HttpSessionListener
Changes to attributes
会话域属性增删改的操作
javax.servlet.http.HttpSessionAttributeListener
Session migration
javax.servlet.http.HttpSessionActivationListener
钝化: 使对象随Session存储到硬盘中
活化:使对象随Session活化到内存中
Object binding
javax.servlet.http.HttpSessionBindingListener
使对象感知自己被放到session中,称为绑定setAttribute("user", new User())
使对象感知自己从session中移除,称为解绑removeAttribute("user")
Servlet request events
Lifecycle
请求域创建和销毁
javax.servlet.ServletRequestListener
Changes to attributes
请求域属性增删改的操作
javax.servlet.ServletRequestAttributeListener
Web基础之Servlet的更多相关文章
- Web基础和servlet基础
TomCat的目录结构 Bin:脚本目录(存放启动.关闭这些命令) Conf:存放配置文件的目录 Lib:存放jar包 Logs: 存放日志文件 Temp: 临时文件 Webapps: 项目发布目录 ...
- Java Web基础 --- Servlet 综述(理论篇)
摘要: Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.本文首先从请求/响应架构应用的大背景谈起 Servlet 的由来,明确 Ser ...
- J2EE基础之Servlet
J2EE基础之Servlet 1. 什么是Servlet? Servlet即Java服务小程序,是使用应用程序设计接口以及相关类和方法的Java程序.它可以作为一种插件,像Applet程序一样嵌入到 ...
- Web服务器与Servlet容器
今日要闻: Oracle启动了JRE7到JRE8的自动更新, JRE8发布于2014.3,于2014.10成为java.com默认版本, JRE7发布于2011.7, Oracle指定的Java生命政 ...
- java web基础环境搭建
java web基础环境包括:(1)servlet容器也即tomcat(2)jre即java程序运行环境 环境变量配置:分别下载jdk和tomcat安装包. jdk环境变量配置: 第一步:系统环境变量 ...
- java web基础 --- URL重定向Filter
java web基础 --- URL重定向Filter httpRequest.getRequestDispatcher("/helloWorld").forward(httpRe ...
- web基础笔记整理(一)
一.程序的分层 1.界面层: 某种类型的应用程序 a.DOS(控制台运行) b.桌面应用程序--独立安装,独立运行 c.web类型--现在流行的 单机版:电脑上要安装,程序升级之后,电脑上也要升级-- ...
- 20155312 张竞予 Exp 8 Web基础
Exp 8 Web基础 目录 基础问题回答 (1)什么是表单 (2)浏览器可以解析运行什么语言. (3)WebServer支持哪些动态语言 实践过程记录 1.Web前端:HTML 2.Web前端jav ...
- Exp 8 Web基础
Exp 8 Web基础 20154305 齐帅 一.实践要求: (1).Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. ...
随机推荐
- VMwara虚拟机三种网络模式
虚拟机:虚拟机是能够让用户在一台物理机上模拟出多个操作系统的软件其本质是通过中间层实现计算机资源的管理和再分配让系统资源的利用率最大化VMware即是一款虚拟机软件注意:虚拟机和操作系统的区别,虚拟机 ...
- java并发AtomicIntegerFieldUpdater
java并发AtomicIntegerFieldUpdater 支持对象的成员变量原子操作类由AtomicIntegerFieldUpdater,AtomicLongFieldUpdater, Ato ...
- Day9 - F - Monkey and Banana HDU - 1069
一组研究人员正在设计一项实验,以测试猴子的智商.他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子.如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉. ...
- springboot2.1mysql驱动类弃用
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdb ...
- ES6中 ,var,let和const的区别
var的特点 没有代码块的概念,全局范围内都有效 存在“变量提升”现象,即变量可以在声明之前使用,值为undefined let的特点 声明的变量仅在块级作用域内有效,存在了代码块的概念 不存在“变量 ...
- 第3节 sqoop:2、sqoop的基本简介和安装
3. sqoop数据迁移 3.1.概述 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具. 导入数据:MySQL,Oracle导入数据到Hadoop的HDFS.HI ...
- vscode dart 插件 关闭自动注释
vscode dart 插件 关闭自动注释 左下角设置 --> 搜索 Closing Labels --> 去掉勾选
- matlab练习程序(快速搜索随机树RRT)
RRT快速搜索随机树英文全称Rapid-exploration Random Tree,和PRM类似,也是一种路径规划算法. 和PRM类似,算法也需要随机撒点,不过不同的是,该算法不是全局随机撒点,而 ...
- 验证码取不到$_SESSION['code']的值,无法进行验证码正误验证问题
关键还是session启动问题.解释如下: //A.php session_start();//打开session 在每个页面使用Session前都需要先session_start $_SESSION ...
- 007、MySQL日期取当前时间,取昨天
#取今天文本格式 SELECT DATE_SUB( curdate( ), INTERVAL DAY ); #取昨天文本格式 SELECT DATE_SUB( curdate( ), INTERVAL ...