Servlet

key point

  • Servlet GenericServlet HttpServlet HttpRequestServlet HttpResponseServlet
  • 保持狀態(tài)的方法
  • Servlet 之間的消息共享級(jí)別
  • Context Listener(application)
    • ServletContextListener
    • ServletContextAttributeListener
  • Session Listener session
    • HttpSessionListener
    • HttpSessionAttributeListener
    • HttpSessionActivationListener
    • HttpSessionBindingListener
  • Filter

Java 和PHP體系對(duì)比

體系 負(fù)載均衡 中間件 框架 數(shù)據(jù)庫(kù)
JAVA nginx tomcat/jboss spring/play mysql/postgre...
PHP nginx php-cgi thinkphp/laravel mysql/postgre...

基本信息

servlet 的全稱(chēng)是 Server Applet讼庇。 是用Java編寫(xiě)的服務(wù)器端程序诚撵。其主要功能在于交互式地瀏覽和修改數(shù)據(jù)搅轿,生成動(dòng)態(tài)內(nèi)容。servlet不僅能處理http協(xié)議還能處理ftp等協(xié)議夺饲。
在servlet3.0之前一個(gè)servlet應(yīng)用由一系列處理請(qǐng)求的Java編譯文件(*.class)和一個(gè)告訴Java編譯文件是怎么組織的部署描述符(web.xml)構(gòu)成组砚。
在3.0之后 部署描述可以通過(guò)Java編碼的方式進(jìn)行拆挥,web.xml可以省略畔咧。

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package javax.servlet;

import java.io.IOException;


/**
 * Defines methods that all servlets must implement.
 *
 * <p>A servlet is a small Java program that runs within a Web server.
 * Servlets receive and respond to requests from Web clients,
 * usually across HTTP, the HyperText Transfer Protocol. 
 *
 * <p>To implement this interface, you can write a generic servlet
 * that extends
 * <code>javax.servlet.GenericServlet</code> or an HTTP servlet that
 * extends <code>javax.servlet.http.HttpServlet</code>.
 *
 * <p>This interface defines methods to initialize a servlet,
 * to service requests, and to remove a servlet from the server.
 * These are known as life-cycle methods and are called in the
 * following sequence:
 * <ol>
 * <li>The servlet is constructed, then initialized with the <code>init</code> method.
 * <li>Any calls from clients to the <code>service</code> method are handled.
 * <li>The servlet is taken out of service, then destroyed with the 
 * <code>destroy</code> method, then garbage collected and finalized.
 * </ol>
 *
 * <p>In addition to the life-cycle methods, this interface
 * provides the <code>getServletConfig</code> method, which the servlet 
 * can use to get any startup information, and the <code>getServletInfo</code>
 * method, which allows the servlet to return basic information about itself,
 * such as author, version, and copyright.
 *
 * @author  Various
 *
 * @see     GenericServlet
 * @see     javax.servlet.http.HttpServlet
 *
 */


public interface Servlet {

    /**
     * Called by the servlet container to indicate to a servlet that the 
     * servlet is being placed into service.
     *
     * <p>The servlet container calls the <code>init</code>
     * method exactly once after instantiating the servlet.
     * The <code>init</code> method must complete successfully
     * before the servlet can receive any requests.
     *
     * <p>The servlet container cannot place the servlet into service
     * if the <code>init</code> method
     * <ol>
     * <li>Throws a <code>ServletException</code>
     * <li>Does not return within a time period defined by the Web server
     * </ol>
     *
     *
     * @param config            a <code>ServletConfig</code> object 
     *                  containing the servlet's
     *                  configuration and initialization parameters
     *
     * @exception ServletException  if an exception has occurred that
     *                  interferes with the servlet's normal
     *                  operation
     *
     * @see                 UnavailableException
     * @see                 #getServletConfig
     *
     */

    public void init(ServletConfig config) throws ServletException;
    
    

    /**
     *
     * Returns a {@link ServletConfig} object, which contains
     * initialization and startup parameters for this servlet.
     * The <code>ServletConfig</code> object returned is the one 
     * passed to the <code>init</code> method. 
     *
     * <p>Implementations of this interface are responsible for storing the 
     * <code>ServletConfig</code> object so that this 
     * method can return it. The {@link GenericServlet}
     * class, which implements this interface, already does this.
     *
     * @return      the <code>ServletConfig</code> object
     *          that initializes this servlet
     *
     * @see         #init
     *
     */

