美文网首页servlet原理
Servlet细节&Cookie&Session

Servlet细节&Cookie&Session

作者: NextGame | 来源:发表于2016-06-08 00:51 被阅读52次

    Servlet细节&Cookie&Session


    Servlet的细节问题


    • 一个Servlet可以有多个映射<url-pattern>
    <servlet>
      <servlet-name>MappingServlet</servlet-name>
      <servlet-class>com.ghyz.mapping.MappingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>MappingServlet</servlet-name>
      <url-pattern>/mapping</url-pattern>
      <url-pattern>/mapping2</url-pattern>
      <url-pattern>/mapping3</url-pattern>
    </servlet-mapping>
    
    • Servlet<url-pattern>可以使用通配符*进行配置
      • /*表示可以使用任意字符访问当前的Servlet
      • /system/*可以使用以/system为前缀,后面是任意字符即可访问当前的Servlet
      • *.xxx任何字符,加上指定的后缀名即可访问当前的Servlet
    • Servlet<servlet-name>不能为default如果为default那么当前项目中的静态资源将无法被访问
      • 因为在Tomcat中有一个默认的Servlet配置其<servlet-name>就是default专门用来访问项目中的静态资源。
    • Servlet中初始化操作非常复杂的时候,那么这种操作就非常好使,给第一个访问用户的体验就很差
      • 问题的根本:初始化操作放在了第一次访问的时候执行
      • 解决方案:应该将耗时的初始化操作放在第一次访问执行之前
    <servlet>
      <servlet-name>MappingServlet</servlet-name>
      <servlet-class>com.ghyz.mapping.MappingServlet</servlet-class>
      <!-- 设置Servlet在Tomcat中启动的时候执行初始化,数字越小越先执行 -->
      <load-on-startup>0</load-on-startup>
    </servlet>
    

    Servlet3.0的新特性--注解配置


    Servlet3.0开始Servlet就支持使用注解进行配置,可以使用注解来替代部分web.xml文件

    • 使用注解的准备工作(web.xml的配置)
      • metadata-complete="true":指定服务器忽略Servlet上面的注解
      • metadata-complete="false":指定服务器编译Servlet上的注解(缺省值)
    • 选择注解还是web.xml配置Servlet?
      • web.xml维护难度大
      • 注解:将硬编码拉回到程序中,不好维护
      • 如果当前配置是针对某一个Servlet的话,可以使用注解
      • 如果是通用的配置,应该使用web.xml例如给多个Servlet共享数据

    使用注解配置Servlet示例代码

    @WebServlet(value="/anno", 
    loadOnStartup=0, 
    initParams={@WebInitParam(name="encoding", value="UTF-8")})
    public class AnnoServlet extends HttpServlet {
      // TODO...
    }
    

    Servlet线程安全问题


    • Servlet在整个应用中只有一个实例

    问题的根本原因:因为有多个线程并发访问(修改)当前的Servlet中的资源,又因为Servlet是单例的,所以所有的成员,都会去访问同一个对象

    • 解决方法
      • 可以让当前的Servlet去实现一个接口SingleThreadModel,表示当前的Servlet只能被同一个线程访问该方法不推荐,已经被淘汰了
      • Servlet中使用局部变量代替成员变量

    Http协议无状态带来的问题


    HTTP是无状态协议,也就是没有记忆力,每个请求之间无法共享数据。这样就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。

    web中的回话:在浏览器打开的时候,在这之钱应该要进行多次一问一答的交互,关闭浏览器的时候结束

    • 解决方案:解决HTTP无协议状态的问题
      • 使用参数传递机制
      • cookie
      • session

    在请求路径后面跟上响应参数如/param/list?username=ghyz这种方式可以解决数据共享的问题,但是,参数显示在了地址栏中,不安全(不推荐)

    Cookie


    Cookie客户端技术,将共享数据保存在客户端中(浏览器)

    • 原理

    浏览器记住键值对,是向响应头中添加一下头即可set-Cookie:name=tom
    浏览器记住之后,向服务器发送键值对,是在请求头中添加下面的信息Cookie:name=tom

    • Cookie的细节
    // 1.创建Cookie对象,并设置共享数据
    Cookie c = new Cookie(String name, String value);
    // 2.将Cookie响应给浏览器
    response.addCookie(c);
    // 3.获取Cookie中的共享数据
    Cookie[] cookies = request.getCookies();
    for (Cookie c : cookies) {
      if ("username".equals(c.getName())) {
        String value = c.getValue();
      }
    }
    // 4.修改Cookie中的共享数据
    // 方式一:获取到要修改的Cookie对象,调用setValue(String newValue);
    // 方式二:重新创建一个名字和要修改的Cookie一样的Cookie对象即可,修改之后需要将Cookie重新发送给浏览器
    // 5.Cookie的生命周期(默认是在关闭浏览器就销毁)
    void setMaxAge(int expiry)
    // expiry > 0:设置生存的时间为expiry妙
    // expiry = 0:立即删除当前的Cookie
    // expiry < 0:缺省值,在关闭浏览器就销毁
    // 6.删除Cookie
      c.setMaxAge(0);
    // 7.Cookie中的name和value不支持中文
    // 解决方案
    // 将文中的字符先重新编码(编码成非中文的)
    // 编码
    URLEncoder.encode("大黄", "UTF-8");
    // 解码
    URLDecoder.decode("对应的编码","UTF-8");
    
    // 8.cookie的路径和cookie的域范围
    // 在Servlet中创建的Cookie对象,会默认的将Servlet的相对路径设置给Cookie
    // 如:/cookie/login-->相对路径/cookie/
    // 此时访问/session/list的时候,浏览器不会将Cookie中的数据发送给服务器
    // 解决方案
    // 通常可以将Cookie的路径设置为/,表示访问当前项目中的所有资源,都会将共享数据发送给服务器
    c.setPath("/");
    
    // 域范围
    // 如果使用的二级域名。可以使用下面的方式进行共享
    // void setDomain(String path)
    c.setPath("/");
    c.setDomain("baidu.com");
    
    // Cookie的缺陷
    // 1.取值的时候,操作复杂
    // 2.不支持中文,中文参数很多的时候,操作很麻烦
    // 3.cookie一次只能保存一个字符串,如果一次需要保存多个共享数据,就需要创建多个Cookie对象
    // 4.将共享数据保存在浏览器中不安全
    // 5.Cookie在浏览器中有数量大小的限制,在低版本的IE中
    // 每个应用在浏览其中只能保存20个Cookie信息,其他的可以保存50个
    

    Session


    • 什么是session

    服务器端的会话技术,将共享数据保存到服务端,同时在可断保存一个id,以后就根据id查找到服务器端的共享数据

    session实际就是一个会话cookie

    • 使用方法
    // 1.如何获得Session
    HttpSession session = request.getSession();
    // 2.如何操作
    session.setAttribute(key, value);
    session.getAttribute(key);
    session.removeAttribute(key);
    session.getAttributeNames();
    
    • 原理

    浏览器第一次访问服务器,服务器会在内存中开辟一个空间(session)

    session对应的id发送给浏览器

    那么下次浏览器再去访问服务器,会把sessionId交给服务器,服务器通过sessionId找到刚才开辟的空间

    相关文章

      网友评论

        本文标题:Servlet细节&Cookie&Session

        本文链接:https://www.haomeiwen.com/subject/nccjdttx.html