tomcat与servlet知识点

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://tomcat.apache.org/download-80.cgi
解压,执行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全限定名,反射获取对象,执行方法。

生命周期:

// 1. servlet对象创建时,调用此方法(默认第一次请求来时创建servlet对象,单例模式)
public void init(ServletConfig servletConfig);
// 2. 用户访问servlet时,调用此方法
public void service(ServletRequest servletRequest, ServletResponse servletResponse);
// 3. servlet对象销毁时,调用此方法(当服务器关闭或者servlet被移除的时候)
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://localhost:8080/servlet_demo/requestDemo1,全路径。
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    
* 方式一
    // 1.设置状态码
        response.setStatus(302);
    // 2.设置响应头 Location
        response.setHeader("Location","重定向网络地址");
* 方式二
    // 1.response这哥们封装专门处理重定向的方法
        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(requestresponse);

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拦截路径-->
    <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")) {        // 判断用户是否为post请求,才设置编码
    request.setCharacterEncoding("UTF-8");
}
response.setContentType("text/html;charset="+encode);    // 真实场景中,过滤器不会统一响应mime类型

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实体对应),比如insertdelete
包目录结构:
    * com.lagou 基本包(公司域名倒写)
    * com.lagou.dao 持久层database access object
    * com.lagou.service 业务层
    * com.lagou.servlet 控制层
    * com.lagou.web 表示层
    * com.lagou.domain 实体(JavaBean),各个层之间传递的一些实体对象。
    * com.lagou.util 工具
posted @ 2022-03-28 10:38  心平万物顺  阅读(65)  评论(0编辑  收藏  举报