tomcat介绍:
软件架构:
两个非常典型的交互方式——B/S 交互模型(架构)和 C/S 交互模型(架构)
Browser/Server 浏览器/服务器
资源的分类
静态资源
对于同一个页面,不同用户看到的内容是一样的。
动态资源
用对于同一个页面,不同用户看到的内容可能不一样。
常见的Web服务器(对比python的wsgi)
* Tomcat: Apache组织开源免费的web服务器,支持JavaEE规范(Servlet/Jsp).
* Jetty:Apache组织开源免费的小型web服务器,支持JavaEE规范.
* JBoss: RedHat红帽公司的开源免费的web服务器,支持JavaEE规范.
* Glass Fish:Sun公司开源免费的web服务器,支持JavaEE规范.
---------------------------------------------------------------------
* WebLogic: Oracle公司收费的web服务器,支持JavaEE规范.
* WebSphere:IBM公司收费的web服务器,支持JavaEE规范.
JavaEE规范
在Java中所有的服务器厂商都要实现一组Oracle公司规定的接口,这些接口是称为JavaEE规范。不同
厂商的JavaWeb服务器都实现了这些接口,在JavaEE中一共有13种规范。实现的规范越多,功能越强。
下载:
https:
解压,执行startup.bat即可
访问8080端口
发布项目流程:
① webapps 部署
直接放置在 webapps 目录下,html文件
这种方案(支持热更新,将新的文件复制过去),一般在开发完毕后,来使用的
② server.xml部署
在tomcat/conf/server.xml中找到标签<Host>,添加标签<Context path="myapp" docBase="D:\webapps\myapp\" />
缺点
1.配置文件修改完毕后,需要重启后生效...
2.server.xml是tomcat的核心配置文件,如果稍有不慎操作失误,整个tomcat启动失败
3.这种方案作为了解即可
③ 独立xml部署
在tomcat/conf/Catalina/localhost 目录下创建一个myapp.xml文件,在文件里添加标签<Context docBase="D:\webapps\myapp\" />
热更新
使用Idea发布tomcat项目:
配置tomcat
新建Java EE项目
配置configuration,比如deployment,url,更新操作。
目录WEB_INF里的静态文件无法访问。
常见配置:
共享线程池:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
会给service组件下的容器使用,在如context、wrapper等容器需要的时候
Connector相关:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" maxThreads="1" redirectPort="8443" />
默认使用http-nio-{port}-exec-前缀的线程池,可以通过executor="tomcatThreadPool"使用指定的线程池,比如上面配置的tomcatThreadPool。
请求QPS的上限和该connector线程池的max有关。
该connector负责接收来自8080 connector转发的请求,可以独立配置线程池。
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
Servlet:
概述:
servlet= server+applet :运行在服务器端的java程序。
Servlet是一个接口,一个类要想通过浏览器被访问到,那么这个类就必须直接或间接的实现Servlet接口
与tomcat的关系:
客户端的请求直接打到tomcat,它监听端口,请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理
快速入门:
① 创建web项目(选择JavaEE)
② 编写普通java类,实现Servlet接口,重点是server方法。
③ 在web.xml配置url-pattern(或者通过@WebServlet("/hello-servlet")注解的方式)
servlet-name:当前servlet的别名(使用类名即可)
servlet-class:全限定类名
servlet-name:给指定别名的servlet配置映射
url-pattern:网络访问地址(注意:必须以/开头,后面是否有/也要匹配)
④ 部署web项目(ide自动配置)
⑤ 启动测试
执行原理:
通过url对应的class全限定名,反射获取对象,执行方法。
生命周期:
public void init(ServletConfig servletConfig);
public void service(ServletRequest servletRequest, ServletResponse servletResponse);
public void destroy();
配置启动时执行init方法
<load-on-startup></load-onstartup>
正数:4-N 【服务器启动时,创建】
补充:Tomcat的web.xml里有1,3 所以推荐4-n
负数(默认值):-1 【用户第一次访问时,创建】
体系结构:
Servlet(接口) -> GenericServlet(抽象类,实现大多数方法,只需重写service方法) -> HttpServlet(抽象类,处理http协议,根据不同的请求方式作出不同处理)
HttpServlet
根据不同请求方法调用不同方法。
doGet、doPost
url-pattern的配置方式:
1.Servlet映射多个url
多个servlet-mapping即可
2.url映射模式
精确匹配(掌握)/servletDemo3 localhost:8080/项目路径/servletDemo3
目录匹配/aa/*
后缀匹配*.xxx 例如:*.do
/完全匹配除xxx.jsp指定后缀外的所有路径。
Request对象:
概述:
用户通过浏览器访问服务器时,Tomcat将HTTP请求中所有的信息都封装在Request对象中
获取请求行信息:
1. 获取请求方式 GET【掌握】
String getMethod()
2. 获取项目虚拟路径(项目名)/servlet_demo【掌握】
String getContextPath()
3. 获取URL 如http:
StringBuffer getRequestURL()
4. 获取协议和版本号 HTTP/1.1
String getProtocol()
5. 获取客户端ip
String getRemoteAddr()
获取请求头信息:
1. 获取知道请求头名称对应的值,注:名称不区分大小写
String getHeader(String name)
2. 获取所有请求头的名称
Enumeration<String> getHeaderNames()
注:是Iterator前身
示例:
while(headerNames.hasMorehasMoreElements()){
String name = enumeration.nextElement();
String value = req.getHeader(name);
}
获取请求体信息(请求参数):
获取queryString参数,不能获取body。form表单的get通过key=value&的形式传输,post数据通过FORM-data的形式传输到body里面。
1. 获取指定参数名的值 username=jack
String getParameter(String name)
2. 获取指定参数名的值数组 hobby=drink&hobby=perm
String[] getParameterValues(String name)
3. 获取所有参数名和对应值数组,参数名 name(key),值数组 value,封装map集合
Map<String,String[]> getParameterMap()
4.getReader()
5.getInputStream()
中文乱码【重点】
get:在tomcat8及以上版本,内部URL编码(UTF-8)
post:编码解码不一致,造成乱码现象
客户端(浏览器)编码:UTF-8
服务器默认 解码:ISO-8859-1 拉丁文,导致了乱码。
指定解码:void setCharacterEncoding("UTF-8") 注:必须在方法内,行首
请求转发:
一种在服务器内部的资源跳转方式,只能转发服务器内部资源
1. 通过reqeust对象,获得转发器对象
RequestDispatcher getRequestDispatcher(String path)
2. 通过转发器对象,实现转发功能
void forward(ServletRequest request, ServletResponse response)
链式编程
request.getRequestDispatcher("/bServlet").forward(reqeust,response)
域对象(共享数据)
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于一次请求中转发的多个资源中共享数据
常用方法:
1. 设置数据
void setAttribute(String name, Object o)
2. 获取数据
Object getAttribute(String name)
3. 删除数据
void removeAttribute(String name)
生命周期:
开始:用户发送请求时,创建request
销毁:服务器返回响应是,销毁request
一次请求,包含多次转发
Response对象:
体系结构:
ServletResponse 接口
|
HttpServletResponse 接口
|
org.apache.catalina.connector.ResponseFacade 实现类(由tomcat提供的)
设置Http响应消息:
响应行:
void setStatus(int sc) 200 302 304 404 500
响应头
void setHeader(String name, String value)
响应体【重点】
1. 字符输出流
PrintWriter getWriter()
2. 字节输出流
ServletOutputStream getOutputStream()
注意:在同一个servlet中,二种类型的输出流不能同时存在,互斥
响应重定向:
用户访问AServlet后,服务器告诉浏览器重定向到BServlet
* 方式一
response.setStatus(302);
response.setHeader("Location","重定向网络地址");
* 方式二
response.sendRedirect("重定向网络地址");
特点
1. 地址栏会发生改变
2. 重定向是二次请求
3. 重定向是客户端(浏览器)行为,可以跳转到服务器外部资源...
4. 不能使用request域共享数据
请求转发与重定向的区别
1.对象不同
转发(request对象的方法)
重定向(response对象的方法)
2.请求次数
3.使用场景(重点掌握)
如果需要传递数据(request域),使用转发
如果不需要传递数据(request域),使用重定向
响应中文:
默认输出编码ISO-8859-1,浏览器默认解码格式位GBK
1. 指定服务器响应编码方式
response.setCharacterEncoding("GBK"); HttpServletRequest类型
2. 统一浏览器和服务器编码
response.setContentType("text/html;charset=utf-8");
ServletContext:
概述:
web容器(tomcat)在启动时,它会为每个web项目承建一个对应的ServletContext对象
应用上下文。对上获取tomcat的一些信息,对下获取servlet的一些信息。
主要作用:
1. 是一个域对象(共享数据)
2. 获取资源在服务器的真实地址(物理路径)
3. 获取全局的配置参数
4. 获取文件MIME类型
获取ServletContext对象:
1. 通过request对象获得
ServletContext sc = request.getServletContext();
2. 继承HttpServlet后,可以直接调用
ServletContext sc = this.getServletContext();
域对象(共享数据):
在当前项目范围内,共享数据(多个servlet都可以获取)
常用方法:
1. 存储数据
void setAttribute(String name,Object value)
2. 获取数据
Object getAttribute(String name)
3. 删除数据
void removeAttribute(String name)
生命周期:
何时创建?项目加载时,创建
何时销毁?项目卸载时,销毁
作用范围?与项目共存亡(多个servlet都可以操作它)
获取资源在服务器的真实地址:
因为编译路径和存放路径不一样,所以不能直接写物理路径。
方法:
String getRealPath(String path);
示例:
request.getServletContext().getRealPath("/img/car.jpg"); /表示项目所在路径。
获取全局的配置参数:
作用:
读取web.xml配置文件中标签信息,实现参数和代码的解耦(多个servlet都可以获取)
示例:
String value = request.getServletContext().getInitParameter("encode");
<context-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</context-param>
获取文件MIME类型:
定义:
在互联网通信过程中定义的一种文件数据类型格式。针对不同的返回类型,设置不同的Content-Type
格式:
大类型/小类型 例如: text/html image/jpeg
方法:
String mimeType = request.getServletContext().getMimeType(filename);根据文件拓展名来获取。
应用场景:
统计网站的访问次数
1.Servlet初始化init方法往ServletContext设置count=0
getServletContext().setAttribute("count", 0);
2.每次请求count+=1
ServletContext servletContext = request.getServletContext();
Integer count = (Integer) servletContext.getAttribute("count");
count++;
servletContext.setAttribute("count", count);
会话技术:
概述:
客户端会话技术:cookie
服务器端会话技术:session
Cookie:
快速入门
设置
Cookie cookie = new Cookie(String name,String value); *value只能存字符串
response.addCookie(cookie);
获取
Cookie[] cookies = request.getCookies();
工作原理
基于HTTP协议:请求头cookie 和 响应头 set-cookie
Cookie细节
服务器发送多个Cookie?可以
Cookie在浏览器保存时间?
默认是浏览器关闭(会话结束),cookie销毁(内存)
cookie.setMaxAge(int second); -- 单位是秒
正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁
负数:默认浏览器关闭,cookie销毁
零:立即销毁(自杀)
Cookie是否可以存储中文?
tomcat8之前的版本,不支持中文
tomcat8以后的版本,支持中文... Rfc6265Cookie规范,不允许使用 分号、空格等一些特殊符号...
通用方式:
URLEncoder 编码
URLDecoder 解码
特点
1. cookie存储数据都在客户端(浏览器)
2. cookie的存储数据只能是字符串
3. cookie单个大小不能超过4KB
4. cookie存储的数据不太安全
Session:
概念:
在一次会话的多次请求之间共享数据,将数据保存到服务器端
快速入门
HttpSession也是一个域对象HttpSession session = request.getSession();
1. 存储数据
void setAttribute(String name,Object value)
2. 获取数据
Object getAttribute(String name)
3. 删除数据
void removeAttribute(String name)
工作原理
Session基于Cookie技术实现,键为JESSIONID=1011;
生命周期
何时创建
用户第一次调用request.getSession()方法时,创建
何时销毁
服务器非正常关闭(正常关闭会序列化和反序列化,存在内存中)
非活跃状态30分钟后
tomcat进行配置 /tocmat安装目录/conf/web.xml
session.invalidate(); 自杀
作用范围
一次会话中,多次请求之间
注意:每一个浏览器跟服务器都是独立的会话...
三大域对象总结:
request、session、ServletContext
总结:
能用小的不用大的:request<session<servletContext
常用的场景:
request:一次查询的结果(servlet转发jsp)
session:存放当前会话的私有数据
用户登录状态
验证码
购物车
servletContext:若需要所有的servlet都能访问到,才使用这个域对象.
如何返回静态文件html:
1.RequestDispatcher view = request.getRequestDispatcher("/addUser.html");
view.forward(request, response);
2.href路径直接填addUser.html
Filter:
概述:
当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的操作。
应用:
登录验证、统一编码处理、敏感字符过滤
快速入门:
编写filter对目标资源servlet进行拦截
实现filter接口
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("QuickFilter拦截了请求...");
filterChain.doFilter(servletRequest, servletResponse); # 如果不执行这个,返回为空,状态码为200。
System.out.println("QuickFilter拦截了响应...");
}
配置:
<filter>
<filter-name>QuickFilter</filter-name>
<filter-class>com.lagou.a_quick.QuickFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>QuickFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
工作原理:
请求对应的servlet时,先执行doFilter。
返回时,再执行doFilter
生命周期:
* 创建
服务器启动项目加载,创建filter对象,执行init方法(只执行一次)
* 运行(过滤拦截)
用户访问被拦截目标资源时,执行doFilter方法
* 销毁
服务器关闭项目卸载时,销毁filter对象,执行destroy方法(只执行一次)
补充:
过滤器一定是优先于servlet创建的
拦截路径:
* 精准匹配
用户访问指定目标资源(/targetServlet)时,过滤器进行拦截
* 目录匹配
用户访问指定目录下(/user/*)所有资源时,过滤器进行拦截
* 后缀匹配
用户访问指定后缀名(*.html)的资源时,过滤器进行拦截
* 匹配所有
用户访问该网站所有资源(/*)时,过滤器进行拦截
过滤器链:
过滤器链执行顺序 (先进后出)
1.用户发送请求
2.FilterA拦截,放行
3.FilterB拦截,放行
4.执行目标资源 show.jsp
5.FilterB增强响应
6.FilterA增强响应
7.封装响应消息格式,返回到浏览器
过滤器链中执行的先后问题
配置文件
谁先声明,谁先执行
<filter-mapping>
应用:
1.tomcat8.5版本中已经将get请求的中文乱码解决了,但是post请求还存在中文乱码。浏览器发出的任何请求,通过过滤器统一处理中文乱码
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getMethod().equalsIgnoreCase("post")) {
request.setCharacterEncoding("UTF-8");
}
response.setContentType("text/html;charset="+encode);
Listener:
概念:
在我们的java程序中,有时也需要监视某些事情,一旦被监听的对象发生相应的变化,我们应该采取相应的操作。
监听web三大域对象:HttpServletRequest、HttpSession、ServletContext 通过监听器监听三大域对象它们的创建和销毁
使用这个监听器可以在项目启动和销毁的时候做一些事情,例如,在项目启动的时候加载配置文件。
场景:
历史访问次数(监听HttpServletRequest创建次数)、统计在线人数(统计session的创建次数)、系统启动时初始化配置信息
ServletContextListenner常用方法:
void contextInitialized(ServletContextEvent sce) 监听servletcontext创建
void contextDestroyed(ServletContextEvent sce) 监听servletcontext销毁
使用步骤:
1.创建一个类实现ServletContextListenner接口
2.实现ServletContextListenner的contextInitialized和contextDestroyed方法。
3.配置:
<listener>
<listener-class>com.itheima.listenner.MyServletContextListenner1</listenerclass>
</listener>
其他Listener:
HttpSessionListener:监听Httpsession域的创建于销毁的监听器
ServletRequestListener:监听ServletRequest域的创建于销毁的监听器
MVC模式:
JSP发展史:
1.早期只有servlet,只能使用response输出html标签,非常麻烦。
2.后来有了JSP,简化了servlet开发;一个文件,里面可以写html和java代码。
如果过度使用JSP,在JSP页面中写了大量的java代码和html标签,造成难于维护,难于分工协作的场景。
3.再后来为了弥补过度使用jsp的问题,使用servlet+jsp这套前后端分离的模式,利于分工协作。
MVC介绍:
MVC设计模式: Model-View-Controller简写。
MVC是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的设计方法。
简单来说:前辈们总结的一套设计经验,适合在各种软件开发领域,目的:高内聚,低耦合
* M:model(模型) JavaBean(1.处理业务逻辑、2.封装实体)
* V:view(视图) Jsp/html(展示数据)
* C:controller(控制器)Servlet(1.接收请求、2.调用模型、3.转发视图)
三层架构(MVC升级版):
概念
通常意义上的三层架构就是将整个业务应用划分为:表示(现)层、业务逻辑层、数据访问层。
区分层次的目的 为了高内聚低耦合的思想
表示(现)层:又称为web层,与浏览器进行数据交互(控制器和视图),控制器调用service层,跳转视图。
业务逻辑层:又称为service层,处理业务数据(if判断,for循环),将几个dao的方法组合在一起,实现某个具体的功能。
数据访问(持久)层:又称为dao层,与数据库进行交互(每一条(行)记录与javaBean实体对应),比如insert、delete
包目录结构:
* com.lagou 基本包(公司域名倒写)
* com.lagou.dao 持久层database access object。
* com.lagou.service 业务层
* com.lagou.servlet 控制层
* com.lagou.web 表示层
* com.lagou.domain 实体(JavaBean),各个层之间传递的一些实体对象。
* com.lagou.util 工具