美文网首页工作生活
Head First Servlet & JSP读书笔记

Head First Servlet & JSP读书笔记

作者: 殇不患_531c | 来源:发表于2019-06-29 20:03 被阅读0次

    Head First Servlet & JSP读书笔记

    本书内容:Servlet和JSP

    Servlet和JSP的关系分析:Servlet接受来自用户浏览器发送的请求,并最终返回响应;JSP根据Servlet的请求(request)内容创造动态网页作为相应。JSP优化了Servlet中out.println输出html的繁琐,利用请求转发将请求交给JSP,作出响应。
    MVC思想:M(model):可复用的处理业务的类文件;V(version):JSP;C(controller):servlet

    第一章:为什么使用Servlet和JSP

    1.GET和POST请求的区别:安全性、数据量、幂等性(一般来说GET是幂等的,POST不是幂等的,即你可以一遍一遍反复做同一件事,而不会产生意想不到的结果,例子:网络卡的时候多次付款操作应视为只有一次。这是一般的规范,由程序员自己注意并实现),而且一般来说,GET不对服务器的内容进行修改
    2.MIME类型:Content-Type(内容类型)响应首部的值称为MIME类型,一般使用:

    response.setContentType("text/html");
    response.setContentType("application/jar");
    

    除此之外还有文件类型
    3.Servlet的部署(初步)
    方法一:使用备注,即在创建Servlet的时候将support asyxxxx打勾,使用该servlet的时候使用对应url
    方法二:在web.xml中部署
    方法一的优先级高于二(?)
    4.使用JSP的必要性
    在Servlet中利用输出流输出html十分繁琐,例子:

    out.println("<a href=\""+response.encodeURL("/BeerTest.do")+"\">click me</a>");
    

    所以使用JSP,Servlet接收浏览器请求(request)和业务层的信息(?),将请求转发给JSP,产生动态页面
    注意:请求转发操作前不能响应输出,否则会报illegal的错,即不能out.flush(),输出由JSP产生返回

    第二三四五章

    1.使用web.xml的好处
    对web应用进行修改而不必修改源文件,其次Listener等也只能在web.xml中部署(?)
    2.请求转发:在服务器端做工作,用户发送一次请求

    RequestDispatcher view = request.getRequestDispachter("result.jsp");
    

    3.重定向:在客户端做工作,用户发送两次请求

    response.sendRedirect("http://hfajkfhkajl.com");
    

    4.ServletConfig和ServletContext,及作用域
    每个Servlet只有一个ServletConfig,里面可设置servlet作用域的属性(setAttribute)
    每个web应用只有一个ServletContext,web作用域
    注意:
    5.Servlet和JSP的数据传输一般通过在request上添加属性
    Servlet和java模型(pojo)是Servlet获得java类的实例对象
    6.初始化参数
    1)servlet的初始化参数:
    对于可能修改的参数可设置为servlet的初始化参数,在web.xml中修改
    部署:

    <servlet>
    <init-param>
    <param-name>name</param-name>
    <param-value>xiaoxue</param-value>
    </init-param>
    </servlet>
    

    读取(返回参数):

    getServletConfig().getInitParameter("name");
    

    2)Web应用的初始化参数
    对于web应用公用的参数,为避免固定servlet初始化顺序,在context中设置初始化参数
    部署:(在web-app内,servlet外)

    <context-param>
    <param-name>name</param-name>
    <param-value>xiaoxue</param-value>
    </context-param>
    

    读取:

    getServletContext().getInitParameter("name");
    

    7、Listener
    上述可实现对初始化字符串参数的引入,那对类对象呢,例如数据库连接?
    为避免固化Servlet的初始化顺序,使用Listener类(监听者)
    ServletContextListener例子

    /*Listener项目运行思路:
     * 首先Listener获得serveltcontext对象,通过web.xml中的inti参数构造对象(或直接构造对象,如数据库连接)
     * 最后在context的attribute里面添加
     * 然后servlet获得context中的属性,即测试完毕
     */
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import wyn.Dog;
    public class MyServletContextListener implements ServletContextListener {
        public void contextDestroyed(ServletContextEvent arg0) {
    
        }
        public void contextInitialized(ServletContextEvent arg0) {
            ServletContext sc = arg0.getServletContext();
            String dogBreed = sc.getInitParameter("breed");
            Dog d = new Dog(dogBreed);
            sc.setAttribute("dog", d);
        }
    
    }
    

    对应servlet的注意点:

    `Dog d = (Dog)getServletContext().getAttribute("dog");
    

    部署:

      <listener>
        <listener-class>wyn.MyServletContextListener</listener-class>
      </listener>
    

    完整的故事:
    容器读取部署描述文件(web.xml)
    创建servletcontext对象
    将读取的初始化参数交给servletcontext
    创建ServletContextListener对象
    容器调用contextInitialized()方法,该方法接收ServletContextEvent参数,实际上有ServletContext的一个引用
    Listener请求一个ServletContext的一个引用,并获得初始化参数
    利用初始化参数构造一个Dog对象
    将Dog对象设置为ServletContext中的一个属性
    Servlet读取对象,完成(注意类型转换)
    8、Listener类型了解(待)
    9、属性与参数的区别:属性的值是Object类型,参数是String类型
    10、线程安全问题(重点)
    1)上下文属性不是线程安全的,每个Servlet都可以修改ServletContext的内容,如果考虑线程安全一定要使用ServletContext的情况的话,使用:

    synchronized(getServletContext()){
    //对上下文的操作
    }
    

    但同步就意味着妨碍并发性,开发必须尽量让同步时间最短
    2)会话属性(session)也不是线程安全的,一个用户也可能打开两个不同的浏览器,而容器还是以为用户使用相同的会话,用户的多个同时的请求可能会影响安全。
    关键是让用户在同一个会话内只能同时发送一个请求,或者将请求同步执行
    可以对HttpSession同步:

    synchronized(session){
    //对session的操作
    }
    

    3)只有请求属性和局部变量是线程安全的
    一般来说,不使用对实例变量的同步(sychronized),这一方面影响效率并一方面设计与考虑也很麻烦(如serlvet计数器的例子,不能使用实例池的解决方案,尽管可能实现singleThreadModel也可能事与愿违),

    所以一个好的servlet不会看到任何实例变量

    另一方面也要加强的作用域的利用

    第六章、会话状态(request)
    1、request.getSession()(用的多)
    使用一个会话,在响应中发送一个cookie
    1)如果没有会话则创建会话,因此需要对会话进行检验:

    HttpSession session = request.getSession();
    if(session.isNew()){//如果客户使用该session做过响应则返回false
        pass
    }
    

    2)只想要一个已经有的会话使用request.getSession(false)
    如果没有匹配的会话则返回null,(session==null)检验
    2、禁用cookie的话常用URL重写(不是很理解)
    必须显式进行URL编码,如:response.encodeURL("/BeerTest.do")
    3、会话设置
    servlet内:略
    DD:<session-config><session-time>15</session-time></session-config>
    注意:程序中以秒为单位,部署文件中以分钟为单位
    4、直接使用cookie(如使用表单提供的用户名使用cookie存起来,而非仅仅jsession编号)

    //p252
    

    5、HttpSessionBindingListener
    无需在DD中部署,仅用来告诉类本身什么时候加入一个会话

    public class Dog implements HttpSessionBindingListener{
    pass
    }
    

    6、会话迁移

    只有HttpSession对象会从一个VM移动到另一个VM

    可以使用HttpSessionActivationListener来监听激活和钝化
    会话计数器:p261

    至多后天写完全书读后感,jsp部分略看,大后天开始JavaScript高级设计及锋利的jquery
    第一次写文章,请多多指教

    相关文章

      网友评论

        本文标题:Head First Servlet & JSP读书笔记

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