Servlet

一、Http方法:

  • POST,GET,HEAD,TRACE,PUT,DELETE,OPTIONS,CONNECT(servlet API没有处理doConnect()的机制,所以HttpServlet没有doConnect())

MIME类型:响应首部的值。MIME类型告诉浏览器要接收的数据是什么类型。MIME类型值与HTTP请求首部的Accept所列的值有关。

Web服务器只提供静态页面,动态内容由其他应用提供。


二、容器的作用

  • 通信支持。容器能提供方法让servlet与web服务器对话,无需自己建立ServletSocket、监听端口、创建流等。容器自己知道自己与web服务器之间的协议,所以只需要在servlet中实现业务逻辑。
  • 生命周期管理。容器控制着servlet的生死,它负责加载类、实例化和初始化servlet、调用servlet方法,并使servlet实例能够被垃圾回收。
  • 多线程支持。容器会自动为接收到的每个servlet请求创建一个新的Java线程。针对某个客户请求。如果servlet已经运行完相应的HTTP服务方法,这个线程就会结束。但仍需考虑同步问题。
  • 生命方式实现安全。
  • JSP支持。容器负责把JSP代码翻译成Java。

三、URL映射到servlet方法

  • 部署描述文件(DD)。

内部名映射到完全限定类名。
内部名映射到公共URl名。

  • 注解。

四、容器处理请求过程

1.用户点击一个链接(指向的是非静态页面),浏览器将请求数据发给容器。
2.容器创建两个对象:HttpServletResponse和HttpServletRequest
3.容器根据请求中的URL找到正确的servlet,为这个请求创建或分配一个线程,并把请求和响应对象传递给servlet。
4.容器调用servlet的service()方法,根据请求的不同,service()方法调用doGet()或doPost()方法。
5.doGet()生成动态页面,并把页面填入响应对象。
6.线程结束,容器把响应对象转换成HTTP响应,把它返回给客户,然后删除请求和响应对象。

有请求分派时:
5.为请求对象增加一个属性,供JSP使用。(request.setAttribute())
6.servlet把请求转发给JSP。
7.JSP从请求对象得到回答,为容器生成一个页面。
8.容器把页面返回。


五、servlet&JSP中的MVC(模型-视图-控制器)

把业务逻辑从servlet抽出来放在模型中。
  • 模型。可重用的普通Java类。只有模型与数据库通信。
  • 控制器(servlet)。从请求获得用户输入,告诉模型自行更新,并让视图得到更新的模型状态。
  • 视图(JSP)。从控制器得到模型的状态。获得用户输入并提交给控制器。

六、J2EE&web容器&EJB组件

  • 一个完全兼容的J2EE应用服务器必须包括一个web容器和一个EJB容器。
  • Tomcat只是一个web容器,不是完整的J2EE应用服务器。
  • 如今,EJB都作为完整的J2EE服务器的一部分,但独立的web容器仍存在。
  • 独立的web容器通常配置为与一个HTTP web服务器(如Apache)协作,但tomcat本身就可以作为一个基本的HTTP服务器,但功能方面没有Apache健壮。所以通常非EJB web应用会结合使用Apache和Tomcat。
    【注】
    Apache是设计服务于静态web页面的web服务器。
    Tomcat是一个Servlet/Jsp容器,它同时也作为一个web服务器使用。Tomcat = ( Web Server + Servlet container + JSP environment ),因为我们知道JSP也是转译为Servlet的,Tomcat接收请求之后,如果是JSP页面的话,Tomcat里面的JSP引擎可以将JSP转换为Servlet类。

七、应用服务器和web服务器的区别

https://www.cnblogs.com/111testing/p/7129215.html

  • 应用服务器就是提供应用的服务器,这里的应用有很多,比如java应用,ruby 应用,或者 c#应用。应用服务器也提供了http服务,比如tomcat。
  • web服务器就是提供了web功能的服务器,主要就是http服务,包括图片的下载等一系列和web相关的。优点是在处理静态信息上。例如一些静态的html,图片等其他静态的东西。

Tomcat&Apache

