Servlet小结

Servlet

Servlet配置

<!-- 配置一个servlet -->
<!-- servlet的配置 -->
<servlet>
    <!-- servlet的内部名称,自定义。尽量有意义 -->
    <servlet-name>FirstServlet</servlet-name>
    <!-- servlet的类全名: 包名+简单类名 -->
    <servlet-class>gz.itcast.a_servlet.FirstServlet</servlet-class>
</servlet>

<!-- servlet的映射配置 -->
<servlet-mapping>
    <!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->
    <servlet-name>FirstServlet</servlet-name>
    <!-- servlet的映射路径(访问servlet的名称) -->
    <url-pattern>/first</url-pattern>
</servlet-mapping>

Servlet的映射路径

1)url-pattern要么以 / 开头,要么以*开头。 例如, itcast是非法路径。

2)不能同时使用两种模糊匹配,例如 /itcast/*.do是非法路径

3)当有输入的URL有多个servlet同时被匹配的情况下:

3.1 精确匹配优先。(长的最像优先被匹配)
3.2 以后缀名结尾的模糊url-pattern优先级最低!!!


                  url-pattern                   浏览器输入
精确匹配             /first                 http://localhost:8080/day10/first
                    /itcast/demo1          http://localhost:8080/day10/itcast/demo1

模糊匹配             /*                   http://localhost:8080/day10/任意路径
                    /itcast/*               http://localhost:8080/day10/itcast/任意路径
                    *.后缀名              http://localhost:8080/day10/任意路径.do
                    *.do
                    *.action
                    *.html(伪静态)

生命周期方法

  1. 构造方法
  2. init方法
  3. service方法
  4. destroy方法

生命周期过程

  1. 浏览器客户端向服务器端发送请求

    http://localhost:8080/ReqeustDemo/HelloServlet
    
  2. Tomcat服务器解析地址,获取资源名称/RequestDemo,进入该Web目录下,查找web.xml,是否有/HelloServlet的url-pattern,如果有该url-pattern则查找Servlet-name然后再Servlet-class

  3. 通过反射创建该Servlet对象,Servlet的构造方法被调用

  4. 创建ServletConfig对象,通过反射调用init方法

  5. 创建Response和Request对象,通过反射调用Service方法

  6. 服务器关闭或者项目重新部署,调用destroy方法

Servlet默认为用户第一次访问时调用,该对象为单例多线程对象。因此会有线程安全问题

解决办法:
1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)
2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

通过设置load-on-startup可以在tomcat加载该应用时就创建和初始化该Servlet对象

 <!-- 让servlet对象自动加载 -->
<load-on-startup>1</load-on-startup>  注意: 整数值越大,创建优先级越低!!

init的无参和有参数方法
无参方法是给程序员写代码用的,有参数方法默认会调用无参方法

public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

ServletConfig对象

ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

创建时机: 在创建完servlet对象之后,在调用init方法之前创建。

得到对象: 直接从有参数的init方法中得到!!!

ServletConfig的API:

java.lang.String getInitParameter(java.lang.String name)  根据参数名获取参数值
java.util.Enumeration getInitParameterNames()    获取所有参数
ServletContext getServletContext()     得到servlet上下文对象
java.lang.String getServletName()       得到servlet的名称

ServletContext对象

ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一个ServletContext对象。

创建时机:加载web应用时创建ServletContext对象。
得到对象: 从ServletConfig对象的getServletContext方法得到

  1. 獲取Web應用的初始化參數

    java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数
    java.util.Enumeration getInitParameterNames()  
    
  2. 獲取域對象

    void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
    java.lang.Object getAttribute(java.lang.String name)  
    void removeAttribute(java.lang.String name)  
    
  3. 轉發

    RequestDispatcher getRequestDispatcher(java.lang.String path)   --转发(类似于重定向),等價于request.getRequestDispatcher(java.lang.String path)
    
  4. 獲取Web資源

    java.lang.String getRealPath(java.lang.String path)     --得到web应用的资源文件
    java.io.InputStream getResourceAsStream(java.lang.String path)  
    
  5. 得到Web應用的路徑

    java.lang.String getContextPath()   --得到当前web应用的路径,類似于request的getContextPath()
    

Web應用中/和.的含義:
目标资源是给谁使用的

  1. 给服务器使用的: / 表示在当前web应用的根目錄(webRoot下)
  2. 给浏览器使用的: / 表示在webapps的根目錄下
1. 转发 目標資源是給瀏覽器使用,故/表示的爲webapps目錄
2. 请求重定向 目標資源給服務器使用,故/表示爲當前web應用的根目錄下
3. html页面的超连接href /表示webapps根目錄
4. html页面中的form提交地址 /表示webapps根目錄

ServletContext域对象:作用范围在整个web应用中有效!!!

所有域对象:

HttpServletRequet 域对象
ServletContext域对象
HttpSession 域对象
PageContext域对象

请求转发与重定向

RequestDispatcher getRequestDispatcher(java.lang.String path)

1)转发

a)地址栏不会改变
b)转发只能转发到当前web应用内的资源
c)可以在转发过程中,可以把数据保存到request域对象中

2)重定向

a)地址栏会改变,变成重定向到地址。
b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。
c)不能再重定向的过程,把数据保存到request中。

结论: 如果要使用request域对象进行数据共享,只能用转发技术!!!

Cookie和Session

Cookie原理

在服務器產生Cookie對象,通過設置響應頭(set-cookie)傳遞到瀏覽器;瀏覽器下次訪問的時候會將該cookie添加到請求頭(cookie)傳遞到服務器,服務器可以通過request或得cookie。Cookie是存儲在瀏覽器端的。

  1. 創建Cookie對象

    Cookie cookie = new Cookie("name","value);

  2. 服務器發送Cookie信息到瀏覽器

    response.setHeader("set-cookie","name=value");
    response.addCookie(cookie);

  3. 瀏覽器得到服務器發送的cookie
  4. 下次訪問會帶著cookie訪問服務器
  5. 服務器接收瀏覽器帶來的cookie

    request.getCookies();

Cookie核心API

    1)构造Cookie对象
        Cookie(java.lang.String name, java.lang.String value)
    2)设置cookie
        void setPath(java.lang.String uri)   :设置cookie的有效访问路径
        void setMaxAge(int expiry) : 设置cookie的有效时间
        void setValue(java.lang.String newValue) :设置cookie的值
    3)发送cookie到浏览器端保存
        void response.addCookie(Cookie cookie)  : 发送cookie
    4)服务器接收cookie
        Cookie[] request.getCookies()  : 接收cookie

Cookie細節

void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。

void setMaxAge(int expiry) : 设置cookie的有效时间。

正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
零:表示删除同名的cookie数据

Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

Session

Session的会话数据保存在服务器端。(内存中)

Session原理

前提: 在哪个session域对象保存数据,就必须从哪个域对象取出!!!!

    浏览器1:(给s1分配一个唯一的标记:s001,把s001发送给浏览器)
            1)创建session对象,保存会话数据
                    HttpSession session = request.getSession();   --保存会话数据 s1
    浏览器1    的新窗口(带着s001的标记到服务器查询,s001->s1,返回s1) 
            1)得到session对象的会话数据
                    HttpSession session = request.getSession();   --可以取出  s1

    新的浏览器1:(没有带s001,不能返回s1)
            1)得到session对象的会话数据
                    HttpSession session = request.getSession();   --不可以取出  s2

    浏览器2:(没有带s001,不能返回s1)
            1)得到session对象的会话数据
                    HttpSession session = request.getSession();  --不可以取出  s3

代碼解讀

1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID

    new HttpSession();

2)把JSESSIONID作为Cookie的值发送给浏览器保存

    Cookie cookie = new Cookie("JSESSIONID", sessionID);
    response.addCookie(cookie);

3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。

    if(找到){
        return map.get(sessionID);
    }
    Map<String,HttpSession>]


    <"s001", s1>
    <"s001,"s2>

5)如果找到对应编号的session对象,直接返回该对象

6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

结论:通过JSESSION的cookie值在服务器找session对象!!!!!

核心API

  1. java.lang.String getId() : 得到session编号

  2. 两个getSession方法:

    getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创 建新的session对象。
    getSession(false): 得到session对象。没有匹配的session编号,返回null

  3. void setMaxInactiveInterval(int interval) : 设置session的有效时间
    session对象销毁时间:

    1 默认情况30分服务器自动回收

    2 修改session回收时间

    3 全局修改session有效时间

    <!-修改session全局有效时间:分钟 -->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
    

    4.手动销毁session对象

    void invalidate():销毁session对象
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值