springMVC1

springMVC

SpringMVC分為:

  • 前端控制器:當(dāng)用戶請(qǐng)求時(shí)綜合調(diào)用映射器咐刨、適配器插龄、控制器上遥、視圖解析器對(duì)用戶的請(qǐng)求進(jìn)行響應(yīng)

  • 映射器:對(duì)前端控制器發(fā)送的URL路徑進(jìn)行檢查澡谭,如果路徑錯(cuò)誤返回404

  • 適配器:尋找正確的控制器纯命,如果找不到拋出異常

  • 控制器:對(duì)用戶的請(qǐng)求進(jìn)行處理西剥,將請(qǐng)求得到的數(shù)據(jù)以及要顯示的視圖放入ModelAndView對(duì)象中

  • 視圖解析器:接收ModelAndView對(duì)象,從中獲取數(shù)據(jù)亿汞,經(jīng)過處理組合成視圖交給前端控制器進(jìn)行處理

DispatcherServlet原理

1瞭空、根據(jù)請(qǐng)求的路徑找到HandlerMethod(帶有Method反射屬性,也就是對(duì)應(yīng)Controller中的方法)

2疗我、然后匹配路徑對(duì)應(yīng)的攔截器

3咆畏、通過HandlerMapping接口實(shí)現(xiàn)類獲得HandlerExecutionChain對(duì)象(包含HandlerMethod和攔截器)

4、有了HandlerExecutionChain之后吴裤,通過HandlerAdapter對(duì)象進(jìn)行處理得到ModelAndView對(duì)象

調(diào)用HandlerMethod內(nèi)部handle的時(shí)候:
1旧找、使用各種HandlerMethodArgumentResolver接口實(shí)現(xiàn)類,完成參數(shù)綁定

2麦牺、使用到各種Converter接口實(shí)現(xiàn)類钮蛛,完成類型轉(zhuǎn)換

3、使用各種HandlerMethodReturnValueHandler接口實(shí)現(xiàn)類枕面,處理返回值

4愿卒、最終返回值被處理成ModelAndView對(duì)象

5、這期間發(fā)生的異常會(huì)被HandlerExceptionResolver接口實(shí)現(xiàn)類進(jìn)行處理

5潮秘、RequestToViewNameTranslator接口實(shí)現(xiàn)類將請(qǐng)求地址解析為視圖名(若有手動(dòng)設(shè)置視圖名琼开,則使用手動(dòng)設(shè)置的)

6、通過各種View和ViewResolver接口實(shí)現(xiàn)類渲染視圖(將Model中的數(shù)據(jù)放到request域?qū)ο笾姓碥瘢?yè)面的編譯柜候。。躏精。)

前端控制器

前端控制器在web.xml中配置

  <servlet>
  <!-- 命名 -->
    <servlet-name>springmvc</servlet-name>
    <!-- 加載包中的前端控制器 -->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 讓服務(wù)器已啟動(dòng)就開始加載文件springMVC.xml渣刷,用的是contextConfigLocation這個(gè)屬性 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springMVC.xml</param-value>
    </init-param> 
        <!-- 啟動(dòng)加載 -->
    <load-on-startup>1</load-on-startup> 
  </servlet>

  <servlet-mapping>
  <!-- 對(duì)應(yīng)上面的命名 -->
    <servlet-name>springmvc</servlet-name>
    <!-- 對(duì)文件進(jìn)行攔截來執(zhí)行上面的程序, "/"代表攔截所有的-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

兩種映射器

    <!-- 映射器 -->                    
   <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
   <!-- 映射器2 -->
   <bean class=" org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
            <!-- 這里的值要和控制器中的id相對(duì)應(yīng) -->
                <prop key="/text1">text</prop>
                <prop key="/text1">text</prop>
            </props>
        </property>
   </bean>

兩種適配器

   <!-- 適配器  要實(shí)現(xiàn)Controller接口-->
   <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
   <!-- 適配器2 要實(shí)現(xiàn) HttpRequestHandler接口 -->
   <bean class=" org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>

控制器

   <!-- 控制器 -->
   <bean class="com.hemi.controller.MyController"  name="/text" id="text"></bean>

后端控制器代碼