Tomcat服务器是一个免费的开放源代码的Web应用服务器。因为Tomcat技术先进、性能稳定且免费,所以深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。
到目前为止,Tomcat一直被认为是Servlet/JSP API的执行器,也就所谓的Servlet容器。然而,Tomcat并不仅仅如此,它还提供了JNDI和JMX API的实现机制。尽管如此,Tomcat仍然还不能算是应用服务器,因为它不提供大多数J2EE API的支持。
Tomcat是提供一个支持Servlet和JSP运行的容器。Servlet和JSP能根据实时需要,产生动态网页内容。而对于Web服务器来说, Apache仅仅支持静态网页,对于支持动态网页就会显得无能为力;Tomcat则既能为动态网页服务,同时也能为静态网页提供支持。尽管它没有通常的Web服务器快、功能也不如Web服务器丰富,但是Tomcat逐渐为支持静态内容不断扩充。大多数的Web服务器都是用底层语言编写如C,利用了相应平台的特征,因此用纯Java编写的Tomcat执行速度不可能与它们相提并论。
一般来说,大的站点都是将Tomcat与Apache的结合,Apache负责接受所有来自客户端的HTTP请求,然后将Servlets和JSP的请求转发给Tomcat来处理。Tomcat完成处理后,将响应传回给Apache,最后Apache将响应返回给客户端。

八、servlet周期与方法

与servlet有关的所有一切(除了JSP)都在javax.servlet和javax.servlet.http中。

不存在——>初始化
容器要加载类,调用servlet的无参数构造函数,并调用servlet的init()方法,从而初始化servlet。
servlet接口方法:init(可能覆盖),service(不覆盖),destroy
  • init总是在第一个service调用之前完成,在servlet的一生中只调用一次。
  • 容器运行多个线程来处理对一个servlet的多个请求。
  • 若应用分布在多个JVM上,则每个JVM都有一个servlet实例。

ServletConfig对象和ServletContext

ServleConfig:
  • 每个servlet都有一个ServletConfig对象
  • 用于向servlet传递部署时信息
  • 用于访问ServletContext
ServletContext
  • 每个Web有一个
  • 用于访问Web应用参数

容器实现HttpServletRequest和HttpServletResponse接口。


九、Get和POST的区别

  • POST有体。
  • 安全性。使用GET时,参数数据会显示在浏览器的输入栏中(URL后面用?分隔)
  • 书签。GET请求可以建立书签。POST则不能。
  • 幂等。GET是幂等的,不会对服务器做出任何改变;POST是非幂等的,是一个更新,可使用POST体的数据来修改服务器(更新数据库)。
【注】HTTP中的GET是幂等的,但是你可以在servlet中实现一个非幂等的doGet方法。

// 默认是GET请求


十、请求

从请求对象可以得到参数,客户的平台和浏览器信息,与请求相关的,与客户相关的会话,请求的HTTP方法,请求的输入流。

