SpringMVC筆記

前言:一年前看視頻學(xué)習(xí)這個(gè)框架的時(shí)候做的筆記。渗柿「雠瑁〈滂耄現(xiàn)在自己看來(lái)覺(jué)得還是有點(diǎn)蛋疼玫鸟。谅将。中跌。想了想還是放上來(lái)了谋逻,萬(wàn)一開(kāi)發(fā)要看呢沼死,求勿噴也搓。和媳。声登。

springmvc

  • 執(zhí)行流程的過(guò)程圖:
基本流程
  • 具體執(zhí)行流程(這個(gè)就是現(xiàn)在自己手寫的啦):

1.用戶提交請(qǐng)求狠鸳。
2.DispatchServlet接收到請(qǐng)求,將請(qǐng)求交給 HandlerMapping處理悯嗓,而HandlerMapping將會(huì)把請(qǐng)求映射為HandlerExecutionChain對(duì)象(包含一個(gè)Handler處理器(頁(yè)面控制器)對(duì)象件舵、多個(gè)HandlerInterceptor攔截器)對(duì)象。
3.DispatchSerlvet調(diào)用HandlerAdapter來(lái)調(diào)用Handler(Controller)脯厨,HandlerAdapter將會(huì)把處理器包裝為適配器铅祸,HandlerAdapter將會(huì)根據(jù)適配的結(jié)果調(diào)用真正的處理器的功能處理方法,完成功能處理合武;并返回一個(gè)ModelAndView對(duì)象(包含模型數(shù)據(jù)临梗、邏輯視圖名)
4.DispatchServlet調(diào)用ViewResolver,ViewResolver將把邏輯視圖名解析為具體的View稼跳。
5.將Model的數(shù)據(jù)渲染到View上盟庞。
6.將View返回到用戶。

  • 基本配置(xml版):
    • 先導(dǎo)入jar包汤善,如下:
      <code>commons-logging.jar
      org.springframework.asm-3.0.5.RELEASE.jar
      org.springframework.beans-3.0.5.RELEASE.jar
      org.springframework.context-3.0.5.RELEASE.jar
      org.springframework.core-3.0.5.RELEASE.jar
      org.springframework.expression-3.0.5.RELEASE.jar
      org.springframework.web.servlet-3.0.5.RELEASE.jar
      org.springframework.web-3.0.5.RELEASE.jar</code>

    • 在web.xml中配置核心過(guò)濾器:
      <code><servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      </servlet>
      <servlet-mapping>
      <servlet-name>DispatcherServlet</servlet-name>
      // 確保了只有action后綴名的請(qǐng)求才可以提交到后臺(tái)
      <url-pattern>*.action</url-pattern>
      </servlet-mapping>
      </code>

    • 開(kāi)發(fā)action(實(shí)現(xiàn)controller接口):
      <code>
      public class HelloAction implements Controller{
      // 構(gòu)造函數(shù)什猖,下文有驚喜
      public HelloAction() {
      System.out.println("HelloAction():"+this.hashCode());
      }
      @Override
      public ModelAndView handleRequest(HttpServletRequest request,
      HttpServletResponse response) throws Exception {
      // ModelAndView表示封裝的Model數(shù)據(jù)和View視圖
      System.out.println("handleRequest()");
      ModelAndView modelAndView = new ModelAndView();
      modelAndView.addObject("message", "this is my first springmvc app");
      // 沒(méi)配置邏輯視圖的要配置文件路徑
      // 如:modelAndView.setViewName("./jsp/success.jsp");
      modelAndView.setViewName("success");
      return modelAndView;
      }
      }
      </code>

    • 在配置xml中配置映射(要注意的是票彪,上面的配置核心過(guò)濾器步驟,沒(méi)有指定配置文件不狮,所以默認(rèn)叫做DispatcherServlet-servlet.xml降铸,而且是放在WEB-INF目錄下):
      <code>
      <bean name="/hello.action" class="com.ycTime.action.HelloAction"></bean></code>

    • 自定義配置文件路徑:
      <code>
      <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
      </init-param>
      </servlet>
      </code>

    • 配置邏輯視圖(直接返回頁(yè)面的名字),需要在springmvc.xml(我的配置叫這個(gè)名字而已)那里配置:
      <code>
      <bean
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/jsp/"></property>
      <property name="suffix" value=".jsp"></property>
      </bean></code>


      結(jié)果