public class MyController implements org.springframework.web.servlet.mvc.Controller{

    @Override
    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {      
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//      req.setAttribute("username", username);
//      req.setAttribute("password", password);
        ModelAndView view = new ModelAndView();
        if("lisi".equals(username)&&"123".equals(password)){
            view.setViewName("Hello.jsp");
        }
        else{
            view.setViewName("login.jsp");
        }

        return view;
    }

}

視圖解析器

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

視圖解析器的配置前綴后綴

   <!-- 視圖解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <!-- 前綴 -->
   <property name="prefix" value="/"></property>
   <!-- 后綴 -->
   <property name="suffix" value=".jsp"></property>
   </bean>

使用注解的方式配置springMVC

注意:注解適配器和映射器要一起使用才有效

注解適配器和映射器要一起使用才有效

     <!-- 掃描包 -->
   <context:component-scan base-package="com.hemi.controller"></context:component-scan>


   <!-- 配置注解 1-->
        <!-- 配置映射器注解 -->
   <bean class=" org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping "></bean>
        <!-- 配置適配器注解 -->
   <bean class=" org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!--配置注解2-->
    <!-- 終極替換上面的注解 -->
    <mvc:annotation-driven></mvc:annotation-driven>
  • @RequestMapping("path"):在方法上使用該注解矗烛,配置對(duì)應(yīng)的映射路徑
 @Controller
 public class TextControler{
       @RequestMapping("show1")
       public ModelAndView show1(){}
   }

springMVC后端控制器進(jìn)行響應(yīng)的三種方式

ModleAndView類型返回值:

  • view.setViewName("Hello"); 保存要顯示的視圖

  • view.addObject("password", password); 向域?qū)ο笾斜4鏀?shù)據(jù)(實(shí)際是保存到request域?qū)ο笾?

   @RequestMapping("show1")
   public ModelAndView show1(HttpServletRequest req){
       String username = req.getParameter("username");
       String password = req.getParameter("password");
       ModelAndView view = new ModelAndView();
       view.addObject("username", username);
       view.addObject("password", password);       
       view.setViewName("Hello");
       return view;        
   }
@RequestMapping("show1")
   public ModelAndView show1(HttpServletRequest req){
       String username = req.getParameter("username");
       String password = req.getParameter("password");
       ModelAndView view = new ModelAndView();
       view.addObject("username", username);
       view.addObject("password", password);       
       view.setViewName("Hello");
       return view;        
   }
  • String類型返回值返回視圖位置辅柴,使用Modle以及ModleMap來保存數(shù)據(jù)
    @RequestMapping("show2")
   public String show2(Model model,HttpServletRequest req){
       String username = req.getParameter("username");
       String password = req.getParameter("password");
       model.addAttribute("username", username);
       model.addAttribute("password", password);
       return "Hello";     
   }

