Head First Servlet & JSP读书笔记

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
第一次写文章,请多多指教

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容