    public ServletConfig getServletConfig();
    
    

    /**
     * Called by the servlet container to allow the servlet to respond to 
     * a request.
     *
     * <p>This method is only called after the servlet's <code>init()</code>
     * method has completed successfully.
     * 
     * <p>  The status code of the response always should be set for a servlet 
     * that throws or sends an error.
     *
     * 
     * <p>Servlets typically run inside multithreaded servlet containers
     * that can handle multiple requests concurrently. Developers must 
     * be aware to synchronize access to any shared resources such as files,
     * network connections, and as well as the servlet's class and instance 
     * variables. 
     * More information on multithreaded programming in Java is available in 
     * <a >
     * the Java tutorial on multi-threaded programming</a>.
     *
     *
     * @param req   the <code>ServletRequest</code> object that contains
     *          the client's request
     *
     * @param res   the <code>ServletResponse</code> object that contains
     *          the servlet's response
     *
     * @exception ServletException  if an exception occurs that interferes
     *                  with the servlet's normal operation 
     *
     * @exception IOException       if an input or output exception occurs
     *
     */

    public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;
    
    

    /**
     * Returns information about the servlet, such
     * as author, version, and copyright.
     * 
     * <p>The string that this method returns should
     * be plain text and not markup of any kind (such as HTML, XML,
     * etc.).
     *
     * @return      a <code>String</code> containing servlet information
     *
     */

    public String getServletInfo();
    
    

    /**
     *
     * Called by the servlet container to indicate to a servlet that the
     * servlet is being taken out of service.  This method is
     * only called once all threads within the servlet's
     * <code>service</code> method have exited or after a timeout
     * period has passed. After the servlet container calls this 
     * method, it will not call the <code>service</code> method again
     * on this servlet.
     *
     * <p>This method gives the servlet an opportunity 
     * to clean up any resources that are being held (for example, memory,
     * file handles, threads) and make sure that any persistent state is
     * synchronized with the servlet's current state in memory.
     *
     */

    public void destroy();
}

public void init(ServletConfig servletConfig) throws ServletException ;

init 方法在整個(gè)類(lèi)的生命周期內(nèi)只執(zhí)行一次(不是每一次用戶(hù)請(qǐng)求一次、這個(gè)類(lèi)就會(huì)被生成一次牧牢,而是當(dāng)用戶(hù)第一次請(qǐng)求這個(gè)類(lèi)的時(shí)候這個(gè)類(lèi)會(huì)被生成看锉,然后這個(gè)類(lèi)會(huì)放在JVM的heap里面,直到被GC)

ServletConfig servletConf

容器從部署文件中讀出Servlet初始化參數(shù)塔鳍,并把這些參數(shù)交給ServletConfig伯铣,然后把ServletConfig傳遞給servlet的init(ServletConfig config)方法。從而避免了在類(lèi)里硬編碼

URI和servlet對(duì)應(yīng)的這個(gè)部分可以用注解來(lái)代替

@WebServlet(name = "test", urlPatterns = {"/test1/test2/test3/"})
@WebInitParam(name = "color", value = "red")
public class MyServlet2 extends HttpServlet{
     @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
        PrintWriter printWriter = response.getWriter();
        printWriter.printf(getServletConfig().getInitParameter("color"));
    }
}

對(duì)于之前的servlet接口有兩個(gè)可以改進(jìn)的地方

  • 對(duì)于我們沒(méi)有功能的方法也要進(jìn)行實(shí)現(xiàn)
  • servletConfig要我們自己去定義
    于是就有了
    GenericServlet 這個(gè)類(lèi)里面有ServletConfig屬性轮纫,實(shí)現(xiàn)了servlet接口腔寡,我們的類(lèi)繼承GenericServlet這個(gè)接口,只用對(duì)有必要的函數(shù)進(jìn)行重寫(xiě)蜡感。

為了便于http的處理蹬蚁,JEE提供了HttpServlet。HttpServlet繼承于GenericServlet郑兴。

