javaweb概述
JDBC
-
JDBC(Java DataBase Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。简单说就是用Java语言来操作数据库。
-
jdbc原理
-
早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API实现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动。
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
JDBC – Java官方提供 – 一系列接口 – 规范
驱动 – 数据库厂商提供 – JDBC接口的实现类 – 实现
-
-
JDBC实现方式:Statement方式和 PreparedStatement方式,一般使用PreparedStatement,因为预编译SQL 语句,安全,避免SQL注入;
-
平替:DBUtils是Apache Commons组件中的一员,开源免费。是对JDBC的简单封装,用来操作数据库,简化JDBC的操作。可以将结果转换成List、Array、Set,bean等集合。
QueryRunner
:执行sql语句的类- 构造器:
QueryRunner()
,在事务里面使用; - 构造器:
QueryRunner(连接池对象)
- 构造器:
- sql语句的操作
update()
:执行INSERT、UPDATE、DELETE =》 返回行数query()
:执行SELECTbatch()
批处理
-
resultsethandler接口=> 定义了执行select操作后如何封装结果集
- BeanHandler(单行) --> 构造器需要一个Class类型的参数,用来把一行结果转换成指定类型的javaBean对象;
- BeanListHandler(多行) --> 构造器也是需要一个Class类型的参数,用来把一行结果集转换成一个javabean,那么多行就是转换成List对象,一堆javabean;
- MapHandler(单行) --> 把一行结果集转换Map对象;
- MapListHandler(多行) --> 把一行记录转换成一个Map,多行就是多个Map,即List;
- ScalarHandler(单行单列) --> 通常用与select count(*) from t_stu语句!结果集是单行单列的!它返回一个Object 聚合函数。
-
-
JDBC的使用:无论使用什么方式,思路基本相同
-
// 1、加载四大参数 String driverName = "com.mysql.jdbc.Driver"; //驱动名 String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false"; //连接数据库的url String username = "root"; //用户名 String password = "root"; //密码//2、加载驱动 Class.forName(driverName);//3、建立连接(从连接池里获取) Connection connection = DriverManager.getConnection(url, username, password);// 4、获取操作数据库的对象 并进行数据库的相关操作 //Statement方式 Statement statement1 = connection.createStatement(); ResultSet resultSet1 = statement1.executeQuery("SELECT * FROM user WHERE `id` = 1"); // 增、删、改使用executeUpdate // PreparedStatement方式 PreparedStatement statement2 = connection.prepareStatement("SELECT * FROM user WHERE `id` = ?"); statement2.setInt(1, 2); // 第一个参数是的值2 ResultSet resultSet2 = statement2.executeQuery(); // 增、删、改使用executeUpdate // Commons_DbUtils方式,这个有很多使用方式,这里只说一种 QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM `user` WHERE `id`=?"; User query = qr.query(connection, sql, new BeanHandler<>(User.class), 6);//返回User对象 ;`update()`:执行INSERT、UPDATE、DELETE System.out.println(query);// 5、释放资源 遵循先开后关原则,释放所使用到的资源对象。 if(Objects.nonNull(resultSet1)){resultSet.close(); // 如果不是查询就没有这个 } if(Objects.nonNull(resultSet2)){resultSet.close(); // 如果不是查询就没有这个 } if (statement1 != null) {statement1.close(); } if (statement2 != null) {statement2.close(); } connection.close();
-
-
数据库连接池:与其说连接池的概念不如说“池”的概念,比如连接池、线程池等等。都是先创建一定数量的对象,每次使用时从池中获取,使用完毕之后在扔到池中(因此不用关闭资源),节约了资源创建和初始化耗费的时间。Java为数据库连接池提供了公共的接口:
javax.sql.DataSource
,各个厂商可以让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池。-
使用连接池只是获取连接的方式不一样了,其他的正常使用
-
平替:Druid连接池:Druid是阿里巴巴开源的一个数据源,主要用于java数据库连接池,相比spring推荐的DBCP和hibernate推荐的C3P0、Proxool数据库连接池,Druid在市场上占有绝对的优势。
-
//创建Druid连接池对象 DruidDataSource dataSource = new DruidDataSource();//为Druid连接池设置参数 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false"); dataSource.setUsername("root"); dataSource.setPassword("root"); //初始化连接数量 dataSource.setInitialSize(10); //最大连接数量 dataSource.setMaxActive(100); //最小空闲连接 dataSource.setMinIdle(5);//从连接池中获取连接 Connection connection = dataSource.getConnection(); // 其他的参考上述
-
-
-
JDBC使用事务
-
try {con.setAutoCommit(false); // `setAutoCommit(boolean)`如果true(默认值就是true)表示自动提交,`con.setAutoCommit(false)`表示开启事务;//这代表多个JDBC操作con.commit();//try的最后提交事务 } catch() {con.rollback();//回滚事务 }
-
对应的sql事务为
-
# 1,开启事务 START TRANSACTION;# 多个SQL操作# 提交事务 COMMIT; # 回滚 ROLLBACK;
-
web概述
-
Web(World Wide Web) 即全球广域网,也称为万维网,简单理解就是网站
-
常见软件系统体系结构
- CS:(Client/Server,客户端/服务器模式):桌面级应用 响应速度快,安全性强,个性化能力强;例如QQ;需要编写服务器端程序,以及客户端程序,例如我们安装的就是QQ的客户端程序;
- 缺点:软件更新时需要同时更新客户端和服务器端两端,比较麻烦;
- 优点:安全性比较好(不安装软件就无法使用,自然安全)。
- BS:(Browser/Server,浏览器/服务器模式):web应用 可以实现跨平台,客户端零维护,但是个性化能力低,响应速度较慢。
- 优点:只需要编写服务器端程序,不需要安装专门的客户端软件,只需要浏览器就行;
- 缺点:安全性较差。
- CS:(Client/Server,客户端/服务器模式):桌面级应用 响应速度快,安全性强,个性化能力强;例如QQ;需要编写服务器端程序,以及客户端程序,例如我们安装的就是QQ的客户端程序;
-
web资源:web资源就是运行在服务器上的资源,比如放到web下的页面 js 文件 图片 css等。
- 静态web资源 :供人们浏览的数据始终是不变;不需要查数据库也不需要程序处理,直接就能够显示的页面,如果想修改内容则必须修改页面,但是访问效率相当高。例如:HTML、CSS、JavaScript、各种图片
- 动态web资源:动态资源就是web页面中供人们浏览的数据是由程序产生的,不同的用户或者不同时间点访问web页面看到的内容各不相同;如果客户端请求的是动态网页,服务器需要先把动态网页转换成静态网页,然后再把转换后的静态网页响应给客户端。所以从广义上讲,用户看到的都是静态网页;例如:Servlet、JSP、ASP、PHP,但是在Java里面只涉及JSP/Servlet。在Java中,动态web资源开发技术统称为JavaWeb
-
怎么访问web资源
-
URL(Uniform Resource Locatior) 统一资源占位符,表示Intenet上某一资源的地址。格式:协议://主机地址:端口号/资源地址
-
URL url = new URL("http://www.baidu.com:80/index.html?name=567&age=23#header"); System.out.println("协议:" + url.getProtocol()); System.out.println("主机:" + url.getHost()); System.out.println("端口:" + url.getPort()); System.out.println("请求资源1:" + url.getFile()); System.out.println("请求资源2:" + url.getPath()); System.out.println("参数:" + url.getQuery()); System.out.println("锚点:" + url.getRef());
-
-
-
Web服务器:Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问。
- IIS (Internet Information Services): 互联网信息服务,只能在微软公司的windows操作系统下使用
- Nginx:反向代理、负载均衡
- Apache :代码开源,使用最广,运行在多种操作系统。Apache只支持静态网页,但像asp,php,cgi,jsp等动态网页就需要Tomcat来处理。 =》 apache搭建图片服务器
- Tomcat : 是Apache的扩展,用来处理动态资源
Servlet
-
JavaWeb的三大组件(Servlet、Filter、Lisener)之一,是动态资源的一种 。 启动的顺序为:监听器 -> 过滤器 -> servle
-
servlet概述
-
Servlet(Server Applet),称为小服务程序或服务连接器,是由服务器端调用和执行的、按照Servlet自身规范编写的Java类。
-
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
-
Servlet是单例的,一个类型的Servlet只有一个实例对象。Servlet不是线程安全的,不应该在Servlet中创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。
- 不要在Servlet中创建成员,创建局部变量即可;
- 可以创建无状态成员;
- 可以创建有状态的成员,但状态必须为只读的。
-
作用:
- 接收请求
- 处理数据
- 完成响应
-
-
servlet体系结构图
-
快速入门
- 配置JDK、tomcat、idea新建javaweb项目
- 实现servlet的三种方式
- 实现Servlet接口
- 继承GenericServlet类 => 重写抽象service方法
- 继承HttpServlet类=》重写doGet/doPost/doPut…方法
- 配置/注册Servlet的两种方式
- web.xml
- 注解方式
- 运行项目,访问指定servlet
-
tomcat 容器是如何创建 servlet 类实例?用到了什么原理?=》也就是servlet生命周期的第二步
- 浏览器输入访问路径后,携带了请求行,头,体
- 根据访问路径找到已注册的servlet名称
- 根据映射找到对应的servlet名
- 根据根据servlet名找到我们全限定类名,既我们自己写的类,服务器找到全限定类名后,通过反射创建对象,
-
Servlet的运行过程 / 生命周期
-
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
- Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
- 由web服务器(tomcat)装载并创建该Servlet的一个实例对象(通过xml或者注释中的全限定名 通过反射创建对象)。同时也创建了servletConfig,里面存放了一些初始化信息(注意服务器只会创建一次servlet对象,所以servletConfig也只有一个)
- 调用Servlet实例对象的init()方法。
- 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
- WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
-
-
request
-
获取请求头(地址栏信息等)
String getMethod()
:返回请求方法,例如:GETString getRemoteAddr()
:返回当前客户端的IP地址String getRemoteHost()
:返回当前客户端的主机名,但这个方法的实现还是获取IP地址String getServerName()
:返回主机名,例如:localhostint getServerPort()
:返回服务器端口号,例如:8080
-
获取请求参数
String getParameter(String name)
:通过指定名称获取参数值(必须掌握)String[] getParameterValues(String name)
:当多个参数名称相同时,可以使用方法来获取Enumeration getParameterNames()
:获取所有参数的名字Map getParameterMap()
:获取所有参数封装到Map中,其中key为参数名,value为参数值,因为一个参数名称可能有多个值,所以参数值是String[],而不是String
-
请求乱码问题处理
-
Get请求乱码:Tomcat8的版本中get方式不会出现乱码了,因为服务器对url的编码格式可以进行自动转换。
-
POST请求乱码:解决方案:使用从ServletRequest接口继承而来的
setCharacterEncoding(charset)
方法进行统一的编码设置。- request.setCharacterEncoding(“utf-8”);
-
-
请求转发
- 创建调度器
RequestDispatcher rd = request.getRequestDispatcher("/BServlet");
- 转发
rd.forward(request, response);
- 创建调度器
-
-
response
-
设置响应正文
PrintWriter out = response.getWriter()
:获取字符流ServletOutputStream out = response.getOutputStream()
如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream();- 注意:在一个请求中,不能同时使用这两个流,也就是说,要么你使用
repsonse.getWriter()
,要么使用response.getOutputStream()
,但不能同时使用这两个流。不然会抛出IllegalStateException
异常。
-
设置响应头信息 - 响应乱码问题处理
-
所有乱码其实就一个原因就是就是编码解码方式不一样,在服务器中使用的编码解码方式默认为:ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,因此服务器也需要设置以UTF-8字符
-
使用
response.setContentType("text/html;charset=utf-8")
;一定要在获取输出流前进行设置;- 设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据;
- 这个方法还会调用
response.setCharacterEncoding(“utf-8”)
保证输出给客户端的字符都是使用UTF-8编码的。
-
-
重定向/状态码
-
方式1
- 设置响应码
response.setStatus(302);
; - 设置重定向的位置
response.setHeader("Location", "/项目名/bServlet");
。
- 设置响应码
-
方式2
response.sendRedirect("/项目名/bServlet");
-
-
-
请求转发和重定向的区别
- 请求转发是一个请求,而重定向是两个请求
- 请求转发后浏览器地址栏不会有变化,而重定向会有变化,因为重定向是两个请求
- 请求转发的目标只能是本应用中的资源,重定向的目标可以是其他应用
- 请求转发对AServlet和BServlet的请求方法是相同的,即要么都是GET,要么都是POST,因为请求转发是一个请求
- 重定向的第二个请求一定是GET
会话技术_cookie_session
-
cookie:保存在浏览器
-
Cookie概述
- cookie就是服务器端⽤来区分访问⽤户的,实现持久化会话的最好⽅式。
- 浏览器与WEB服务器之间是使用HTTP协议进行通讯的,而HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断浏览器身份,即无论浏览器是否已经访问过,服务器都会当成第一次来对待。这时就需要一个能保存访问状态的信息,去告诉服务器我已经访问过你了。而这个信息就可以使用Cookie来保存。
-
cookie的原理
- Cookie实际上是一小段的文本信息(key-value格式)。浏览器向服务器发起请求,如果服务器需要记录该状态,服务器就会向在HTTP响应头中附带传送给浏览器的一小段数据。浏览器会把Cookie保存起来。当浏览器再请求该服务器时,都应在HTTP请求头中将这个Cookie回传给Web服务器 。服务器检查该Cookie,以此来辨认浏览器状态。
- 注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。
-
cookie使用
-
// 获取所有cookie Cookie[] cks = request.getCookies(); // 添加cookie Cookie cookie = new Cookie("name", "zs");// 创建Cookie cookie.setMaxAge(-1);//设置Cookie的超时时间 -1表示一旦关闭浏览器窗口,那么cookie就会消失 response.addCookie(cookie);// 添加到response对象中,响应时发送给客户端 这是添加cookie也是修改cookie
-
-
Cookie是怎么分类的?
- 会话cookie。临时cookie,记录了⽤户访问站点时的设置和偏好。⽤户退出浏览器时,会话cookie就被删除了。
- 持久cookie。持久cookie的⽣存时间更长⼀些;它们存储在硬盘上,浏览器退出,计算机重启时它们仍然存在
唯⼀区别就是它们的过期时间。如果设置了Discard参数或没有设置Expires或没有设置Max-Age参数则说明这个cookie就是⼀个会话cookie。
-
Cookie的生命
- Cookie不只有name和value,Cookie还是生命。所谓生命就是Cookie在客户端的有效时间,可以通过
setMaxAge(int)
来设置Cookie的有效时间。
cookie.setMaxAge(-1)
:cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。cookie.setMaxAge(60*60)
:单位是秒。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活;cookie.setMaxAge(0)
:cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。
- Cookie不只有name和value,Cookie还是生命。所谓生命就是Cookie在客户端的有效时间,可以通过
-
-
session:Session是服务器端对象,保存在服务器端。
-
关于会话:
- 会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束
- 一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器
- 类似生活中的对话
javax.servlet.http.HttpSession
接口表示一个会话,是Java Web提供的。
-
session原理
- Session底层依赖Cookie
- 当用户第一次使用session时(表示第一次请求服务器),服务器会创建session,并创建一个Cookie,在Cookie中保存了session的id,发送给客户端。这样客户端就有了自己session的id了。但这个Cookie只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie就会丢失,也就丢失了sessionId;
- 当用户第二次访问服务器时,会在请求中把保存了sessionId的Cookie发送给服务器,服务器通过sessionId查找session对象,然后给使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session对象。这样也就可以让多个请求共享同一个session了;
- 当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了sessionId,那么服务器会创建一个session,再把sessionId通过Cookie保存到浏览器中,也是一个新的会话开始了。原来的session会因为长时间无法访问而失效;
- 当用户打开某个服务器页面长时间没动作时,这样session会超时失效,当用户再有活动时,服务器通过用户提供的sessionId已经找不到session对象了,那么服务器还是会创建一个新的session对象,再把新的sessionId保存到客户端。这也是一个新的会话开始了。
- Session底层依赖Cookie
-
session快速入门
-
//获取Session HttpSession session = request.getSession(); //在Session域中存放数据 session.setAttribute("name", "zs"); //从Session域中获取数据 String name = (String)session.getAttribute("name"); System.out.println(name);
-
-
jsp与jstl
-
jsp概述
- JSP(Java Server Pages)是JavaWeb服务器端的动态资源,是一种动态网页开发技术。它与HTML页面的作用是相同的**,显示数据和获取数据**。EL主要是用于作用域获取数据,虽然可以做运算判断,但是得到的都是一个结果,做展示;EL不存在流程控制。比如判断;EL对于集合只能做单点访问,不能实现遍历操作。比如循环。
- JSP原理
- JSP是特殊的Servlet(查看编译后的JSP源码)类,当JSP页面首次被访问时,容器(Tomcat)会先把JSP编译成Servlet,然后再去执行Servlet。所以JSP其实就是一个Servlet。
- JSP注释
<%-- ... --%>
, 在JSP编译成.java时会被忽略的,即JSP注释。<!-- … -->
,html注释,但这个注释在JSP编译成的.java中是存在的,它不会被忽略,而且会被发送到客户端浏览器。
- jsp脚本:本质上就是Java代码片段
<%...%>
:Java语句<%!...%>
:Java定义类成员内置对象(无需创建就可以使用的对象),但是最好不使用,因为不安全<%=…%>
:与out.print()功能是相同的,它们都是向客户端输出。out对象在JSP页面中无需创建就可以使用,它的作用是用来向客户端输出;
-
三大指令
- page指令 :设定当前JSP网页的静态属性/依赖属性,比如脚本语言、编码、导入包、错误页面等
- include指令 :用来向当前页面插入一个静态文件的内容。这个文件可以是JSP、HTML、文本或是Java程序。
- taglib指令 :用于在 JSP 页面中导入标签库(JSP 标准标签库、第三方标签库、自定义标签库)。
-
七大动作标签
- jsp : include: 用于动态引入一个 JSP 页面。
- jsp : forward: 执行页面转向,将请求的处理转发到下一个页面。作用与RequestDispatcher.forward()方法相同
- jsp : param: 用于传递参数,必须与其他支持参数曲标签一起使用。
- jsp : plugin: 用于下载 JavaBean 或 Applet 到客户端执行。
- jsp : useBean: 使用 JavaBean。
- jsp : setProperty: 修改 JavaBean 实例的属性值。
- jsp : getProperty: 获取 JavaBean 实例的属性值。
-
九大内置对象
pageContext(PageContext)
:页面上下文对象,它是最后一个没讲的域对象request(HttpServletRequest)
:即HttpServletRequest类的对象(注意)session(HttpSession)
:即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>
,说明这个页面不能使用sessionapplication(ServletContext)
:即ServletContext类的对象(注意)
out(JspWriter)
:等同与response.getWriter(),用来向客户端发送文本数据config(ServletConfig)
:对应”真身”中的ServletConfigpage(当前JSP的真身类型)
:当前JSP页面的“this”,即当前对象exception(Throwable)
:只有在错误页面中可以使用这个对象response(HttpServletResponse)
:即HttpServletResponse类的对象(注意)
-
EL表达式
-
EL:Expression Language,表达式语言。在JSP页面中可以直接使用,从JSP2.0开始,代替JSP脚本,非Java开发人员也可以使用。
-
获取基本类型
-
${scope.name}
获取具体某个作用域中的数据;-
<%-- 使用EL表达式获取某个域中的数据并在网页上显示作用域 xxxScope--%> <p>${requestScope.name}</p>
-
-
${name}
获取作用域中的数据,逐级查找(pageContext、request、session、application)-
<%--全域查找如果没有限定xxxScope,会按照pageContext,request,session,application的顺序进行查找--%> <p>${name}</p>
-
-
-
获取引用数据类型
-
<%--通过EL表达式在页面上显示对象中的属性前提:属性要有对应的set和get方法--%> <p>${requestScope.person.id}</p> <%-- 通过EL表达式在页面上显示数组中的元素 --%> <p>${requestScope.arr[3]}</p>
-
-
EL表达式运算符
+ - * /
等等
-
-
JSTL
-
可对EL获取到的数据进行逻辑操作;与EL合作完成数据的展示。
-
<!-- 当条件为true时执行标签体内容 --> <c:if test="${条件}"> hello </c:if> 。。。
-
域对象
- 概述:通俗的讲就是这个对象本身可以存储一定范围内的所有数据,通过它就能获取和存储数据,用于数据共享。
- 域对象通用方法
- getAttribute(String name) 获取对应的数据
- getAttributeNames()获取所有的key
- removeAttribute(String name) 移除对应的数据
- SetAttribute(String name, Object object) 设置数据
- 域对象范围
jsp | servlet | 作用域 |
---|---|---|
page =》 pageContext | 在同一个页面有效 | |
request | HttpServletRequest | 在同一次请求(请求页面)间有效,一般请求完毕则失效,但若是通过forward的方式跳转,则forward页面依旧能拿到request的值。 |
session | HttpSession | 当前会话有效=》关闭、切换六千 |
application | servletContext | 当前应用有效,直到服务器停止才会失效 |
- 获取ServletContext
- GenericServlet,HttpServletRequest,HttpSession都提供了
getServletContext()
方法; - 在任意Servlet中,通过:this.getServletContext() 方法获取。
- GenericServlet,HttpServletRequest,HttpSession都提供了
- 获取HttpSession
- HttpSession session = request.getSession();
Filter
-
filter概述
- Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。
- 与Servlet类似,用来拦截请求,不同的是 当且仅当满足条件的时候才会放行,不是用来处理请求的;
- WEB开发人员通过Filter技术,对web服务器管理的所有web资源。常用场景有:
- 资源拦截:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。
- 权限控制:例如实现URL级别的权限访问控制
- 过滤敏感词汇
- 压缩响应信息
- 乱码处理
- 登录验证
-
filter快速入门
- 实现Filter接口
- 配置Filter =》xml / 注解
-
Filter是如何实现拦截的?
-
Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
- 调用目标资源之前,让一段代码执行。
- 是否调用目标资源(即是否让用户访问web资源)。
- 调用目标资源之后,让一段代码执行。
-
web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对 象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方 法,即web资源就会被访问,否则web资源不会被访问。
-
-
Filter的生命周期
-
init
:在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建,在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;doFilter
:这个方法会在用户每次访问目标资源(web.xml文件配置Filter的url-pattern中的路径)时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;destroy
:服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。
-
-
过滤器链
- 客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
- 每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
-
过滤器优先级
- 如果为注解的话,是按照类全名称的字符串顺序决定作用顺序;
- 如果web.xml,按照 filter-mapping注册顺序,从上往下;
- web.xml配置高于注解方式;
- 如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次。
Lisener
- Lisener概述(了解,实际中使用很少)
- JavaWeb中的监听器是Servlet规范中定义的一种**特殊类**,
- 在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContext,HttpSession和ServletRequest这三个域对象
三层架构与mvc设计模式
- 无论是MVC还是三层架构,都是一种规范,都是奔着**“高内聚,低耦合”**的思想来设计的,区别在于
- 三层架构是一个分层式的软件体系架构设计,适用于所有的项目。
- MVC模式是为了让前端和业务逻辑代码和数据分开,只使用在web项目中。
- 三层架构是框架层面上的。而MVC设计模式是设计模式层面上的。一个软件肯定要先确定好框架,之后才有下一步的设计模式。所以:三层架构明显是要高于MVC设计模式的。
- 三层架构:
- 表现层(UI:User Interface ): 主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。
- 业务逻辑层(BLL:Business Logic Layer ):UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。
- 数据访问层(DAL:Data Access Layer ): 也叫持久层。与数据库打交道。主要实现对数据的增、删、改、查。并返回信息给BLL
- 实体层(Entity):javabean 将上述联系起来。实体层是数据库表的映射对象,简单的说就是将获取到的数据库数据以对象的形式标示出来
- mvc设计模式
- Model(模型) 是应用程序中用于处理应用程序数据逻辑的部分。通常负责在数据库中存取数据。
- View(视图) 是应用程序中处理数据显示的部分。通常是依据模型数据创建的。
- Controller(控制器) 是应用程序中处理用户交互的部分。通常负责从视图读取数据,控制用户输入,并向模型发送数据。
- 三层架构: