servlet

Servlet是Server与Applet的缩写,是服务端小程序的意思。是SUN公司提供的一门用于开发动态Web资源的技术。

servlet首先是一个协议,主要用于满足java的web后端处理的协议

servlet也是java自带的类库,是对servlet协议的实现

servlet也指使用上面servlet类库实现的servlet程序

servlet程序是没有主函数中,不能单独运行,所以必须运行在servlet容器中,常用的servlet容器有tomcat,jetty和jboss等等。servlet容器又叫做servlet引擎。

 Apache官方对各版本的解释:http://tomcat.apache.org/whichversion.html

https://www.cnblogs.com/whgk/p/6399262.html

 1、servlet的生命周期是什么?

          服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)

          该servlet对象去处理所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行

          最后服务器关闭时,才会销毁这个servlet对象,执行destroy()方法。

              

        2、为什么创建的servlet是继承自httpServlet,而不是直接实现Servlet接口?

        3、servlet的生命周期中,可以看出,执行的是service方法,为什么我们就只需要写doGet和doPost方法呢?

          查看源码,httpServlet的继承结构。

             httpServlet继承GenericServlet。懂的人立马就应该知道,GenericServlet(通用Servlet)的作用是什么?大概的就是将实现Servlet接口的方法,简化编写servlet的步骤。具体下面详解

                

             GenericServlet的继承结构,实现了Servlet接口和ServletConfig接口,

                    

             Servlet接口内容

                  

                从这里可以看到,Servlet生命周期的三个关键方法,init、service、destroy。还有另外两个方法,一个getServletConfig()方法来获取ServletConfig对象,ServletConfig对象可以获取到Servlet的一些信息,ServletName、ServletContext、InitParameter、InitParameterNames、通过查看ServletConfig这个接口就可以知道

             ServletConfig接口内容

                 

                其中ServletContext对象是servlet上下文对象,功能有很多,获得了ServletContext对象,就能获取大部分我们需要的信息,比如获取servlet的路径,等方法。

               到此,就知道了Servlet接口中的内容和作用,总结起来就是,三个生命周期运行的方法,获取ServletConfig,而通过ServletConfig又可以获取到ServletContext。而GenericServlet实现了Servlet接口后,也就说明我们可以直接继承GenericServlet,就可以使用上面我们所介绍Servlet接口中的那几个方法了,能拿到ServletConfig,也可以拿到ServletContext,不过那样太麻烦,不能直接获取ServletContext,所以GenericServlet除了实现Servlet接口外,还实现了ServletConfig接口,那样,就可以直接获取ServletContext了。

              GenericServlet类的内容详解

                     

                看上图,用红色框框起来的就是实现Servlet和ServletConfig接口所实现的方法,有9个,这很正常,但是我们可以发现,init方法有两个,一个是带有参数ServletConfig的,一个有无参的方法,为什么这样设计?这里需要知道其中做了什么事情,来看看这两个方法分别做了什么事?

                init(ServletConfig config)

                      

                init()

                      

                一个成员变量config

                      

                getServletConfig()

                      

                通过这几个方法一起来讲解,首先看init(ServletConfig config)方法,因为只有init(ServletConfig config)中带有ServletConfig对象,为了方便能够在其他地方也能直接使用ServletConfig对象,而不仅仅局限在init(ServletConfig config)方法中,所以创建一个私有的成员变量config,在init(ServletConfig config)方法中就将其赋值给config,然后通过getServletConfig()方法就能够获取ServletConfig对象了,这个可以理解,但是在init(ServletConfig config)中,158行,还调用了一个init()方法,并且这个init()方法是空的,什么读没有,这是为什么呢?这个原因是为了防止一件事情,当我们需要在init方法中做一点别的事情,我们想到的方法就是继承GenericServlet并且重写了init(ServletConfig config)方法,这样依赖,就破坏了原本在GenericServlet类中init(ServletConfig config)写的代码了,也就是在GenericServlet类中的成员变量config会一直是null,无法得到赋值,因为被重写了,就不会在执行GenericServlet中init(ServletConfig config)方法中的代码。要想赋值,就必须在重写的init(ServletConfig config)方法中调用父类的init(ServletConfig config)方法,也就是super.init(ServletConfig config),这样一来,就很不方便,怕有时候会忘了写这句代码,所以在GenericServlet类中增加一个init()方法,以后需要在init方法中需要初始化别的数据,只需要重写init()这个方法,而不需要去覆盖init(ServletConfig config)这个方法,这样设计,就好很多,不用在管init(ServletConfig config)这个其中的内容了。也不用出现其他的问题。

                service(ServletRequest req, ServletResponse res)

                      

                   一个抽象方法,说明在GenericServlet类中并没有实现该内容,那么我们想到的是,在它上面肯定还有一层,也就是还有一个子类继承它,实现该方法,要是让我们自己写的Servlet继承GenericServlet,需要自己写service方法,那岂不是累死,并且我们可以看到,service方法中的参数还是ServletRequest,ServletResponse。并没有跟http相关对象挂钩,所以我们接着往下面看。

           HttpServlet类详解

               继承了GenericServlet类,通过我们上面的推测,这个类主要的功能肯定是实现service方法的各种细节和设计。并且通过类名可以知道,该类就跟http挂钩了。

                     

                关注service(HttpServletRequest req, HttpServletResponse resp)方法和service(ServletRequest req, ServletResponse res)方法。

                  service(ServletRequest req, ServletResponse res)方法

                        

                    该方法中就做一件事情,就是将ServletRequest和ServletResponse这两个对象强转为HttpServletRequest和HttpServletResponse对象。为什么能这样转?

                      首先要知道req、res是什么类型,通过打印System.out.println(req),可以知道,req实际上的类型是org.apache.catalina.connector.RequestFacade                         Tomcat中的源码。

                        

                          

                    通过图可以得知,req的继承结构:RequestFacade、httpServletRequest、ServletRequest,我们知道本身req是ServletRequest,那么从继承结构上看,它也可以看成HttpServletRequest,也可以看成ServletRequest,所以强转为HttpServletRequest是可以的,如果不明白,我举个例子,ArrayList、List、Object 这个,Object obj = new ArrayList();  List list = new ArrayList();  一个ArrayList对象可以看成List对象, 也可以看成一个Object对象,现在obj是不是可以堪称List对象呢?答案是可以的,因为obj就是ArrayList对象,既然是ArrayList对象,那么就可以看成是List对象。一样的道理,RequestFacade 对应 ArrayList、httpServleRequest对应 List、 ServletRequest 对应 Object。

                    转换为httpServletRequest和HttpServletResponse对象之后,在调用service(HttpServletRequest req, HttpServletResponse resp)方法。

                service(HttpServletRequest req, HttpServletResponse resp)

                    这个方法就是判断浏览器过来的请求方式是哪种,每种的处理方式不一样,我们常用的就是get,post,并且,我们处理的方式可能有很多的内容,所以,在该方法内会将get,post等其他5种请求方式提取出来,变成单个的方法,然后我们需要编写servlet时,就可以直接重写doGet或者doPost方法就行了,而不是重写service方法,更加有针对性。所以这里就回到了我们上面编写servlet时的情况,继承httpServlet,而只要重写两个方法,一个doGet,一个doPost,其实就是service方法会调用这两个方法中的一个(看请求方式)。所以也就解答了我们一开始提的问题3。 