在實(shí)現(xiàn)Servlet接口的service方法的時(shí)候?qū)⑷雲(yún)⑾蛳罗D(zhuǎn)型為HttpServletRequest 和HttpServletRequest犀斋。這樣我們可以使用HTTP協(xié)議的一些特性。
HttpServletRequest

  • String getContextPath();//返回context(上下文的根)的路徑
  • Cookie[] getCookies();//獲得cookie
  • String getHeader(String name);//根據(jù)HTTP頭的key獲得value
  • String getMethod();//獲得請(qǐng)求的方法
  • String getQueryString(); //返回URI?后面的全部部分
  • HttpSession getSession();//找到和這個(gè)請(qǐng)求的有關(guān)的session情连。如果沒(méi)有找到叽粹,創(chuàng)建新的session。

HttpServletResponse

  • addCookie(Cookie cookie);
  • addHeader();
  • sendRedirect(); 向?yàn)g覽器response 狀態(tài)碼為302 location為sendRedirect里的地址
    HttpService 重載service方法 根據(jù)HttpRequest.method 的不同將請(qǐng)求分發(fā)到不同的函數(shù)中却舀,后續(xù)繼承HttpService的類(lèi)只要重寫(xiě)要進(jìn)行處理的Http方法的方法就好虫几。比如我要處理http的get,我繼承于HttpService的類(lèi)只要重寫(xiě)doGet方法就好挽拔。

Servlet保持狀態(tài)的4種方法

  1. 網(wǎng)址重寫(xiě) ?a=b&c=d
  2. form-data
  3. cookie
  4. HttpSession
    第1種和第2種方法可以通過(guò)request.getParameter("")的方式 通過(guò)key來(lái)訪(fǎng)問(wèn)值
    第3種 cookie是放在http頭部中的 每一次向服務(wù)器發(fā)送信息的時(shí)候都會(huì)包括該域名下所有的cookie辆脸,cookie的個(gè)數(shù)是有限制的最大數(shù)量為20個(gè)。通過(guò)HttpServletReuest 的getCookies()方法可以獲得所有的cookie 然后通過(guò)比較cookie名稱(chēng)和我們預(yù)想的cookie的name是否一致得到我們想要的cookie螃诅。
    第4種方法 一般向服務(wù)器發(fā)送消息的時(shí)候會(huì)有一個(gè)叫做JESSIONID Cookie 里面包含了在內(nèi)存這次訪(fǎng)問(wèn)session的key啡氢,服務(wù)器可以根據(jù)這個(gè)key反序列化出相關(guān)的信息。在Servlet中可以通過(guò)HttpServlet的getSession() 方法得到本次訪(fǎng)問(wèn)的HttpSession 對(duì)象术裸。

Servlet之間的消息共享

Servlet 之間通過(guò)Attribute(屬性)的方式進(jìn)行消息共享倘是。消息分享的層級(jí)有以下三個(gè)

  • request(當(dāng)個(gè)訪(fǎng)問(wèn)者當(dāng)次請(qǐng)求)
  • session (當(dāng)個(gè)訪(fǎng)問(wèn)者,所有的請(qǐng)求)
  • application (全部訪(fǎng)問(wèn)者袭艺,所有的請(qǐng)求)

在request 級(jí)別的attirbute 的使用方法一般是

Map<String, String[]> bigCities = new HashLinkedMap<>();
bigCities.put("China",{"Beijing", "Shanghai", "Hongkong"});
bigCities.put("USA",{"New York", "Boston", "Washington, D.C."})
request.setAttrribuate("bigCities",bigCities);
RequestDispatcher rd = request.getRequestDispatcher("/show.jsp");
rd.forward(request, response);

將屬性放到request中搀崭,把這個(gè)屬性轉(zhuǎn)交給jsp頁(yè)面進(jìn)行頁(yè)面的渲染

<c:forEach item = "${requestScope.bigCities}" var = "country">
    ${country.key}
    <c:forEach item= "${country.value}" var ="city" varStatus = "status">
        ${city}
        <c:if test = "${! status.last}">
            <br/>
        </c:if>
    </c:forEach>
</c:forEach>

監(jiān)聽(tīng)器

進(jìn)行事件驅(qū)動(dòng)編程,當(dāng)什么事情發(fā)生的時(shí)候我們要做出合適的反應(yīng)
定義監(jiān)聽(tīng)器有兩個(gè)方法

