精华内容
下载资源
问答
  • action和servlet的关系

    2017-03-04 13:59:00
    那些MVC框架Servlet(struts1)或者Filter(struts2)来封装了HttpServletRequestHttpServletResponse对象,在自己Action类中实现控制层.从对象本身来说,确实不是一个东西,但是从设计分层(架构...

    版本一

    其实就是一个玩意儿!
    只不过action是那些MVC框架的控制层的叫法.
    当然,这个回答是笼统了点,但是其实就那回事.
    那些MVC框架用Servlet(struts1)或者Filter(struts2)来封装了HttpServletRequest和HttpServletResponse对象,在自己的Action类中实现控制层.从对象本身来说,确实不是一个东西,但是从设计分层(架构)上看,这对于使用框架的开发者来说,这难道不是一样的道理?就是控制层!
    action是业务层?那要看你这个工程项目的规模了.要是小网站,那可以把service都写在action里面.但从这个角度来说,是把service层合并到控制层去了.

    版本二

    struts的action 有一个servlet 的成员,而且struts的action 的方法 
    execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
    会传入一个HttpServletRequest的参数 
    详情参见struts的官方文档:http://struts.apache.org/1.x/apidocs/index.html 

    无论是在struts1还是在struts2 
    action 本身只是一个普通的Java bean 

    在struts2中,action 与servlet 就没有关系了,除非你实现servletaware接口,这样的话,struts2会给你注入一个servlet


    说的应该是struts2中的action ,关系肯定是有的,action 运行在web容器中,不管是struts1还是struts2,action 跟容器的交互,实质上都是通过request 和response ,只不过,struts1把他们暴露出来了,而struts2则由框架来维护了,这是struts2的分层思想的一个体现。

    转载于:https://www.cnblogs.com/printN/p/6501212.html

    展开全文
  • 从上图可以看出,在Tomcat中,Service,Host,Context,Wrapper四个相邻的容器之间的关系都是1对n的关系。其中,Service还包含了一个Connector,对应服务连接端口;一个Executor,用来维护内部Servlet的执行线程;...

    1. 概要介绍          

    Tomat是一个Servlet容器,不过它也内部也放置了Web应用服务。先上一张Tomcat静态的结构简图

    Tomcat静态结构

           从上图可以看出,在Tomcat中,Service,Host,Context,Wrapper四个相邻的容器之间的关系都是1对n的关系。其中,Service还包含了一个Connector,对应服务连接端口;一个Executor,用来维护内部Servlet的执行线程;一个 Engine,一个Engine可以配置多个Host,也就是站点,站点的概念,可以理解为子域名,基地址,例如ris.xxxxx.com、emr.xxxxx.com;每个Host可以对应多个Context,这个和含有WEB-INF(Web.xml)文件夹相对应,可以理解为一级目录,例如xxxxx.com/risManager、xxxxx.com/emrManager;每个Wrapper都对应一个Servlet。

            这些概念其实都是很具体的,我们从Server.xml配置文件中,就很容易理解这些概念;我绘制了一张图,首先可以从部署的位置就直接能判断的是,含有WEB-INF(Web.xml)文件夹中的内容,也就是我们自己开发的应用,就和上边介绍的Context概念相对应,在Web.xml中,<servlet>标签和Wrapper的概念相对应。

            另外,Service和Host概念,应用开发工程师可能比较陌生,属于Tomcat自己管理和部署概念,这些概念同样可以在Server.xml配置文件中能得到进行体现。例如还是下图中,如果要求在一个ip地址的多个端口上分别部署多开发的应用,就可以通过以下的示例配置实现。这种方式,很适合做SaaS的2B企业,将按照业务拆分好的云化的子服务应用,私有化部署到客户小规模的单台或者有限的几台实体服务器上,同时,这种方式还可以针对特定的子业务服务去分配适合的线程数量(Executor),以最大的限度的为客户解决成本。

            同样,也可以在一台服务器上的一个端口上,部署多个Host站点的方式,部署多个开发应用。这种方式比较适合在服务器前没有负载,直接用域名解析后端服务器的时候,使用子域名直接访问后端服务的情况。这种方式,我在实际工作不怎么用,在云端部署时,我们还是要在后端服务前加上SLB的,这样,域名解析就直接关联负载了,也就不存在上边这个需求。

    一个Tomcat部署结构

    2 ServletContext和Servlet 

    先说下Servlet和ServletContext中的概念

    1 Servlet的生命周期,如下图所示

    Servlet生命周期图

    2 Servlet是单例的,所以,线程是不安全的,所有请求线程都使用同一个Servlet实例。如果需要线程安全,需要实现STM(single thread mothod)

    而ServletContext是对这些Servlet的生命周期和使用时机进行管理,主要的职责有

    1 对Servlet进行创建,销毁,调用

    2 分配线程,每次http的请求都会生成或者从线程池获取一个可用线程,service调用结束后,将线程返还给线程池

    3 针对网络访问端口的监听,特定协议的解析,字符流或者字节流的解析和编码(自己写过这种编解码,真的很不健壮)

            下面就从源码解读上,去窥视下整个Servlet工作的动态过程。首先,自定义一个Servlet类JavacCommand,并在Web.xml中,进行配置

    Servlet执行堆栈标题
    以上看到的代码是不是和第一节讲的内容说的类有很大不同?其实,任何概念都必须要在源码上验证的。如果只是了解下,其实,第一小节以及足够了,毕竟我们平时也没必要太关注这些问题。

    3 Tomcat中Service,Host,Context,Wrapper四容器原理和源码解读

            首先,介绍几个概念,容器,也就是在一小节中介绍的Service、Host、Context、Wrapper的概念,对应到代码中,这些都是接口类。可实例化的类分别对应StandardService、StandardHost、StandardContext、StandardWrapper这四个类。这个容器中,都有个保存真真执行任务的pipe列表,列表中记录着每个可以执行业务的阀类,阀类都继承于ValveBase类,ValueBase类又实现了Value接口类,在Value接口类中,就有重要的接口函数invoke。
           这里主要介绍下,pipeline生成的逻辑,这里可以对照下源代码,篇幅有限,我只粘贴主要逻辑代码,在pipeLine中,是将新的阀类插入到倒数第二的位置,倒数第一的位置留给了basic,我们再看容器代码,任意找个容器 StandardHost
    public class StandardPipeline{
        private Valve first = null;
        private Valve basic = null;
        public void addValve(Valve valve) {
            if (first == null) {
                first = valve;
                valve.setNext(basic);
            } else {
                Valve current = first;
                while (current != null) {
                    if (current.getNext() == basic) {  //插入到队列的倒数第二位置,最后一个位置一直都是basic
                        current.setNext(valve);
                        valve.setNext(basic);
                        break;
                    }
                    current = current.getNext();
                }
            }
        }
    }
    public class StandardHost {   
      protected Pipeline pipeline = new StandardPipeline(this);   
      public StandardHost() {   
        super();   
        pipeline.setBasic(new StandardHostValve());   
      }   
    }

           接下来,我们开始讲整个动态调用到Servlet实例的过程;我们直接看StandardHostValve的invoke函数

    final class StandardHostValve extends ValveBase {
        public final void invoke(Request request, Response response) {
            // 1 选择对应的Context容器
            Context context = request.getContext();
            // 2 在容器的阀链中,找到第一个阀类,执行invoke
            context.getPipeline().getFirst().invoke(request, response);
        }
    }

    大概画了一张面条图,这些容器和阀类,通过设计的一个职责链模式的模式组织到一起,进行工作。

    一个Servlet在Tomcat中执行的调用顺序,阀体类和容器类

    在网上找到这张图,感觉比我做的好,很能说明整个执行的过程。大家注意,这的StandardHost容器中,有个AccessLogValve阀,就是在平时的配置中常常使用的阀类,大家可以看上文中的一个Tomcat部署结构的图中的server.xml中的配置。

    阀类和容器类调用过程

     

     

     

    最后,还有一个问题没有解决,就是在各个标准阀类中查找对应的容器的过程。

    3 针对当前request容器类的创建和查询

    大家看上边的图“自定义Servlet堆栈调用“,CoyoteAdapter在执行Service之前,首先找到当前uri对应的各级容器,是通过CoyoteAdapter.postParseRequest获取的,

    public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
    
                throws Exception {
    
            //这个地方,是我省略掉一堆代码,直接也是new出来的
    
            Request request = new Request();
    
            Response response = new Response();
    
            //查找到合适的容器并且附加到request上
    
            postParseSuccess = postParseRequest(req, request, res, response);
    
            //就是2小节中描述的过程
    
            connector.getService().getContainer().getPipeline().getFirst().invoke(
    
                            request, response);
    
    }

    postParseRequest函数更长,直接吧我能看懂的代码段贴上来

    protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
    
                org.apache.coyote.Response res, Response response) throws IOException, ServletException {
    
            //通过一个Mapper类来实现的,最后将request.mappingData给填充完毕
    
            connector.getService().getMapper().map(serverName, decodedURI,
    
                        version, request.getMappingData());
    
            return true;
    
    }

    下面看Mapper.java类

        public void map(MessageBytes host, MessageBytes uri, String version,
                        MappingData mappingData) throws IOException {
    
            internalMap(host.getCharChunk(), uri.getCharChunk(), version, mappingData);
        }

     

    通过内部的结构将,需要的各级容器查询到。

    这篇文章的篇幅太大,下一篇,详细将这个Mapper的创建和查询介绍下。

     

    展开全文
  • 在Spring框架中applicationContext.xmlSpring -servlet.xml有任何关系吗? DispatcherServlet可以使用到在applicationContext.xml中声明属性文件吗? 另外,为什么我需要*-servlet.xml呢?为什么只有...

    问题:spring框架里面applicationContext.xml 和spring-servlet.xml 的区别

    • 在Spring框架中applicationContext.xml和Spring -servlet.xml有任何关系吗?

    • DispatcherServlet可以使用到在applicationContext.xml中声明的属性文件吗?

    • 另外,为什么我需要*-servlet.xml呢?为什么只有applicationContext.xml是不够的?

    回答一

    Spring允许您在parent-child这个层级结构中定义多个上下文。

    applicationContext.xml定义了“root webapp context”的beans,即与webapp关联的上下文。

    spring-servlet.xml(你想叫什么都行)定义了一个servlet的应用程序上下文的bean。在一个webapp(一个Spring servlet)中可能有很多这样的文件(例如:servlet spring1的spring1 .xml,servlet spring2的spring2 .xml)。

    spring-servlet.xml中的bean可以引用applicationContext.xml中的bean,但反之则不行。

    所有Spring MVC控制器都必须放在Spring -servlet.xml上下文中。

    在大多数简单的情况下,applicationContext.xml上下文不是必需的。它通常被用于包含webapp中所有servlet共享的bean。如果您只有一个servlet,那么没有什么意义,除非你有特殊的用处。

    回答二

    简单来说就是:

    • applicationContext.xml定义了在所有servlet之间共享的bean。如果您的应用程序有多个servlet,那么在applicationContext.xml中定义共有的资源那就很有用了。

    • spring-servlet.xml定义了只与该servlet相关的bean。这是dispatche servlet。因此,你的Spring MVCcontrollers 必须要在这个文件中定义。

    • 如果在web应用程序中只运行一个servlet,那么在spring-servlet.xml里面中定义所有的bean也是没有问题的鸭。

    文章翻译自Stack Overflow:https://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring-frame

    展开全文
  • 1. Servlet是服务器端运行一个程序,是一个被编译好Java类。它不是框架等。 2. Web容器启动,需要依赖Servlet。当web服务器开始执行时,servlet类就被初始化 3. 当用户通过浏览器访问时候,会

    转自:http://blog.csdn.net/initphp/article/details/38171219



    Servlet是什么

    1. Servlet是服务器端运行的一个程序,是一个被编译好的Java类。它不是框架等。

    2. Web容器的启动,需要依赖Servlet。当web服务器开始执行时,servlet类就被初始化

    3. 当用户通过浏览器访问的时候,会输入URI,这个时候,web服务器就通过Servlet来分发请求执行不同的内容。


    一般我们会使用Tomcat来运行Java的web项目。通常我们可以在web项目的目录中可以看到WEB-INF这样的文件夹。这个文件夹是受保护的,外部无法通过url来访问的。文件夹里面包含了web.xml以及classlibs目录。我们要将web项目运行起来,就得在web.xml中定义一个Servlet,因为定义了Servlet,web容器才能知道需要如何去分发请求进行业务处理的。

    Servlet是有一个Jar包,里面包含了一些Servlet的相关设计和细节。


    一个使用Spring的Servlet的web.xml配置例子:

    [html] view plain copy
     print?
    1. <servlet>  
    2.     <servlet-name>apiServlet</servlet-name>  
    3.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    4.     <init-param>  
    5.         <param-name>contextConfigLocation</param-name>  
    6.         <param-value>classpath:spring-common.xml</param-value>  
    7.     </init-param>  
    8.     <load-on-startup>1</load-on-startup>  
    9. </servlet>  
    10. <servlet-mapping>  
    11.     <servlet-name>apiServlet</servlet-name>  
    12.     <url-pattern>/api/*</url-pattern>  
    13. </servlet-mapping>  



    HttpServlet

    HttpServlet是一个抽象类,具体的实现自己需要的Servlet需要通过继承该类来实现 。

    HttpServlet中主要的几个方法:

    方法 用途
    doGet          处理HTTP GET请求
    doPost 处理HTTP POST请求
    doPut 处理HTTP PUT请求
    doDelete 处理HTTP DELETE请求

    Servlet最终调用的是service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost

    可以看下HttpServlet类:

    [java] view plain copy
     print?
    1. package javax.servlet.http;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.PrintWriter;  
    5. import java.io.OutputStreamWriter;  
    6. import java.io.UnsupportedEncodingException;  
    7. import java.lang.reflect.Method;  
    8. import java.text.MessageFormat;  
    9. import java.util.Enumeration;  
    10. import java.util.Locale;  
    11. import java.util.ResourceBundle;  
    12.   
    13. import javax.servlet.GenericServlet;  
    14. import javax.servlet.ServletException;  
    15. import javax.servlet.ServletOutputStream;  
    16. import javax.servlet.ServletRequest;  
    17. import javax.servlet.ServletResponse;  
    18.   
    19.   
    20. public abstract class HttpServlet extends GenericServlet  
    21.     implements java.io.Serializable  
    22. {  
    23.     private static final String METHOD_DELETE = "DELETE";  
    24.     private static final String METHOD_HEAD = "HEAD";  
    25.     private static final String METHOD_GET = "GET";  
    26.     private static final String METHOD_OPTIONS = "OPTIONS";  
    27.     private static final String METHOD_POST = "POST";  
    28.     private static final String METHOD_PUT = "PUT";  
    29.     private static final String METHOD_TRACE = "TRACE";  
    30.   
    31.     private static final String HEADER_IFMODSINCE = "If-Modified-Since";  
    32.     private static final String HEADER_LASTMOD = "Last-Modified";  
    33.       
    34.     private static final String LSTRING_FILE =  
    35.     "javax.servlet.http.LocalStrings";  
    36.     private static ResourceBundle lStrings =  
    37.     ResourceBundle.getBundle(LSTRING_FILE);  
    38.      
    39.   
    40.     public HttpServlet() { }  
    41.       
    42.     //处理HTTP的GET请求,你需要实现一个Servlet,然后实现该方法  
    43.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
    44.     throws ServletException, IOException  
    45.     {  
    46.     String protocol = req.getProtocol();  
    47.     String msg = lStrings.getString("http.method_get_not_supported");  
    48.     if (protocol.endsWith("1.1")) {  
    49.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
    50.     } else {  
    51.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
    52.     }  
    53.     }  
    54.   
    55.     protected long getLastModified(HttpServletRequest req) {  
    56.     return -1;  
    57.     }  
    58.   
    59.   
    60.     protected void doHead(HttpServletRequest req, HttpServletResponse resp)  
    61.     throws ServletException, IOException  
    62.     {  
    63.     NoBodyResponse response = new NoBodyResponse(resp);  
    64.       
    65.     doGet(req, response);  
    66.     response.setContentLength();  
    67.     }  
    68.       
    69.     //实现HTTP POST请求  
    70.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
    71.     throws ServletException, IOException  
    72.     {  
    73.     String protocol = req.getProtocol();  
    74.     String msg = lStrings.getString("http.method_post_not_supported");  
    75.     if (protocol.endsWith("1.1")) {  
    76.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
    77.     } else {  
    78.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
    79.     }  
    80.     }  
    81.   
    82.   
    83.     protected void doPut(HttpServletRequest req, HttpServletResponse resp)  
    84.     throws ServletException, IOException  
    85.     {  
    86.     String protocol = req.getProtocol();  
    87.     String msg = lStrings.getString("http.method_put_not_supported");  
    88.     if (protocol.endsWith("1.1")) {  
    89.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
    90.     } else {  
    91.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
    92.     }  
    93.     }  
    94.   
    95.   
    96.     protected void doDelete(HttpServletRequest req,  
    97.                 HttpServletResponse resp)  
    98.     throws ServletException, IOException  
    99.     {  
    100.     String protocol = req.getProtocol();  
    101.     String msg = lStrings.getString("http.method_delete_not_supported");  
    102.     if (protocol.endsWith("1.1")) {  
    103.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
    104.     } else {  
    105.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
    106.     }  
    107.     }  
    108.       
    109.   
    110.     private Method[] getAllDeclaredMethods(Class c) {  
    111.   
    112.         if (c.equals(javax.servlet.http.HttpServlet.class)) {  
    113.             return null;  
    114.         }  
    115.   
    116.         Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());  
    117.         Method[] thisMethods = c.getDeclaredMethods();  
    118.       
    119.         if ((parentMethods != null) && (parentMethods.length > 0)) {  
    120.             Method[] allMethods =  
    121.                 new Method[parentMethods.length + thisMethods.length];  
    122.         System.arraycopy(parentMethods, 0, allMethods, 0,  
    123.                              parentMethods.length);  
    124.         System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,  
    125.                              thisMethods.length);  
    126.   
    127.         thisMethods = allMethods;  
    128.     }  
    129.   
    130.     return thisMethods;  
    131.     }  
    132.            
    133.     protected void doOptions(HttpServletRequest req, HttpServletResponse resp)  
    134.     throws ServletException, IOException  
    135.     {  
    136.     Method[] methods = getAllDeclaredMethods(this.getClass());  
    137.       
    138.     boolean ALLOW_GET = false;  
    139.     boolean ALLOW_HEAD = false;  
    140.     boolean ALLOW_POST = false;  
    141.     boolean ALLOW_PUT = false;  
    142.     boolean ALLOW_DELETE = false;  
    143.     boolean ALLOW_TRACE = true;  
    144.     boolean ALLOW_OPTIONS = true;  
    145.       
    146.     for (int i=0; i<methods.length; i++) {  
    147.         Method m = methods[i];  
    148.           
    149.         if (m.getName().equals("doGet")) {  
    150.         ALLOW_GET = true;  
    151.         ALLOW_HEAD = true;  
    152.         }  
    153.         if (m.getName().equals("doPost"))   
    154.         ALLOW_POST = true;  
    155.         if (m.getName().equals("doPut"))  
    156.         ALLOW_PUT = true;  
    157.         if (m.getName().equals("doDelete"))  
    158.         ALLOW_DELETE = true;  
    159.           
    160.     }  
    161.       
    162.     String allow = null;  
    163.     if (ALLOW_GET)  
    164.         if (allow==null) allow=METHOD_GET;  
    165.     if (ALLOW_HEAD)  
    166.         if (allow==null) allow=METHOD_HEAD;  
    167.         else allow += ", " + METHOD_HEAD;  
    168.     if (ALLOW_POST)  
    169.         if (allow==null) allow=METHOD_POST;  
    170.         else allow += ", " + METHOD_POST;  
    171.     if (ALLOW_PUT)  
    172.         if (allow==null) allow=METHOD_PUT;  
    173.         else allow += ", " + METHOD_PUT;  
    174.     if (ALLOW_DELETE)  
    175.         if (allow==null) allow=METHOD_DELETE;  
    176.         else allow += ", " + METHOD_DELETE;  
    177.     if (ALLOW_TRACE)  
    178.         if (allow==null) allow=METHOD_TRACE;  
    179.         else allow += ", " + METHOD_TRACE;  
    180.     if (ALLOW_OPTIONS)  
    181.         if (allow==null) allow=METHOD_OPTIONS;  
    182.         else allow += ", " + METHOD_OPTIONS;  
    183.       
    184.     resp.setHeader("Allow", allow);  
    185.     }  
    186.       
    187.      
    188.     protected void doTrace(HttpServletRequest req, HttpServletResponse resp)   
    189.     throws ServletException, IOException  
    190.     {  
    191.       
    192.     int responseLength;  
    193.       
    194.     String CRLF = "\r\n";  
    195.     String responseString = "TRACE "+ req.getRequestURI()+  
    196.         " " + req.getProtocol();  
    197.       
    198.     Enumeration reqHeaderEnum = req.getHeaderNames();  
    199.       
    200.     while( reqHeaderEnum.hasMoreElements() ) {  
    201.         String headerName = (String)reqHeaderEnum.nextElement();  
    202.         responseString += CRLF + headerName + ": " +  
    203.         req.getHeader(headerName);   
    204.     }  
    205.       
    206.     responseString += CRLF;  
    207.       
    208.     responseLength = responseString.length();  
    209.       
    210.     resp.setContentType("message/http");  
    211.     resp.setContentLength(responseLength);  
    212.     ServletOutputStream out = resp.getOutputStream();  
    213.     out.print(responseString);    
    214.     out.close();  
    215.     return;  
    216.     }         
    217.   
    218.     //最终所有的具体实现都是需要实现Service方法.容器最终调用的就是该方法  
    219.     protected void service(HttpServletRequest req, HttpServletResponse resp)  
    220.     throws ServletException, IOException  
    221.     {  
    222.     String method = req.getMethod();  
    223.         //这边通过HTTP的方法来判断,具体的HTTP METHOD,然后决定需要执行的方法名称。     
    224.     if (method.equals(METHOD_GET)) {  
    225.         long lastModified = getLastModified(req);  
    226.         if (lastModified == -1) {  
    227.         // servlet doesn't support if-modified-since, no reason  
    228.         // to go through further expensive logic  
    229.         doGet(req, resp);  
    230.         } else {  
    231.         long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);  
    232.         if (ifModifiedSince < (lastModified / 1000 * 1000)) {  
    233.             // If the servlet mod time is later, call doGet()  
    234.                     // Round down to the nearest second for a proper compare  
    235.                     // A ifModifiedSince of -1 will always be less  
    236.             maybeSetLastModified(resp, lastModified);  
    237.             doGet(req, resp);  
    238.         } else {  
    239.             resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);  
    240.         }  
    241.         }  
    242.   
    243.     } else if (method.equals(METHOD_HEAD)) {  
    244.         long lastModified = getLastModified(req);  
    245.         maybeSetLastModified(resp, lastModified);  
    246.         doHead(req, resp);  
    247.           
    248.     } else if (method.equals(METHOD_POST)) {  
    249.         doPost(req, resp);  
    250.           
    251.     } else if (method.equals(METHOD_PUT)) {  
    252.         doPut(req, resp);     
    253.           
    254.     } else if (method.equals(METHOD_DELETE)) {  
    255.         doDelete(req, resp);  
    256.           
    257.     } else if (method.equals(METHOD_OPTIONS)) {  
    258.         doOptions(req,resp);  
    259.           
    260.     } else if (method.equals(METHOD_TRACE)) {  
    261.         doTrace(req,resp);  
    262.           
    263.     } else {  
    264.         //  
    265.         // Note that this means NO servlet supports whatever  
    266.         // method was requested, anywhere on this server.  
    267.         //  
    268.   
    269.         String errMsg = lStrings.getString("http.method_not_implemented");  
    270.         Object[] errArgs = new Object[1];  
    271.         errArgs[0] = method;  
    272.         errMsg = MessageFormat.format(errMsg, errArgs);  
    273.           
    274.         resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);  
    275.     }  
    276.     }  
    277.   
    278.     private void maybeSetLastModified(HttpServletResponse resp,  
    279.                       long lastModified) {  
    280.     if (resp.containsHeader(HEADER_LASTMOD))  
    281.         return;  
    282.     if (lastModified >= 0)  
    283.         resp.setDateHeader(HEADER_LASTMOD, lastModified);  
    284.     }  
    285.      
    286.     public void service(ServletRequest req, ServletResponse res)  
    287.     throws ServletException, IOException  
    288.     {  
    289.     HttpServletRequest  request;  
    290.     HttpServletResponse response;  
    291.       
    292.     try {  
    293.         request = (HttpServletRequest) req;  
    294.         response = (HttpServletResponse) res;  
    295.     } catch (ClassCastException e) {  
    296.         throw new ServletException("non-HTTP request or response");  
    297.     }  
    298.     service(request, response);  
    299.     }  
    300. }  

    HttpServlet最上层是继承Servlet这个接口类。Servlet这个接口类非常简单,只定义了5个方法。

    可以看下下面的Servlet接口:

    [java] view plain copy
     print?
    1. package javax.servlet;  
    2.   
    3. import java.io.IOException;  
    4.   
    5.   
    6.   
    7.   
    8. public interface Servlet {  
    9.   
    10.     //容器初始化  
    11.     public void init(ServletConfig config) throws ServletException;  
    12.       
    13.       
    14.     //获取配置信息  
    15.     public ServletConfig getServletConfig();  
    16.       
    17.     //具体的service 请求分发  
    18.     public void service(ServletRequest req, ServletResponse res)  
    19.     throws ServletException, IOException;  
    20.       
    21.       
    22.    //获取servlet信息  
    23.     public String getServletInfo();  
    24.       
    25.     //容器销毁的时候  
    26.     public void destroy();  
    27. }  


    Spring的DispatcherServlet

    Spring主要通过DispatcherServlet实现了Servlet。DispatcherServlet最上层也是继承的是HttpServlet这个类。

    我们主要看下DispatcherServlet两个比较重要的方法:

    [java] view plain copy
     print?
    1. @Override  
    2.     protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    3.         if (logger.isDebugEnabled()) {  
    4.             String requestUri = urlPathHelper.getRequestUri(request);  
    5.             logger.debug("DispatcherServlet with name '" + getServletName() + "' processing " + request.getMethod() +  
    6.                     " request for [" + requestUri + "]");  
    7.         }  
    8.   
    9.         // Keep a snapshot of the request attributes in case of an include,  
    10.         // to be able to restore the original attributes after the include.  
    11.         Map<String, Object> attributesSnapshot = null;  
    12.         if (WebUtils.isIncludeRequest(request)) {  
    13.             logger.debug("Taking snapshot of request attributes before include");  
    14.             attributesSnapshot = new HashMap<String, Object>();  
    15.             Enumeration<?> attrNames = request.getAttributeNames();  
    16.             while (attrNames.hasMoreElements()) {  
    17.                 String attrName = (String) attrNames.nextElement();  
    18.                 if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {  
    19.                     attributesSnapshot.put(attrName, request.getAttribute(attrName));  
    20.                 }  
    21.             }  
    22.         }  
    23.   
    24.         // Make framework objects available to handlers and view objects.  
    25.         request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());  
    26.         request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);  
    27.         request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);  
    28.         request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());  
    29.   
    30.         FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);  
    31.         if (inputFlashMap != null) {  
    32.             request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));  
    33.         }  
    34.         request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());  
    35.         request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);  
    36.   
    37.         try {  
    38.             doDispatch(request, response); //这边最终也是调用了doDispatch方法,该方法主要用来处理SPring框架的具体业务分发逻辑。  
    39.         }  
    40.         finally {  
    41.             // Restore the original attribute snapshot, in case of an include.  
    42.             if (attributesSnapshot != null) {  
    43.                 restoreAttributesAfterInclude(request, attributesSnapshot);  
    44.             }  
    45.         }  
    46.     }  
    47.           
    48.         //Spring框架最终的分发都是通过该方法的  
    49.     protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    50.         HttpServletRequest processedRequest = request;  
    51.         HandlerExecutionChain mappedHandler = null;  
    52.         int interceptorIndex = -1;  
    53.   
    54.         try {  
    55.             ModelAndView mv;  
    56.             boolean errorView = false;  
    57.   
    58.             try {  
    59.                 processedRequest = checkMultipart(request);  
    60.   
    61.                 // Determine handler for the current request.  
    62.                 mappedHandler = getHandler(processedRequest, false);  
    63.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
    64.                     noHandlerFound(processedRequest, response);  
    65.                     return;  
    66.                 }  
    67.   
    68.                 // Determine handler adapter for the current request.  
    69.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
    70.   
    71.                 // Process last-modified header, if supported by the handler.  
    72.                 String method = request.getMethod();  
    73.                 boolean isGet = "GET".equals(method);  
    74.                 if (isGet || "HEAD".equals(method)) {  
    75.                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
    76.                     if (logger.isDebugEnabled()) {  
    77.                         String requestUri = urlPathHelper.getRequestUri(request);  
    78.                         logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);  
    79.                     }  
    80.                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
    81.                         return;  
    82.                     }  
    83.                 }  
    84.   
    85.                 // 这里是处理前置拦截器  
    86.                 HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
    87.                 if (interceptors != null) {  
    88.                     for (int i = 0; i < interceptors.length; i++) {  
    89.                         HandlerInterceptor interceptor = interceptors[i];  
    90.                         if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
    91.                             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
    92.                             return;  
    93.                         }  
    94.                         interceptorIndex = i;  
    95.                     }  
    96.                 }  
    97.   
    98.                 //处理最终的Action逻辑  
    99.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
    100.   
    101.                 // Do we need view name translation?  
    102.                 if (mv != null && !mv.hasView()) {  
    103.                     mv.setViewName(getDefaultViewName(request));  
    104.                 }  
    105.   
    106.                                 //处理后置拦截器  
    107.                 if (interceptors != null) {  
    108.                     for (int i = interceptors.length - 1; i >= 0; i--) {  
    109.                         HandlerInterceptor interceptor = interceptors[i];  
    110.                         interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
    111.                     }  
    112.                 }  
    113.             }  
    114.             catch (ModelAndViewDefiningException ex) {  
    115.                 logger.debug("ModelAndViewDefiningException encountered", ex);  
    116.                 mv = ex.getModelAndView();  
    117.             }  
    118.             catch (Exception ex) {  
    119.                 Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
    120.                 mv = processHandlerException(processedRequest, response, handler, ex);  
    121.                 errorView = (mv != null);  
    122.             }  
    123.   
    124.             // Did the handler return a view to render?  
    125.             if (mv != null && !mv.wasCleared()) {  
    126.                 render(mv, processedRequest, response);  
    127.                 if (errorView) {  
    128.                     WebUtils.clearErrorRequestAttributes(request);  
    129.                 }  
    130.             }  
    131.             else {  
    132.                 if (logger.isDebugEnabled()) {  
    133.                     logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +  
    134.                             "': assuming HandlerAdapter completed request handling");  
    135.                 }  
    136.             }  
    137.   
    138.             // Trigger after-completion for successful outcome.  
    139.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
    140.         }  
    141.   
    142.         catch (Exception ex) {  
    143.             // Trigger after-completion for thrown exception.  
    144.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
    145.             throw ex;  
    146.         }  
    147.         catch (Error err) {  
    148.             ServletException ex = new NestedServletException("Handler processing failed", err);  
    149.             // Trigger after-completion for thrown exception.  
    150.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
    151.             throw ex;  
    152.         }  
    153.   
    154.         finally {  
    155.             // Clean up any resources used by a multipart request.  
    156.             if (processedRequest != request) {  
    157.                 cleanupMultipart(processedRequest);  
    158.             }  
    159.         }  
    160.     }  
    展开全文
  • 有很多人认为 Web 开发无非就是了解一些框架,做做页面,如果只是这样话,就会一直停留在很低水平,不断干重复工作,加班累到吐血。之前我们是从 Servlet 讲起,今天需要更深入一步,进入Web底层协议 —— ...
  • JSF与servlet关系

    千次阅读 2016-11-04 16:28:15
    JSF是一个面向组件事件驱动MVC框架,它Struts 2不同,它有点ASP.NETWebForm开发相似。JSF为我们进行了一些封装,提供了很多组件。比如Ajax,验证,转换等,我们都可以使用相 关组件。但不管怎么样,JSF从...
  • Spring mvc和Servlet

    2019-04-01 22:12:00
    总结: ... SpringMVC:开发效率高(好多共性的东西都封装好了,是对...这两者的关系,就如同MyBatisJDBC,一个性能好,一个开发效率高,是对另一个的封装。 springmvc是一个基于spring的web框架, 一、springmv...
  • 定义对象间一对多依赖关系,当一个对象状态发生改变时,所有依赖于它对象都得到通知自动更新。 GUI编程中addXxxxListener都是观察者模式。观察者设计模式示例: 开发步骤: * 第一步:实现一个需要被...
  • servlet学习笔记7——网站框架的改进

    千次阅读 2010-11-21 00:00:00
    (三)网站框架的改进之前程序设计不合理,因为其将界面业务逻辑放在一起(moddel1模式),存在以下问题:1.在LoginCl.java文件Wel.java文件中都操作了数据库,它们逻辑相似,有重复代码(潜在规则:当一段...
  • 自己为一个汽车MIS系统架构一个框架,主框架为SSH,同时根据需要扩展了servlet和JDBC(适应于大数据量查询),典型J2EE三层结构,分为表现层、中间层(业务逻辑层)数据服务层。三层体系将业务规则、数据访问...
  • SpringBoot 默认使用嵌入式 Servlet 容器为 Tomcat,通过依赖关系就可以看到: 问题: 如何定制修改 Servlet 容器相关配置? SpringBoot 能否支持其它 Servlet 容器? 相关配置 方式一:配置文件 在...
  • Tomcat与Servlet的笔记

    千次阅读 2017-10-26 21:08:44
    突然想研究一下,Tomcat服务器和Servlet的关系。一.Tomcat的模块结构和简单流程看了很多关于介绍Tomcat服务器的资料,这里写一个总结。Tomcat服务器主要有几个模块构成 ,Server,Service,Connector,Container...
  • jsp 和servlet区别问题

    2011-03-29 11:18:00
    【1】.什么时候使用servlet 什么情况使用jsp?... servlet业务不变,jsp表现层怎么变,跟业务层也没有关系。 <br />【2】.servlet没有jsp简洁 那么为什么还要使用servlet 是为了框架么? <br /
  • 心得在学了一点SSH框架之后,我就一直在想,如果完全不用任何框架,只使用Servlet和JSP相关知识,来实现一个小系统,会是什么样。这就是这个小程序,一个简单甚至简陋博客系统,功能很简单,只有用户登录、...
  • 一直以来,我们使用SpringMVC...要说任何Web框架都离不开Servlet,它是一个容器,也是一种规范,你要和Web搞上关系,无非就是那么几种,监听器、过滤器和Servlet,最终都是为了切进ServletContext。 SpringMVC是基于S
  • Web应用创建于HTTP之上,...从服务器度端角度看,一个新请求就是一个新用户,这个请求其它请求也没有任何关系。为了解决这个问题,在web中引入了会话(session)概念。一个会话(session)是指从客户端发起第一个
  •  </span></span> <span>tomcatjetty都是web容器,对servlet3.0api提供了不同实现(实际也都是基于nio?) </span></span> <span>HttpAsyncClient这个就是异步http客户端(实际上也是基于java nio) ...
  • 这是一种正确的学习方式,在我看来Servlet是J2EE的基础,要熟练的掌握J2EE,必须深刻的了解Servlet的原理,因为你想想,现在只要是web相关的技术或框架,无论是开源的、非开源的,哪个和Servlet没有关系?...
  • 学好j2ee第一是打好基础比如什么servlet,jsp,filter,等等都重点学学,很多培训学校都忽视了这些。然后学习一些服务器,比如tomcate,jboss,weblogic,webshpere等等,特殊后几个,非常有用,如果想达到企业级开发,...
  • 分别是用户管理页面、供应商管理页面订单管理,主要是进行数据增删改查(CRUD),所以这里主要以 用户管理页面进行数据增删改,主要是理解三层架构Servlet、ServiceDao层操作关系,方便上手后面的框架SSM...
  • Spring框架是一个管理对象的容器,就像Web容器Tomcat可以管理servlet的生命周期,Spring容器可以管理对象的生命周期。 Spring的组件化让类类对象之间的关系变得不那么紧密,降低了耦合度。 Spring的IOC的XML...
  • 学好j2ee第一是打好基础比如什么servlet,jsp,filter,等等都重点学学,很多培训学校都忽视了这些。然后学习一些服务器,比如tomcate,jboss,weblogic,webshpere等等,特殊后几个,非常有用,如果想达到企
  •  什么是Struts2框架 Struts2 框架是用来替代servlet和jsp。他功能就是处理访问服务器请求。 2. Struts2框架的优点1. 接收参数(自动封装参数)2. 参数校验3. 可以控制页面跳转4. 防止表单数据重复...
  • hibernate介绍 Hibernate是一个开放源代码对象关系映射框架,它对JDBC进行了非常轻量级对象封装,使得Java程序员可以随心所欲使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC场合,既可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 552
精华内容 220
关键字:

框架和servlet的关系