http://www.cnblogs.com/xdp-gacl/p/3763559.html

ServletConfig:作用是获取初始和上下文参数,用于有状态请求和线程共享数据

ServletContext:功能:tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web配置公共信息等,通俗点讲,就是一个web项目,就存在一个ServletContext实例,每个Servlet请求读可以访问到它。

 

http://www.cnblogs.com/rocomp/p/4814765.html

Cookie&Session

        1、什么是会话:     
            用户开一个浏览器,点击对个超链接,访问服务器多个Web资源,然后关闭浏览器,整个过程称之为一个会话。
            每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
        2、保存会话数据的两种技术:
              Cookie:Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的Web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
              HttpSession:Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器 创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源是,其他web资源在从用户各自的session中取出数据为用户服务。
        3、Cookie API
            javax.servlet.http.Cookie类用于创建一个Cookie,response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。同样,request接口中也定义了一个个头Cookie方法,它用于获取客户端提交的Cookie。Cookie类的方法:
          public Cookie(String name,String value);
          setValue与getValue方法
          setMaxAge与getMaxAge方法
          setPath与getPath方法
          setDomain与getDomain方法
          getName方法
          由于Cookie保存在客户端,所有,给不给传Cookie是由浏览器决定的,取决于MYURL.startWith(domain+path)完全匹配。domain是主机名加端口号,path是从第一个"/"开始的文件路径。
          cookie.setPath("/");可以让该cookie在同一个服务器下的多个项目共享。
        4、Cookie细节
            一个Cookie只能表示一种信息,它至少患有一个标识该信息的名称(name)和设置值(value)。
            一个Web应用可以给一个浏览器发送多个Cookie;一个浏览器也可以存储多个Web网站的Cookie。
            每个浏览器有自己默认的存放Cookie个数,并限制每个站点存放Cookie的个数,每个Cookie的大小限制为4kb。
            如果创建了一个cookie,并将它发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除,若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
            注意,删除cookie是,path必须一致,否则不会删除。   
        5、Session       
            在web开发中,服务器可以为每个用户浏览器创建一个会话对象(Session对象),把用户数据写到用户浏览器独占的Session中,当前用户使一个浏览器独占一个Session对象。因此,需要保存用户数据时,服务器程序可以用Session保存,统一浏览器可以从用户的Session中取出该用户的数据,为用户服务。
            Session对象有服务器创建,开发人员可以调用request对象的getSession方法得到Session对象。
            浏览器第一次请求时,服务器会在响应头中加入Set-Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8; Path=/Day28ServletResponse/; HttpOnly。当浏览器下次请求时会携带这个Session的唯一标识,Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8。服务器就之后是同一个用户的行为了。
            服务器内存中的每个Session都有一个32位的id作为唯一标识,Tomcat为每个Session默认的生存时间为30分中。
         6、浏览器禁用Cookie之后的Session处理
             浏览器禁用Cookie之后,就无法再请求中携带JSESSIONID内容,所以导致服务器共享出问题。Java提供URL重写方案:
             response.encodeRedirectURL(url);对sendRedirect方法的URL地址进行重写。
             response.encodeURL(url);对表单action和超链接的url地址进行重写。
             如果用户浏览器没有禁用Cookie,重写方法什么也不做;如果用户浏览器禁用了Cookie,则重写方法在每个URL地址中携带JSESSIONID,服务器保证了一个用户的每一个请求行为携带SessionID,从而保证Session的作用。
             Session的invalidate()方法使Session立刻失效。
             可以在项目的web.xml中配置Session失效时间。
 