@WebListener
public class ListenerClass implements ListenerInterface{
}

或者

<listen>
    <listener-class>org.cor.projectName.something</listener-class>
</listen>

Context Listener 上下文級(jí)別的監(jiān)聽(tīng)器

ServletContextLister

當(dāng)一個(gè)application的context被容器所創(chuàng)建的時(shí)候猾编,容器會(huì)調(diào)用實(shí)現(xiàn)這個(gè)接口的對(duì)象的特定方法

  • void contextInitialized(ServletContextEvent event);
    對(duì)環(huán)境的初始化做出響應(yīng)
  • void contextDestoryed(ServletContextEvent event);
    對(duì)環(huán)境的析構(gòu)做出響應(yīng)
  • ServletContext getServletContext();
    得到上下文對(duì)象
    for example
@WebListener
public class AppContextListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent event){
        Map<String, String> contries = new HashMap<String, String>();
        contries.put("ca", "Canada");
        contries.put("us", "USA");
    }
}

當(dāng)一個(gè)application的context被容器所創(chuàng)建的時(shí)候瘤睹,我們給容器增加一個(gè)Attribute

ServletContextAttributeListener

當(dāng)application范圍內(nèi)的attribute發(fā)生改變的時(shí)候,容器會(huì)調(diào)用實(shí)現(xiàn)這個(gè)接口的對(duì)象的特定方法

  • void attributeAdded(ServletContextAttributeEvent event);
    增加屬性
  • void attributeRemoved(ServletContextAttributeEvent event);
    刪除屬性
  • void attributeReplaced(ServletContextAttributeEvent event);
    替換屬性的內(nèi)容

Session Listener session級(jí)別的監(jiān)聽(tīng)器

HttpSessionListener

這個(gè)接口的作用是和上面的ServletContextLister相類(lèi)似只不過(guò)是作用于session范圍

  • sessionCreated(HttpSessionEvent event);
    當(dāng)一個(gè)session被創(chuàng)建時(shí)會(huì)調(diào)用這個(gè)方法
  • sessionDestroyed(HttpSessionEvent event);
    當(dāng)一個(gè)session被銷(xiāo)毀時(shí)調(diào)用這個(gè)方法
  • HttpSession getSession();
    獲得要被操作的session

HttpSessionAttributeListener

這個(gè)接口的作用和上面的ServletContextAttributeListener 相類(lèi)似答倡,作用于session范圍

  • void attributeAdded(HttpSessionBindingEvent event)
    屬性添加
  • void attributedRemoved(HttpSessionBindingEvent event);
    屬性刪除
  • void attributeReplace(HttpSessionBindingEvent event);

HttpSessionActivationListener

session 是保存在內(nèi)存中默蚌,當(dāng)內(nèi)存不夠的時(shí)候容器會(huì)嘗試著將session進(jìn)行遷移或者序列化,通過(guò)這個(gè)接口能對(duì)做出容器的行為做出反應(yīng)

  • void sessionDidActivate(HttpSessionEvent event);(容器嘗試將session觸發(fā))
  • void sessionWillPassivate(HttpSessionEvent event);(容器嘗試著將session鈍化)

HttpSessionBindingListener

如果一個(gè)類(lèi)想知道什么時(shí)候被綁定到HttpSesison上苇羡,那么這個(gè)類(lèi)要實(shí)現(xiàn)HttpSessionBindingListener接口绸吸,在綁定的時(shí)候或者不綁定的時(shí)候,這個(gè)類(lèi)會(huì)做出合適反應(yīng)

public BigCity implements HttpSessionBindingListener{
    ...
    @Override
    public void valueBound(HttpSessionBindingEvent event){
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent event){
    }
}

在把這個(gè)類(lèi)的對(duì)象放到session的setAttribute的時(shí)候设江,valueBound會(huì)被調(diào)用锦茁。

過(guò)濾器

過(guò)濾器是指請(qǐng)求過(guò)來(lái)的時(shí)候先攔截請(qǐng)求,處理一波之后在交給servlet叉存,在驗(yàn)證登陸狀態(tài)字符處理等的方面都有應(yīng)用码俩。
定義過(guò)濾器有兩個(gè)方法