訪問(wèn)了兩次摇零,HelloAction的構(gòu)造函數(shù)只執(zhí)行一次推掸,可以看到構(gòu)造函數(shù)下面一行紅字上寫著,XXXSingletons驻仅,證明Controller是單例的终佛。而且創(chuàng)建這個(gè)單例的時(shí)間,還是在HandlerMapping工作之前的(同樣可以看紅字看出來(lái)雾家,Mapped URL XXXX)
  • 注解版:
    • 直接加注解铃彰,無(wú)需在springmvc.xml那里配置action,只需要配置好掃描的包就可以直接使用芯咧,賊他媽迅速牙捉。
      代碼:<code>
      @Controller
      @RequestMapping(value="/json")
      public class JsonAction</code>
      @Controller的意思是把類聲明為controller。@RequestMapping是請(qǐng)求的控制敬飒,比如value就是控制namespace(映射路徑)邪铲,還有method之類的參數(shù)。

    • 掃描配置:
      <code>

      <context:component-scan base-package="com.ycTime.action"></context:component-scan>
      這個(gè)的前提:
      xmlns:context="http://www.springframework.org/schema/context"
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      在xml那里配置聲明无拗,不然用不了context標(biāo)簽
      </code>

收集參數(shù)(不分版本):

  • 收集參數(shù)并封裝為對(duì)象
    <code>
    @RequestMapping(value="/register",method=RequestMethod.POST)
    public String register(Model model, User user){
    System.out.println(user.getUsername()+":"+user.getPassword()+
    ":"+user.getJoinDate().toLocaleString());
    model.addAttribute("message", "注冊(cè)成功");
    model.addAttribute("user", user);
    return "success";
    }</code>
    直接在函數(shù)的參數(shù)列表里面寫上就好了带到,參數(shù)名字與提交的值的名字必須對(duì)應(yīng),例子中的user是直接將參數(shù)封裝成User對(duì)象英染,注意參數(shù)的名字在user類里面必須有setter方法
    參數(shù)里面里面有個(gè)model揽惹,這個(gè)就是可以操作request域數(shù)據(jù)的對(duì)象
    ![可以直接收集提交的數(shù)據(jù),也可以收集URL中的數(shù)據(jù)四康,后者需要在value上用{}標(biāo)注關(guān)鍵詞名字搪搏,在參數(shù)列表中使用@PathVariable收集到該參數(shù)

  • 收集多類型參數(shù):

    • list:
      <code>
      在表單那里:
      <input type="text" name="userList[0].username" >
      // action中的方法
      public String getArray(Model model, Bean bean){
      // 在代碼中直接獲取list或者數(shù)組就可以了
      List<User> userList = bean.getUserList();
      }
      // Bean對(duì)象
      public class Bean {
      private List<User> userList;
      public List<User> getUserList() {
      return userList;
      }
      public void setUserList(List<User> userList) {
      this.userList = userList;
      }
      }</code>
      其實(shí)這個(gè)和收集并封裝成user是一樣的,因?yàn)榉庋buser的時(shí)候是用表單中提交的值來(lái)完成user的實(shí)例化操作闪金,其中表單的name和user的屬性名是一致的疯溺。
      而封裝list的話,表單名字中的userList[0]正好作為bean里面的setList(List<User> userList)的參數(shù)哎垦,也就是用userList來(lái)完成實(shí)例化操作囱嫩。

    • 數(shù)組:<code>
      // 表單
      <td><input type="checkbox" name="ids" value="1">1</td>
      <td>sivan</td>
      <td><input type="checkbox" name="ids" value="2">2</td>

      <td>tom</td>
      // action 方法
      @RequestMapping(value="/getArray")
      public String getArray(Model model, String[] ids){
      System.out.print("被選中的序號(hào)是:");
      for (String string : ids) {
      System.out.print(string+" ");
      }
      model.addAttribute("message", "xuanzhong成功");
      return "success";
      }</code>

返回Json數(shù)據(jù)