Servlet高级特性--过滤器
        1、过滤器概述:
         过滤器是Servlet2.3规范新增的功能,也是Servlet容器管理的对象,其结构同Servlet很类似,比如init()方法,destory()方法, 但是功能不同,过滤器主要是在源数据与目的数据之间起过滤作用的中间组件。
        2、过滤器链
         在一个Web应用中,可以一次编写多个过滤器,这些过滤器组合起来,称为一个过滤器链,其执行顺序为注册顺序,先注册的会先执行
        3、编码转换过滤器
          在JavaWeb开发中,初学者经常会遇到java乱码的问题,统一字符编码,是解决乱码问题非常有效的手段,在Web开发中,可以使用过滤器对请求中的参数信息进行编码转换。
        4、权限校验过滤器(清楚整个处理流程)
           根据不同的权限,用户分别能够访问不同的页面。
 

Tomcat

学习Servlet技术,就需要有一个Servlet运行环境,也就是需要有一个Servlet容器,本文用的是Tomcat。

Tomcat是一个免费的开放源代码的Servlet容器,它是Apache软件基金会(Apache Software Foundation)的一个顶级项目,由Apache、Sun和其他一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和 JSP规范总是能在Tomcat中得到体现,Tomcat 6支持最新的Servlet 2.5和JSP 2.1规范。因为Tomcat技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱,并得到了部分软件开发商的认可,成为目前比较流行的Web服 务器。