@WebFilter(filterName = "***Filter", urlPatterns = {"/*"})
//過(guò)濾器必須要以Filter結(jié)尾
public class ***Filter implements Filter{
}

或者在部署文件中

<filter>
    <filter-name>***Filter</filter-name>
    <filter-class>test.andrew.io.***Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>***Filter</filter-name>
    <url-patten>/*</url-patten>
</filter-mapping>

一個(gè)典型的Filter的應(yīng)用,設(shè)置字符

public class UTF8Filter implements Filter{

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain fchain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        //System.out.println("先執(zhí)行過(guò)濾器里面的內(nèi)容歼捏。稿存。笨篷。。瓣履。");
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

       fchain.doFilter(request, response);
        
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
               
    }
}

Spring MVC

就和其他的框架一樣 Sring 的出現(xiàn)也是為了簡(jiǎn)化開(kāi)發(fā)

  1. Spring 環(huán)境的構(gòu)建
    1.1 old school
    step1: 在web.xml 指定把所有的請(qǐng)求都發(fā)送給處理
    <?xml version="1.0" encoding="UTF-8"?>
                        <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    </web-app>
    
  • contextLoaderListener
    ContextLoaderListener的作用就是啟動(dòng)Web容器時(shí)率翅,自動(dòng)裝配ApplicationContext的配置信息。因?yàn)樗鼘?shí)現(xiàn)了ServletContextListener這個(gè)接口袖迎,在web.xml配置這個(gè)監(jiān)聽(tīng)器冕臭,啟動(dòng)容器時(shí),就會(huì)默認(rèn)執(zhí)行它實(shí)現(xiàn)的方法燕锥。至于ApplicationContext.xml這個(gè)配置文件部署在哪辜贵,如何配置多個(gè)xml文件,書(shū)上都沒(méi)怎么詳細(xì)說(shuō)明」樾危現(xiàn)在的方法就是查看它的API文檔托慨。在ContextLoaderListener中關(guān)聯(lián)了ContextLoader這個(gè)類(lèi),所以整個(gè)加載配置過(guò)程由ContextLoader來(lái)完成暇榴×穹迹看看它的API說(shuō)明
    • 第一段
      ContextLoaderServlet的API,可以看到它繼承了ContextLoader這個(gè)類(lèi)而且它實(shí)現(xiàn)了ServletContextListener跺撼。
      主要的實(shí)現(xiàn)是基于ContextLoader 這個(gè)類(lèi).
    • 第二段
      ContextLoader創(chuàng)建的是 XmlWebApplicationContext這樣一個(gè)類(lèi)窟感,它實(shí)現(xiàn)的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->
      BeanFactory這樣一來(lái)spring中的所有bean都由這個(gè)類(lèi)來(lái)創(chuàng)建
    • 第三段
      講如何部署applicationContext的xml文件,如果在web.xml中不寫(xiě)任何參數(shù)配置信息歉井,默認(rèn)的路徑是"/WEB-INF/applicationContext.xml柿祈,在WEB-INF目錄下創(chuàng)建的xml文件的名稱(chēng)必須是applicationContext.xml。如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個(gè)context參數(shù):
      <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
      /WEB-INF/classes/applicationContext-.xml
      </param-value>
      </context-param>
      <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
      /WEB-INF/classes/applicationContext-
      .xml
      </param-value>
      </context-param>
      在<param-value> </param-value>里指定相應(yīng)的xml文件名哩至,如果有多個(gè)xml文件躏嚎,可以寫(xiě)在一起并一“,”號(hào)分隔。上面的applicationContext-.xml采用通配符菩貌,比如這那個(gè)目錄下有applicationContext-ibatis-base.xml卢佣,applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件箭阶,都會(huì)一同被載入虚茶。
      由此可見(jiàn)applicationContext.xml的文件位置就可以有兩種默認(rèn)實(shí)現(xiàn):
      第一種:直接將之放到/WEB-INF下
      第二種:將之放到classpath下,但是此時(shí)要在web.xml中加入<context-param>仇参,用它來(lái)指明你的applicationContext.xml的位置以供web容器來(lái)加載嘹叫。按照Struts2 整合spring的官方給出的檔案,寫(xiě)成:
      <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext-
      .xml,classpath:applicationContext-.xml</param-value>
      </context-param>

但是也不一定要定義applicationContext.xml, 如果不定義 applicationContext

1.2 使用config方bo

  1. Spring對(duì)請(qǐng)求的處理
  2. Spring 的ORM
  3. Spring的不同環(huán)境

spring part

該注解用于讀取Request請(qǐng)求的body部分?jǐn)?shù)據(jù)
資料1
資料2
資料3

Spring 環(huán)境的構(gòu)建

每種語(yǔ)言采用自動(dòng)化構(gòu)建的方式不盡相同诈乒,Python用的是pip罩扇,PHP用的是Composer,現(xiàn)在Java社區(qū)比較常用的是gradle和maven怕磨。
下面介紹maven的依賴(lài)構(gòu)建
首先用ide構(gòu)建一個(gè)maven的項(xiàng)目

一個(gè)pom.xml的樣例

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>andrew.io</groupId><!--組織名稱(chēng)-->
    <artifactId>spring</artifactId><!--項(xiàng)目名稱(chēng)-->
    <version>1.0-SNAPSHOT</version><!--版本名稱(chēng)-->

    <dependencies>
        <!--在這個(gè)位置添加依賴(lài)的包-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.10.5.RELEASE</version>
        </dependency>
    </dependencies>
</project>

一個(gè)簡(jiǎn)易的Spring MVC的分層

和其他語(yǔ)言的項(xiàng)目一樣喂饥,一個(gè)簡(jiǎn)單的spring mvc project也會(huì)對(duì)項(xiàng)目進(jìn)行分層消约。分的層次大致如下

  1. controller
    主要用來(lái)組裝客戶(hù)端發(fā)過(guò)來(lái)的信息然后給業(yè)務(wù)層進(jìn)行處理
    捕捉異常,對(duì)異常進(jìn)行合適處理
    將結(jié)果反饋給請(qǐng)求方
  2. service
    負(fù)責(zé)主要的業(yè)務(wù)邏輯的操作
  3. dao
    數(shù)據(jù)庫(kù)CRUD
  4. domian
    對(duì)象和數(shù)據(jù)庫(kù)中的實(shí)體對(duì)應(yīng)
  5. config spring
    配置類(lèi)和spring配置文件(xml,yum,property)

這樣可以明確每個(gè)層次的邊界员帮、減少每個(gè)層次之間的耦合度或粮、增強(qiáng)復(fù)用性。

通過(guò)Spring MVC響應(yīng)一個(gè)請(qǐng)求

當(dāng)一個(gè)請(qǐng)求被容器響應(yīng)的時(shí)候集侯,首先由spring框架的DispatcherServlet進(jìn)行處理。它是一個(gè)前端控制器帜消,在Spring框架中通過(guò)單例模式實(shí)現(xiàn)棠枉,所有的請(qǐng)求都會(huì)通過(guò)它將任務(wù)派發(fā)被Controller。典型的應(yīng)用程序中會(huì)有多個(gè)控制器泡挺,DispatcherServlet會(huì)查詢(xún)一個(gè)或者多個(gè)控制器映射(handler mapping)來(lái)確定要派發(fā)給誰(shuí)辈讶。Controller的職責(zé)主要是將發(fā)過(guò)來(lái)的request做一個(gè)合適的處理(網(wǎng)址重寫(xiě)?a=b,還是通過(guò)表單提交(form-data)的post中的數(shù)據(jù)娄猫,或者是application-* 形式的)贱除,在把數(shù)據(jù)發(fā)送給server層,server層根據(jù)業(yè)務(wù)的要求對(duì)數(shù)據(jù)進(jìn)行加工媳溺,在加工過(guò)程的CRUD由Dao層負(fù)責(zé)月幌,之后將處理好的結(jié)果返回給Contorller。Controller將得到的數(shù)據(jù)進(jìn)行打包悬蔽,并且標(biāo)示出用于渲染輸出的視圖名扯躺,同時(shí)將這些數(shù)據(jù)返回給DispatcherServlet。DispatcherServlet會(huì)將使用視圖解析器(view resolver)來(lái)將邏輯視圖名匹配為一個(gè)特定的視圖實(shí)現(xiàn)蝎困。視圖將使用模型數(shù)據(jù)渲染輸出录语。由此一次請(qǐng)求完成。

配置DispatcherServlet

配置可以通過(guò)web.xml 實(shí)現(xiàn)禾乘,但是xml畢竟不如代碼清晰澎埠,現(xiàn)在比較推薦通過(guò)java類(lèi)進(jìn)行配置以下為一個(gè)配置類(lèi)

public class WebAppInitializer
        extends AbstractAnnotationConfigDispatcherServletInitializer{
    //
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[0];
    }
    //配置文件類(lèi)
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[0];
    }
    //指定上下文的根
    protected String[] getServletMappings() {
        return new String["/"];
    }
}

怎么發(fā)揮作用的?

st=>start: 開(kāi)始
servlet=>operation: 容器查找實(shí)現(xiàn) ServletContainerInitializer接口的類(lèi)
spring=>operation: spring提供了這個(gè)接口的實(shí)現(xiàn)始藕,但是它會(huì)找實(shí)現(xiàn)了WebApplicationInitailizer的類(lèi)
spring3=>operation:  spring3.2提供了一個(gè)WebApplicationInitailizer的基礎(chǔ)實(shí)現(xiàn)
蒲稳,叫做AbstractAnnotationConfigDispatcherServletInitializer,
但是正如名字顯示的是Abstract(抽象的)需要通過(guò)開(kāi)發(fā)者進(jìn)行實(shí)現(xiàn)
e=>end: 結(jié)束
st->servlet->spring->spring3->e
st=>start: 開(kāi)始

e=>end: 結(jié)束

Spring Boot 簡(jiǎn)化開(kāi)發(fā)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伍派,一起剝皮案震驚了整個(gè)濱河市弟塞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拙已,老刑警劉巖决记,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異倍踪,居然都是意外死亡系宫,警方通過(guò)查閱死者的電腦和手機(jī)索昂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扩借,“玉大人椒惨,你說(shuō)我怎么就攤上這事〕弊铮” “怎么了康谆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嫉到。 經(jīng)常有香客問(wèn)我沃暗,道長(zhǎng),這世上最難降的妖魔是什么何恶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任孽锥,我火速辦了婚禮,結(jié)果婚禮上细层,老公的妹妹穿的比我還像新娘惜辑。我一直安慰自己,他們只是感情好疫赎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布盛撑。 她就那樣靜靜地躺著,像睡著了一般捧搞。 火紅的嫁衣襯著肌膚如雪撵彻。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天实牡,我揣著相機(jī)與錄音陌僵,去河邊找鬼。 笑死创坞,一個(gè)胖子當(dāng)著我的面吹牛碗短,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播题涨,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼偎谁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了纲堵?” 一聲冷哼從身側(cè)響起巡雨,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎席函,沒(méi)想到半個(gè)月后铐望,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年正蛙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了督弓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乒验,死狀恐怖愚隧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锻全,我是刑警寧澤狂塘,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站鳄厌,受9級(jí)特大地震影響荞胡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜部翘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一硝训、第九天 我趴在偏房一處隱蔽的房頂上張望响委。 院中可真熱鬧新思,春花似錦、人聲如沸赘风。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邀窃。三九已至荸哟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瞬捕,已是汗流浹背鞍历。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肪虎,地道東北人劣砍。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像扇救,于是被迫代替她去往敵國(guó)和親刑枝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理迅腔,服務(wù)發(fā)現(xiàn)装畅,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 一 servlet概述 狹義的Servlet指javax.servlet包中的一個(gè)接口沧烈,而廣義的Servlet則是...
    靜慎獨(dú)閱讀 456評(píng)論 0 0
  • 從三月份找實(shí)習(xí)到現(xiàn)在掠兄,面了一些公司,掛了不少,但最終還是拿到小米徽千、百度苫费、阿里、京東双抽、新浪百框、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,239評(píng)論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法牍汹,類(lèi)相關(guān)的語(yǔ)法铐维,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法慎菲,異常的語(yǔ)法嫁蛇,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,622評(píng)論 18 399
  • Servlet:Sun公司制訂的一種用來(lái)擴(kuò)展Web服務(wù)器功能的組件規(guī)范。當(dāng)瀏覽器將請(qǐng)求發(fā)送給Web服務(wù)器(比如:a...
    南山伐木閱讀 585評(píng)論 0 4