void類型返回值要用域?qū)ο髞肀4鏀?shù)據(jù),通過請(qǐng)求轉(zhuǎn)發(fā)和重定向來進(jìn)行響應(yīng)

    @RequestMapping("show3")
   public void show3(HttpServletRequest req,HttpServletResponse resp){
       String username = req.getParameter("username");
       String password = req.getParameter("password");
       req.setAttribute("username", username);
       req.setAttribute("password", password);
       try {
           req.getRequestDispatcher("Hello.jsp").forward(req, resp);
       } catch (ServletException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }

參數(shù)綁定

簡(jiǎn)單參數(shù)綁定:傳入的數(shù)據(jù)是以key/value的形式進(jìn)行傳遞,key和后端控制器的形參名字相同,可以使用注解@RequestParam("username")為后端控制器的形參名起別名碌嘀,與key相對(duì)應(yīng)

Pojo參數(shù)綁定:傳入的數(shù)據(jù)是以key/value的形式進(jìn)行傳遞涣旨,key值與Pojo中的屬性名稱相同

自定義類型: 進(jìn)行date和數(shù)據(jù)類型的綁定,需要自己編寫轉(zhuǎn)換類

自定義轉(zhuǎn)換類型配置步驟:

  • 編寫轉(zhuǎn)換類
public class DateConvert implements Converter<String, Date>{

   @Override
   public Date convert(String source) {
       SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
       try {
           return format.parse(source);
       } catch (ParseException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
       return null;
   }

}
  • 在spring配置文件中進(jìn)行配置
   <mvc:annotation-driven conversion-service="conversionService">          
   </mvc:annotation-driven>

   <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
       <property name="converters">
           <list>
               <bean class="com.hemi.controller.convert.DateConvert"></bean>
           </list>         
       </property>

   </bean>
  • 在實(shí)體類中對(duì)綁定的Date屬性值進(jìn)行綁定
private String username;
private String password;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date date;
  • 配置后端控制器
    @RequestMapping("show4")
   public String show4(Model model,User user){
       model.addAttribute("user", user);
       return "Hello";     
   }

參數(shù)綁定數(shù)組(數(shù)組和list集合一樣)

前端頁(yè)面

    <form action="show5" method="post">
       用戶名:<input type="text" name="username"><br> 
       密碼:<input type="password" name="password"> <br>
       日期<input type="text" name="date"><br>
       <!--傳遞list集合中裝的是多個(gè)地址對(duì)象-->
       <input type="text" placeholder="請(qǐng)輸入地址" name="add[0].addres"><br> 
       <input type="text" placeholder="請(qǐng)輸入編碼" name="add[0].code"><br> 
       <input type="text" placeholder="請(qǐng)輸入地址" name="add[1].addres"><br> 
       <input type="text" placeholder="請(qǐng)輸入編碼" name="add[1].code"><br> 
       <!--傳遞單個(gè)地址的實(shí)體對(duì)象-->
       <input type="text" placeholder="請(qǐng)輸入地址" name="add.addres"><br> 
       <input type="text" placeholder="請(qǐng)輸入編碼" name="add.code"><br> 
       <!--傳遞一個(gè)數(shù)組-->
       <input type="checkbox" name="hobby" value="basketball">籃球<br>
       <input type="checkbox" name="hobby" value="football">籃球<br>
       <input type="checkbox" name="hobby" value="tennis">網(wǎng)球
       <input type="submit" value="登錄">
   </form>

實(shí)體類

private String username;
private String password;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date date;
private List<Address> add;

控制器:

   @RequestMapping("show5")
   public String show5(String[] hobby){
   }

全局異常處理

  • 1股冗、自定義異常類(繼承Exception或RuntimeException)
public class CustomException extends Exception{
   private String msg;

   public CustomException(String msg) {
       super(msg);
       this.msg = msg;
   }

   public String getMsg() {
       return msg;
   }

   public void setMsg(String msg) {
       this.msg = msg;
   }
}
  • 2霹陡、自定義異常處理器實(shí)現(xiàn) HandlerExceptionResolver接口
public class ExceptionHandler implements HandlerExceptionResolver{

   @Override
   public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object object,
           Exception ex) {
       CustomException customException=null;
       if (ex instanceof CustomException) {
           customException=(CustomException)ex;
       }else{
           customException=new CustomException("未知錯(cuò)誤");
       }
       ModelAndView view = new ModelAndView();
       view.addObject("error", customException);
       view.setViewName("error");
       return view;
   }
}
  • 3、在springmvc配置文件中配置全局異持棺矗控制器
<!-- 定義全局異常 -->
   <bean class="com.hemi.exception.handler.ExceptionHandler"></bean>

靜態(tài)資源的釋放

在配置文件中進(jìn)行配置

    <!-- 靜態(tài)資源釋放-->
   <mvc:resources location="/image/" mapping="/image/*.*"></mvc:resources>

文件上傳

1烹棉、編寫配置文件

    <!-- 配置文件上傳處理 -->
   <bean id="multipartResolver"
       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       <!-- 配置默認(rèn)編碼 -->
       <property name="defaultEncoding" value="utf-8"></property>
       <!-- 配置最大上傳文件大小 -->
       <property name="maxUploadSize" value="10485760000"></property>
       <!-- 配置最大上傳所用內(nèi)存大小 -->
       <property name="maxInMemorySize" value="40960"></property>
   </bean>

2、上傳單個(gè)文件怯疤,后端控制器:

    public String upload(MultipartFile file,HttpServletRequest req) throws IllegalStateException, IOException{
        if(file==null){
            return "uploadFile";            
        }
        //取出文件名
        String filename = file.getOriginalFilename();
        //根據(jù)文件的虛擬入境找到真實(shí)入境
        String path = req.getServletContext().getRealPath("/temp");
          File file2 = new File(path);
          if (!file2.exists()) {
            //創(chuàng)建目錄
            file2.mkdirs();
        }
          //將傳入的文件按照真實(shí)入境和文件名寫出來
        file.transferTo(new File(file2,filename));
        return "success";       
    }

3浆洗、批量上傳文件,后端控制器

    @RequestMapping("/upload1")
    public String upload1(MultipartFile[] file,HttpServletRequest req) throws IllegalStateException, IOException{
        for (MultipartFile multipartFile : file) {
             if(file==null){
            return "uploadFile";            
            }
            String filename = multipartFile.getOriginalFilename();
            String realPath = req.getServletContext().getRealPath("/team");
            File file2 = new File(realPath);
            if (!file2.exists()) {
                file2.mkdirs();
            }
            multipartFile.transferTo(new File(file2,filename));         
        }
        return "success";
    }

4、編寫前端表單頁(yè)面

    <form action="upload" method="post" enctype="multipart/form-data">
    請(qǐng)上傳文件:<input type="file" name="file">
        <br>
        <input type="submit" value="upload">
    </form> 
    <hr>
    <form action="upload1" method="post" enctype="multipart/form-data">
    請(qǐng)上傳文件:<input type="file" name="file">
        <br>
        請(qǐng)上傳文件:<input type="file" name="file">
        <br>
        <input type="submit" value="upload1">
    </form> 

注意:

  • 把form表單的默認(rèn)的enctype 類型改成 enctype="multipart/form-data"

  • 表單的提交方式設(shè)為:post

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旅薄,一起剝皮案震驚了整個(gè)濱河市辅髓,隨后出現(xiàn)的幾起案子泣崩,更是在濱河造成了極大的恐慌少梁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矫付,死亡現(xiàn)場(chǎng)離奇詭異凯沪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)买优,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門妨马,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杀赢,你說我怎么就攤上這事烘跺。” “怎么了脂崔?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵滤淳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我砌左,道長(zhǎng)脖咐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任汇歹,我火速辦了婚禮屁擅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘产弹。我一直安慰自己派歌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胶果,像睡著了一般常挚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稽物,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天奄毡,我揣著相機(jī)與錄音,去河邊找鬼贝或。 笑死吼过,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咪奖。 我是一名探鬼主播盗忱,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼羊赵!你這毒婦竟也來了趟佃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤昧捷,失蹤者是張志新(化名)和其女友劉穎闲昭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體靡挥,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡序矩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跋破。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片簸淀。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖毒返,靈堂內(nèi)的尸體忽然破棺而出租幕,到底是詐尸還是另有隱情,我是刑警寧澤拧簸,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布劲绪,位于F島的核電站,受9級(jí)特大地震影響狡恬,放射性物質(zhì)發(fā)生泄漏珠叔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一弟劲、第九天 我趴在偏房一處隱蔽的房頂上張望祷安。 院中可真熱鬧,春花似錦兔乞、人聲如沸汇鞭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霍骄。三九已至台囱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間读整,已是汗流浹背簿训。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留米间,地道東北人强品。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像屈糊,于是被迫代替她去往敵國(guó)和親的榛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理逻锐,服務(wù)發(fā)現(xiàn)夫晌,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評(píng)論 25 707
  • 1.Spring web mvc介紹 Spring web mvc和Struts2都屬于表現(xiàn)層的框架,它是Spri...
    七弦桐語閱讀 11,518評(píng)論 2 38
  • 這個(gè)時(shí)代里昧诱,我們應(yīng)該踏下心來把自己像一顆種子一樣摁到土里去晓淀,把自己像一個(gè)植物一樣栽到花盆里面,讓自己的根系在現(xiàn)實(shí)生...
    蝶衣寶貝閱讀 205評(píng)論 0 0
  • 堅(jiān)持不懈的努力造就成功纲熏。
    稼軒李德智閱讀 988評(píng)論 1 9