Tomcat和IIS、Apache等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的 Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache,我们可以将Apache和Tomcat集成在 一起使用,Apache作为HTTP Web服务器,Tomcat作为Web容器。

Tomcat服务器接受客户请求并做出响应的过程如下:

1)客户端(通常都是浏览器)访问Web服务器,发送HTTP请求。 
2)Web服务器接收到请求后,传递给Servlet容器。 
3)Servlet容器加载Servlet,产生Servlet实例后,向其传递表示请求和响应的对象。 
4)Servlet实例使用请求对象得到客户端的请求信息,然后进行相应的处理。 
5)Servlet实例将处理结果通过响应对象发送回客户端,容器负责确保响应正确送出,同时将控制返回给Web服务器。

Tomcat的体系结构

Tomcat服务器是由一系列可配置的组件构成的,其中核心组件是Catalina Servlet容器,它是所有其他Tomcat组件的顶层容器。我们可以通过查看Tomcat安装文件夹下的conf文件夹中的server.xml文件 来了解Tomcat各组件之间的层次关系。由于server.xml注释太多,特简化如下:

<?xml version='1.0' encoding='utf-8'?>  
<Server port="8005" shutdown="SHUTDOWN">  
    <Service name="Catalina">  
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>  
        <Engine name="Catalina" defaultHost="localhost">  
            <Host name="localhost">  
                <Context path="" docBase="WORKDIR" reloadable="true"/>  
            </Host>  
        </Engine>  
    </Service>  
</Server>  

其中WORKDIR为你想要导入的项目路径。我们下面简单介绍一下各组件在Tomcat服务器中的作用。 
(1)Server

Server表示整个的Catalina Servlet容器。Tomcat提供了Server接口的一个默认实现,这通常不需要用户自己去实现。在Server容器中,可以包含一个或多个Service组件。

(2)Service

Service是存活在Server内部的中间组件,它将一个或多个连接器(Connector)组件绑定到一个单独的引擎(Engine)上。在Server中,可以包含一个或多个Service组件。Service也很少由用户定制,Tomcat提供了Service接口的默认实现,而这种实现既简单又能满足应用。

(3)Connector

连接器(Connector)处理与客户端的通信,它负责接收客户请求,以及向客户返回响应结果。在Tomcat中,有多个连接器可以使用。

(4)Engine

在Tomcat中,每个Service只能包含一个Servlet引擎(Engine)。引擎表示一个特定的Service的请求处理流水线。作为一个Service可以有多个连接器,引擎从连接器接收和处理所有的请求,将响应返回给适合的连接器,通过连接器传输给用户。用户允许通过实现Engine接口提供自定义的引擎,但通常不需要这么做。

(5)Host

Host表示一个虚拟主机,一个引擎可以包含多个Host。用户通常不需要创建自定义的Host,因为Tomcat给出的Host接口的实现(类StandardHost)提供了重要的附加功能。

(6)Context

一个Context表示了一个Web应用程序,运行在特定的虚拟主机中。什么是Web应用程序呢?在Sun公司发布的Java Servlet规范中,对Web应用程序做出了如下的定义:“一个Web应用程序是由一组Servlet、HTML页面、类,以及其他的资源组成的运行在Web服务器上的完整的应用程序。它可以在多个供应商提供的实现了Servlet规范的Web容器中运行”。一个Host可以包含多个Context(代表Web应用程序),每一个Context都有一个唯一的路径。用户通常不需要创建自定义的Context,因为Tomcat给出的Context接口的实现(类StandardContext)提供了重要的附加功能。

Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述。

开发者可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的Servlet。
原文地址:https://www.cnblogs.com/suntp/p/9163384.html