示例
  • 首先需要導(dǎo)包
    <code>jackson-core-asl-1.9.11.jar
    jackson-mapper-asl-1.9.11.jar</code>
  • 然后在action函數(shù)返回值那里加一個(gè)類型標(biāo)簽@ResponseBody,返回值直接返回某個(gè)對(duì)象漏设,不返回字符串
    <code>
    @RequestMapping(value="/map2json")
    public @ResponseBody Map<String,User> map2Json(){
    Map<String,User> userMap = new HashMap<>();
    for(int i = 0;i<4;i++){
    User user = new User();
    user.setId(i);
    user.setJoinDate(new Date());
    user.setUsername("Liming");
    user.setAge(i*6-i+3);
    userMap.put(i+"", user);
    }
    return userMap;
    }
    </code>
  • 最后在springmvc.xml配置下適配器(不然會(huì)報(bào)找不到適配器的錯(cuò)誤):
    <code><bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
    <list>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
    </list>
    </property>
    </bean></code>

springmvc攔截器

  • 創(chuàng)建攔截器墨闲,實(shí)現(xiàn)HandlerInterceptor接口(也可以實(shí)現(xiàn)WebRequestInterceptor接口):
    <code>public class FirstInterceptor implements HandlerInterceptor{
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    throws Exception {
    System.out.println("執(zhí)行afterCompletion方法");
    }
    // modelAndView參數(shù):可以控制需要顯示的視圖
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView modelAndView)
    throws Exception {
    System.out.println("執(zhí)行postHandle方法");
    }
    /* 返回值:表示我們是否需要將當(dāng)前的請(qǐng)求攔截下來(lái)
    false: 請(qǐng)求被中止
    true: 請(qǐng)求繼續(xù)
    obj參數(shù):表示的當(dāng)前被攔截的請(qǐng)求目標(biāo)(請(qǐng)求對(duì)應(yīng)的類,比如說(shuō)user2json請(qǐng)求愿题,即obj是UserAction類)
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
    System.out.println("執(zhí)行preHandle方法");
    return true;
    }
    }
    jieguo :
    FirstInterceptor執(zhí)行preHandle方法
    FirstInterceptor執(zhí)行postHandle方法
    FirstInterceptor執(zhí)行afterCompletion方法
    </code>
    其中损俭,preHandle方法是在請(qǐng)求被處理之前執(zhí)行,postHandle在請(qǐng)求被處理之后執(zhí)行潘酗,afterCompletion方法是在請(qǐng)求結(jié)束之后執(zhí)行
  • 在springmvc的配置文件中注冊(cè)攔截器:
    <code>
    <mvc:interceptors>
    <mvc:interceptor>

    <mvc:mapping path="/user/*.action"/>
    <mvc:mapping path="/json/user2json.action"/>
    <bean class="com.ycTime.interceptor.FirstInterceptor"></bean>
    </mvc:interceptor>
    </mvc:interceptors>
    </code>

  • 當(dāng)有多個(gè)攔截器一起工作的時(shí)候杆兵,工作流程如圖:

    先按照攔截器的配置順序執(zhí)行攔截器的preHandle方法,然后執(zhí)行業(yè)務(wù)方法仔夺,然后按攔截器配置順序的倒序來(lái)執(zhí)行攔截器的postHandle方法琐脏,執(zhí)行完所有攔截器的postHandle方法在,再按倒序執(zhí)行afterCompletion方法(個(gè)人猜測(cè)是責(zé)任鏈模式缸兔。日裙。)

    <code>
    <mvc:interceptors>

    <mvc:interceptor>
    <mvc:mapping path="/user/.action"/>
    <mvc:mapping path="/json/user2json.action"/>
    <bean class="com.ycTime.interceptor.FirstInterceptor"></bean>
    </mvc:interceptor>

    <mvc:interceptor>
    <mvc:mapping path="/user/
    .action"/>
    <mvc:mapping path="/json/user2json.action"/>
    <bean class="com.ycTime.interceptor.SecondInterceptor"></bean>
    </mvc:interceptor>
    </mvc:interceptors>
    結(jié)果:
    FirstInterceptor執(zhí)行preHandle方法
    SecondInterceptor執(zhí)行preHandle方法
    1 Liming 注冊(cè)于 :26 Mon Mar 13 17:59:40 CST 2017
    SecondInterceptor執(zhí)行postHandle方法
    FirstInterceptor執(zhí)行postHandle方法
    SecondInterceptor執(zhí)行afterCompletion方法
    FirstInterceptor執(zhí)行afterCompletion方法</code>

  • 攔截起使用場(chǎng)景:解決業(yè)務(wù)共性問(wèn)題

比如:
1)字符編碼例如request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");(假設(shè)沒(méi)配置字符串過(guò)濾器,)
2)權(quán)限校驗(yàn)(request.getSession().getAttribute("user")!=null等)
方法和struts2都是一樣的惰蜜,通過(guò)request或者response加以控制來(lái)實(shí)現(xiàn)昂拂。

  • 提一下過(guò)濾器
    配置字符過(guò)濾器:
    <code><filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>utf8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>*</url-pattern>
    </filter-mapping></code>
  • 攔截器與過(guò)濾器區(qū)別:
    ①攔截器是基于java的反射機(jī)制的,而過(guò)濾器是基于函數(shù)回調(diào)抛猖。
    ②攔截器不依賴與servlet容器格侯,過(guò)濾器依賴與servlet容器。
    ③攔截器只能對(duì)action請(qǐng)求起作用财著,而過(guò)濾器則可以對(duì)幾乎所有的請(qǐng)求起作用联四。
    ④攔截器可以訪問(wèn)action上下文、值棧里的對(duì)象撑教,而過(guò)濾器不能訪問(wèn)朝墩。
    ⑤在action的生命周期中,攔截器可以多次被調(diào)用伟姐,而過(guò)濾器只能在容器初始化時(shí)被調(diào)用一次收苏。
    ⑥攔截器可以獲取IOC容器中的各個(gè)bean,而過(guò)濾器就不行愤兵,這點(diǎn)很重要倒戏,在攔截器里注入一個(gè)service,可以調(diào)用業(yè)務(wù)邏輯
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恐似,一起剝皮案震驚了整個(gè)濱河市杜跷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌矫夷,老刑警劉巖葛闷,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異双藕,居然都是意外死亡淑趾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門忧陪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扣泊,“玉大人近范,你說(shuō)我怎么就攤上這事⊙有罚” “怎么了评矩?”我有些...
    開(kāi)封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阱飘。 經(jīng)常有香客問(wèn)我斥杜,道長(zhǎng),這世上最難降的妖魔是什么沥匈? 我笑而不...
    開(kāi)封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任蔗喂,我火速辦了婚禮,結(jié)果婚禮上高帖,老公的妹妹穿的比我還像新娘缰儿。我一直安慰自己,他們只是感情好散址,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布返弹。 她就那樣靜靜地躺著,像睡著了一般爪飘。 火紅的嫁衣襯著肌膚如雪义起。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天师崎,我揣著相機(jī)與錄音默终,去河邊找鬼。 笑死犁罩,一個(gè)胖子當(dāng)著我的面吹牛齐蔽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播床估,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼含滴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了丐巫?” 一聲冷哼從身側(cè)響起谈况,我...
    開(kāi)封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎递胧,沒(méi)想到半個(gè)月后碑韵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缎脾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年祝闻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遗菠。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡联喘,死狀恐怖华蜒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豁遭,我是刑警寧澤叭喜,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站堤框,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纵柿。R本人自食惡果不足惜蜈抓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昂儒。 院中可真熱鬧沟使,春花似錦、人聲如沸渊跋。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拾酝。三九已至燕少,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒿囤,已是汗流浹背客们。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留材诽,地道東北人底挫。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脸侥,于是被迫代替她去往敵國(guó)和親建邓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理睁枕,服務(wù)發(fā)現(xiàn)官边,斷路器,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • 第一章: 回顧JavaWeb中的MVC設(shè)計(jì)模式 MVC這種設(shè)計(jì)模式外遇,不光運(yùn)用于Web領(lǐng)域拒逮,而且也能用于非Web領(lǐng)域...
    奮斗的老王閱讀 2,311評(píng)論 2 54
  • 一滩援、攔截器入門(工程springmvc-mybatis10) 1.1 攔截器的定義 HandlerIntercep...
    yjaal閱讀 1,146評(píng)論 1 8
  • 主要內(nèi)容: RequestMapping特性 Controller方法返回值 參數(shù)綁定 一玩徊、需求分析 這里我們還是...
    yjaal閱讀 2,850評(píng)論 1 9
  • 一恩袱、相關(guān)原理及概念 1.1執(zhí)行流程 從上面的圖中我們可以大致明白springMVC的調(diào)度流程泣棋,下面詳細(xì)說(shuō)明: 1....
    yjaal閱讀 3,706評(píng)論 0 20