String client = request.getHeader("User-Agent");
Cookie[] cookies = cookie(request.getCookies();
HttpSession session = request.getSession();
String method = request.getMethod();
InputStream input = request.getInputStream();


十一、响应

返回类型(MIME)和输出

ServletResponse接口只提供了两个流:ServletOutputStream(字节)和PrintWriter(字符)。
PrintWriter实际上包装了ServletOutputStream。

PrintWriter writer = response.getWriter();
writer.println("字符");
ServletOutputStream out = response.getOutputStream();
out.write();


十二、重定向和请求分派

重定向是让浏览器完成工作。
请求分派是在服务端做工作。(客户并不关心是谁做出响应)

// 重定向
respons.sendRedirect("URL");
// 请求分派
RequestDispatcher view = request.getRequestDispatcher("result.jsp");
view.forward(request.response);

十三、servlet初始化参数

容器从DD读出servlet初始化参数,并把这些参数交给ServletConfig,然后把ServletConfig传递给servlet的init()方法。

servlet初始化参数只能读取一个,就是在容器初始化servlet的时候。

【注】若初始化参数的值经常变化,最好让servlet从一个文件或者数据库得到值,但这种方法意味着每次servlet代码运行时都会有更多的开销,而不是只在初始化的时候才有。
【过程】

1.容器为这个servlet读取部署描述文件,包括servlet初始化参数(
2.容器为这个servlet创建一个新的ServletConfig实例。

  1. 容器为每个servlet初始化参数创建一个String名/值对。(来自DD的初始化参数)
  2. 容器向ServletConfig提供名/值初始化参数的引用。
  3. 容器创建servlet类的一个新实例。
  4. 容器调用servletdeinit()方法,传入ServletConfig引用。

十四、请求属性(针对一个servlet)

请求对象设置属性(名/值对,值可以是任何对象,若是对象需要判断是否为空),得到请求的任何servlet和JSP都能使用这些属性。

request.setAttribute("styles",result);


十五、上下文初始化参数(针对整个web应用)(,不在元素内)

应用中所有的servlet和JSP都能访问上下文初始化参数,而不必为每个servlet都配置DD。
Web应用初始化过程:
  1. 容器读取DD,对应每个创建一个名/值对。
  2. 容器创建ServletContext的一个新实例。
  3. 容器为ServletContext提供上下文初始化参数各个名/值对的引用。
  4. 在一个Web应用中部署的各个servlet和JSP都能访问同一个ServletContext。
【注】
  • 如果应用是分布式的,那么每个JVM有一个ServletContext。
  • 上下文参数最常见的用途是存储数据库查找名。

十六.监听者(ServletContextListener)(8个)

1.上下文事件监听者
作用:监听ServletContext的初始化和撤销。在应用为客户提供服务之前运行一些代码。如读取上下文参数,创建一个对象并把这个对象设置为ServletContext属性,以便servlet获取。

上下文参数只能是String。若servlet想共享某个对象,就需要用监听者。

用法:

  1. 创建一个监听者类,实现ServletContextListener接口。把它放在WEB-INF/classes目录中,并在部署文件中放元素告诉容器。
  2. 属性类,有监听者类创建,并在监听者类中设置在ServletContext属性中。

十七、属性作用域:上下文、请求、会话

分别有ServletContext、ServletRequest、HttpSession接口处理。

方法:
Object getAttribute(String name)
void setAttribute(String name,Object value)
void removeAttribute(String name)
Enumeration getAttributeNames()

1.上下文(希望整个应用程序共享,如数据库连接,email地址)
  • 不是线程安全的。因为每个servlet都可以访问,所以多个servlet则有多个线程,请求是并发处理的,不论这些请求指向同一个servlet还是不同的servlet。
  • 同步问题。对servlet加锁(对其doGet()或doPost()方法)只能保证servlet一次只能运行一个线程,但不能保证其他servlet或JSP访问这个属性。对于上下文加锁才能保证同步。

(synchronized(getServletContext()){
getServletContext().setAttribute();
}

2.会话(与客户会话有关的资源和数据,如购物车)
  • 不是线程安全的(一个客户同时做出多个请求:当你打开一个新的浏览器窗口,并创建同一个请求,此时新建一个servlet)
  • 同步。

synchronized(session){
session.setAttribute();

}
【注】同步时要让同步块尽可能小。

3.请求(将模型信息从控制器传递给视图)
  • 线程安全的。
【注】

如果需要线程安全,就不要使用实例变量,因为servlet的所有线程都可以处理实例变量,(实现了SingleThreadModel或者同步服务方法可以,但是会导致性能很差),所以servlet的实例变量都是final。
servlet只有一个实例,但可以有多个线程,若希望多个线程都能访问某个值,可以将其声明为服务方法中的局部变量或者在合适的作用域中使用属性。


十八、RequestDispatcher

1. 只有两个方法:forward()和include()。一般使用forward()。
2. RequestDispatcher可以从请求和上下文获得。
3. 提交响应(os.flush())不能再转发请求。
4. include( )会把请求发送给另一个servlet来完成工作,然后再返回。forward()是直接将请求交给另一个servlet,自己不再处理。

你可能感兴趣的:(Servlet)