<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SSM-springMVC

      springMVC完成表現(xiàn)層的開發(fā)

      servlet能做的事情,springMVC都能做。servlet用來接收請(qǐng)求參數(shù),參數(shù)響應(yīng)結(jié)果,springMVC也可以做到這些

      springMVC簡介


      • MVC模型


      springMVC入門案例





      按照上面說的步驟來構(gòu)建項(xiàng)目

      • 1.導(dǎo)入依賴

      • 2.制作控制器

      • 4.創(chuàng)建sevlet容器的配置類,由tomcat負(fù)責(zé)加載并創(chuàng)建servlet容器(替代web.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>com.itheima</groupId>
      <artifactId>springmvc_01_quickstart</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
      <dependencies>
          <!--第一步導(dǎo)入依賴-->
          <!--springmvc底層使用的是servlet-->
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
              <version>3.1.0</version>
              <scope>provided</scope><!--避免和tomcat沖突-->
          </dependency>
          <!--里面已經(jīng)集成了spring-->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>5.2.10.RELEASE</version>
          </dependency>
      </dependencies>
          <!--Tomcat7-maven-plugin這個(gè)插件可以快速配置并部署和啟動(dòng)web工程(這里沒有使用,沒有學(xué)習(xí)過)-->
      <!--<build>
          <plugins>
              <plugin>
                  <groupId>org.apache.tomcat.maven</groupId>
                  <artifactId>tomcat7-maven-plugin</artifactId>
                  <version>2.1</version>
                  <configuration>
                      <port>80</port>
                      <path>/</path>
                  </configuration>
              </plugin>
          </plugins>
      </build>-->
      </project>
      
      • 第二部
      package com.itheima.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      //第二步:定義controller
      @Controller//2.1 將控制器將給spring管理
      public class UserController {
          //2.2設(shè)置當(dāng)前方法的訪問路徑
          @RequestMapping("/save")
          //2.3設(shè)置當(dāng)前操作的返回值(以save方法的返回值作為返回值)
          @ResponseBody
          public String save() {
              System.out.println("user save....");
              return "{'module':'springmvc'}";//以joson的形式返回?cái)?shù)據(jù)
          }
      }
      
      
      • 第三步
      package com.itheima.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      
      //springmvc的配置類(其實(shí)就是spring的配置類)
      //第三步:創(chuàng)建springMvc的配置文件,并加載對(duì)應(yīng)的bean
      @Configuration//配置類
      @ComponentScan("com.itheima.controller")//組件掃描
      public class SpringMvcConfig {
      }
      
      
      • 第四步,讓tomcat加載springmvc配置文件,創(chuàng)建出servlet容器(替代web.xml)
      package com.itheima.config;
      
      import org.springframework.web.context.WebApplicationContext;
      import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
      import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
      
      //第四步:一個(gè)servlet容器啟動(dòng)的配置類,在里面加載spring配置(替代web.xml文件)
      public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
          //加載springmvc容器配置
          @Override
          protected WebApplicationContext createServletApplicationContext() {
              AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
              ctx.register(SpringMvcConfig.class);
              return ctx;
          }
      
          //設(shè)置哪些請(qǐng)求歸屬springmvc處理
          @Override
          protected String[] getServletMappings() {
              return new String[] { "/" };//所有請(qǐng)求都交給springmvc處理
          }
      
          //加載spring容器配置
          @Override
          protected WebApplicationContext createRootApplicationContext() {
              return null;
          }
      }
      
      

      當(dāng)我們?cè)L問時(shí)將返回下面的結(jié)果

      • 總結(jié)

      入門案例工作流程


      bean加載控制



      對(duì)應(yīng)的方案

      • 具體方案
      • 注意
      • 2種方案
      package com.itheima.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.FilterType;
      
      @Configuration
      //@ComponentScan({"com.itheima.dao", "com.itheima.service"})//精確掃描
      @ComponentScan(value = "com.itheima",excludeFilters =@ComponentScan.Filter//使用不包含過濾器
              (type = FilterType.ANNOTATION,//按照注解進(jìn)行過濾
                      classes = Configuration.class))//帶有Configuration注解的類將不進(jìn)行掃描
      public class SpringConfig {
      }
      
      

      此時(shí)我們?cè)趦H僅加載spring的配置文件時(shí),在獲得controller的bean的時(shí)候?qū)?huì)報(bào)錯(cuò)(因?yàn)樗念惒]有被加載)



      此時(shí)我們就可以在tomcat啟動(dòng)的時(shí)候同時(shí)加載springconfig和springmvc了

      • 此時(shí)服務(wù)器加載的配置類就是:
      package com.itheima.config;
      
      import org.springframework.web.context.WebApplicationContext;
      import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
      import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
      
      //第四步:一個(gè)servlet容器啟動(dòng)的配置類,在里面加載spring配置(替代web.xml文件)
      public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
          //加載springmvc容器配置
          @Override
          protected WebApplicationContext createServletApplicationContext() {
              AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
              ctx.register(SpringMvcConfig.class);
              return ctx;
          }
      
          //設(shè)置哪些請(qǐng)求歸屬springmvc處理
          @Override
          protected String[] getServletMappings() {
              return new String[] { "/" };//所有請(qǐng)求都交給springmvc處理
          }
      
          //加載spring容器配置
          @Override
          protected WebApplicationContext createRootApplicationContext() {
              AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
              ctx.register(SpringConfig.class);
              return ctx;
          }
      }
      
      


      • 我們只需要傳入各自的配置文件就可以了,不需要自己創(chuàng)建容器了
      package com.itheima.config;
      
      import org.springframework.web.context.WebApplicationContext;
      import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
      import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
      import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
      
      //第四步:一個(gè)servlet容器啟動(dòng)的配置類,在里面加載spring配置(替代web.xml文件)
      public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          protected Class<?>[] getRootConfigClasses() {
              return new Class[]{SpringConfig.class};
          }
      
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
          protected String[] getServletMappings() {
              return new String[]{"/"};
          }
      
      
      }
      
      

      postMan工具介紹

      • 需要先創(chuàng)建一個(gè)工作空間



        總結(jié)來說postman可以模擬瀏覽器向我的服務(wù)器發(fā)送請(qǐng)求,使用這個(gè)工具我們可以在很大程度上忽略前端的必要性,可以加速我們后端的開發(fā)

      第二部分:請(qǐng)求與響應(yīng)

      設(shè)置請(qǐng)求映射路徑

      問題1:不同模塊相同的請(qǐng)求路徑?jīng)_突問題

      • 下面有2個(gè)模塊:user和book
      //第二步:定義controller
      @Controller//2.1 將控制器將給spring管理
      public class UserController {
          //2.2設(shè)置當(dāng)前方法的訪問路徑
          @RequestMapping("/save")
          //2.3設(shè)置當(dāng)前操作的返回值(以save方法的返回值作為返回值)
          @ResponseBody
          public String save() {
              System.out.println("user save....");
              return "{'UserController':'springmvc'}";//以joson的形式返回?cái)?shù)據(jù)
          }
      
      @Controller
      public class BookController {
      //配置請(qǐng)求路徑
          @RequestMapping("/save")
          @ResponseBody
          public String save(){
              System.out.println("user save....");
              return "{'BookController':'springmvc'}";
          }
      

      他們都有save方法,并且他們的請(qǐng)求路徑都是/save

      • 解決沖突的方式


      這樣我們的路徑?jīng)_突就解決了

      問題2:同一個(gè)模塊中請(qǐng)求路徑冗長問題


      一個(gè)小注意點(diǎn):在postman中使用ctrl+ 加號(hào)和ctrl+減號(hào)可以調(diào)整頁面的大小

      get和post請(qǐng)求發(fā)送普通參數(shù)

      1.get請(qǐng)求發(fā)送參數(shù)




      對(duì)于我們controller中的方法是不區(qū)分get請(qǐng)求還是post請(qǐng)求的,他都能進(jìn)行處理。不需要寫doget和dopost方法了(在之前web中需要使用dopost調(diào)用doget以達(dá)到,方法對(duì)于get和post請(qǐng)求都能處理)。現(xiàn)在簡化了這個(gè)過程
      1.post請(qǐng)求發(fā)送參數(shù)
      我們的post請(qǐng)求的參數(shù)不是放在url中發(fā)送的,而是放在了請(qǐng)求體中進(jìn)行發(fā)送的(也就是為什么我們?cè)诘刂窓谥锌床坏絧ost請(qǐng)求的參數(shù)了),我們的post請(qǐng)求目前我知道的只能在from表單中進(jìn)行發(fā)送(method=post)



      我們的get請(qǐng)求一般不會(huì)發(fā)送中文的參數(shù),下面解決post請(qǐng)求參數(shù)中文亂碼問題
      解決post請(qǐng)求中文亂碼問題

      • 過去的處理方式

        在springmvc中我們?cè)趕ervlet容器的啟動(dòng)配置類中設(shè)置過濾器可以同樣達(dá)到這個(gè)效果
      • 增加一個(gè)過濾器可以解決亂碼
      //第四步:一個(gè)servlet容器啟動(dòng)的配置類,在里面加載spring配置(替代web.xml文件)
      public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
      
          protected Class<?>[] getRootConfigClasses() {
              return new Class[0];
          }
      
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
          //設(shè)置請(qǐng)求體的字符集過濾器
          @Override
          protected Filter[] getServletFilters() {
              CharacterEncodingFilter filter = new CharacterEncodingFilter();
              filter.setEncoding("UTF-8");
              return new Filter[]{filter};
          }
      
          protected String[] getServletMappings() {
              return new String[]{"/"};
          }
      }
      


      注意我們這個(gè)僅僅可以解決post請(qǐng)求體中文亂碼問題,對(duì)于get請(qǐng)求體的中文亂碼問題并不能解決

      5種類型參數(shù)傳遞


      在前面的我們必須在服務(wù)器端設(shè)置和發(fā)送的參數(shù)相同名稱的方法形參,才能接收到這個(gè)傳遞過來的參數(shù)。我們?cè)鯓涌梢詫?shí)現(xiàn)不這樣做也可以接收到參數(shù)呢?
      設(shè)置請(qǐng)求參數(shù)和controller中方法參數(shù)的映射(解決上面的問題)


      在一般情況下我們使用默認(rèn)的映射就可以了,不需要寫這個(gè)映射關(guān)系

      但是在大多數(shù)情況下我們都是收集一些數(shù)據(jù)封裝成一個(gè)domain,所以下面將演示傳遞一個(gè)domain作為參數(shù)

      • POJO數(shù)據(jù)類型
      package com.itheima.domain;
      
      public class User {
          private String name;
          private Integer age;
      
          public User() {
          }
      
          public User(String name, Integer age) {
              this.name = name;
              this.age = age;
          }
      
          /**
           * 獲取
           * @return name
           */
          public String getName() {
              return name;
          }
      
          /**
           * 設(shè)置
           * @param name
           */
          public void setName(String name) {
              this.name = name;
          }
      
          /**
           * 獲取
           * @return age
           */
          public Integer getAge() {
              return age;
          }
      
          /**
           * 設(shè)置
           * @param age
           */
          public void setAge(Integer age) {
              this.age = age;
          }
      
          public String toString() {
              return "User{name = " + name + ", age = " + age + "}";
          }
      }
      
      
      • 控制器
      
          @RequestMapping("/pojoParam")
          @ResponseBody
          public String pojoParam(User user){
              System.out.println("接收到的參數(shù):"+user);
              return "{'BookController':'pojo'}";
          }
      



      只要我們的請(qǐng)求參數(shù)名和我們的domain的屬性名相同,將會(huì)被自動(dòng)封裝成domain對(duì)象

      • 嵌套POJO類型參數(shù)(pojo對(duì)象里面還有引用類型的屬性)
      • User類(里面包含引用類型的屬性Address)
      package com.itheima.domain;
      
      public class User {
          private String name;
          private Integer age;
          private Address address;
      
          public Address getAddress() {
              return address;
          }
      
          public void setAddress(Address address) {
              this.address = address;
          }
      
          public User() {
          }
      
          public User(String name, Integer age) {
              this.name = name;
              this.age = age;
          }
      
          /**
           * 獲取
           * @return name
           */
          public String getName() {
              return name;
          }
      
          /**
           * 設(shè)置
           * @param name
           */
          public void setName(String name) {
              this.name = name;
          }
      
          /**
           * 獲取
           * @return age
           */
          public Integer getAge() {
              return age;
          }
      
          /**
           * 設(shè)置
           * @param age
           */
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      ", address=" + address +
                      '}';
          }
      }
      
      
      • Address
      package com.itheima.domain;
      
      public class Address {
          private String province;
          private String city;
      
          public Address() {
          }
      
          public Address(String province, String city) {
              this.province = province;
              this.city = city;
          }
      
          /**
           * 獲取
           * @return province
           */
          public String getProvince() {
              return province;
          }
      
          /**
           * 設(shè)置
           * @param province
           */
          public void setProvince(String province) {
              this.province = province;
          }
      
          /**
           * 獲取
           * @return city
           */
          public String getCity() {
              return city;
          }
      
          /**
           * 設(shè)置
           * @param city
           */
          public void setCity(String city) {
              this.city = city;
          }
      
          public String toString() {
              return "Address{province = " + province + ", city = " + city + "}";
          }
      }
      
      


      • 數(shù)組類型參數(shù)


      • 集合類型參數(shù)


        因?yàn)樗麑?duì)于引用類型的處理方案是:創(chuàng)建出這個(gè)類型的對(duì)象,然后將請(qǐng)求參數(shù)setter進(jìn)去。(作為屬性)。但是我們現(xiàn)在是想讓請(qǐng)求參數(shù)作為集合的
        值而不是屬性,而且list是接口也沒有構(gòu)造方法



        對(duì)于傳遞參數(shù)總的來說,名稱可以對(duì)應(yīng)上的直接傳遞就可以了,名稱對(duì)應(yīng)不上 是使用@RequestParam綁定一下就可以了

      jason數(shù)據(jù)傳遞參數(shù)(在開發(fā)中大概率使用的是這種方式)


      我們的jason參數(shù)是放在請(qǐng)求體里面發(fā)送的

      • 集合類型
      • 1.添加jason依賴
      <!--jason依賴,實(shí)現(xiàn)將jason數(shù)據(jù)轉(zhuǎn)化成java對(duì)象-->
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-databind</artifactId>
                  <version>2.9.0</version>
              </dependency>
      
      • 2.在postman中編寫jason參數(shù)

        但是此時(shí)我們springmvc還不知道傳遞過來的jason數(shù)據(jù),我們必須開啟一個(gè)功能鍵讓spingmvc幫我們轉(zhuǎn)化jason數(shù)據(jù)

      • 3.開啟轉(zhuǎn)化jason數(shù)據(jù)

      • 4.設(shè)置參數(shù)映射

        此時(shí)我們的jason數(shù)據(jù)就成功封裝到我們的domain中了

      • pojo類型



        好像我們的address的值沒有,因?yàn)槲覀儾]有傳遞address屬性的值

      • 傳遞address的值

      • JSON對(duì)象數(shù)組


      • 注意點(diǎn)


        從目前實(shí)驗(yàn)來看好像發(fā)送jason類型的數(shù)據(jù),在接收端的參數(shù)中都必須加上RequestBody注解才行。對(duì)于非jason參數(shù),
        只有l(wèi)ist集合才需要加上RequestParam注解(因?yàn)槭菍⑺鳛橹担环夏J(rèn)的)

      使用tomcat7-maven-plugin插件簡化tomcat啟動(dòng)

      • 在pom.xml中添加toncat插件
       <build>
              <plugins>
      
                  <plugin>
                      <!--tomcat插件-->
                      <groupId>org.apache.tomcat.maven</groupId>
                      <artifactId>tomcat7-maven-plugin</artifactId>
                      <version>2.2</version>
                      <configuration>
                          <port>80</port><!--設(shè)置項(xiàng)目使用的端口號(hào)(80為http協(xié)議默認(rèn)端口號(hào))將不需要寫端口號(hào)了-->
                          <path>/</path><!--默認(rèn)訪問路徑-->
                      </configuration>
                  </plugin>
              </plugins>
          </build>
      
      • 可以使用下面的步驟快速啟動(dòng)tomcat服務(wù)器

        當(dāng)我們將端口號(hào)設(shè)置成http協(xié)議默認(rèn)端口號(hào)80,我們可以省略工程名和端口號(hào)的書寫

      日期型參數(shù)傳遞


      1.對(duì)于默認(rèn)格式可以直接轉(zhuǎn)化為Date



      2.對(duì)于不是默認(rèn)格式的日期(指定日期格式即可)


      響應(yīng)


      1.響應(yīng)頁面

      但是不知道為什么我的方法可以被訪問到,但是頁面一直無法被顯示

      響應(yīng)頁面問題的解決

      補(bǔ)充配置maven-tomcat插件的快速啟動(dòng)(不是添加模板,是添加新配置)


      2.響應(yīng)文本

      我們前面的測(cè)試返回的都不是jason對(duì)象,都是返回的字符串(只是是jason格式的字符串)
      @ResponseBody注解表示響應(yīng)的是數(shù)據(jù)


      pojo對(duì)象


      對(duì)象數(shù)組



      第三部分內(nèi)容--REST風(fēng)格

      REST風(fēng)格簡介


      • 存在問題



        對(duì)于請(qǐng)求方式有很多種,但是常用的也就是上面提到的4種

      RESTFU入門案例


      package com.itheima.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.bind.annotation.ResponseBody;
      //rext風(fēng)格
      @Controller
      public class UserController {
      @RequestMapping(value = "/users",method = RequestMethod.POST)//表明是保存行為(請(qǐng)求不是post將報(bào)錯(cuò))
      @ResponseBody
          public String save(){
              return "'module':'user save' ";
          }
      
          @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)//表明是刪除行為(請(qǐng)求不是delete將報(bào)錯(cuò))
          @ResponseBody
          public String delete(@PathVariable int id){
              System.out.println("參數(shù)是"+id);
              return "'module':'user delete' ";
          }
          @RequestMapping(value = "/users",method = RequestMethod.PUT)//表明是更新行為(請(qǐng)求不是post將報(bào)錯(cuò))
          @ResponseBody
          public String update(){
              return "'module':'user update' ";
          }
      
          @RequestMapping(value = "/users/{id}",method = RequestMethod.GET)//表明是查詢行為(請(qǐng)求不是delete將報(bào)錯(cuò))
          @ResponseBody
          public String selectById(@PathVariable int id){
              System.out.println("參數(shù)是"+id);
              return "'module':'user select' ";
          }
      
          @RequestMapping(value = "/users",method = RequestMethod.GET)//表明是查詢行為(請(qǐng)求不是delete將報(bào)錯(cuò))
          @ResponseBody
          public String select(){
      
              return "'module':'user select' ";
          }
      }
      
      

      RESTFUL快速開發(fā)

      @RestController //@Controller + ReponseBody
      @RequestMapping("/books")
      public class BookController {
          //@RequestMapping(method = RequestMethod.POST)
          @PostMapping
          public String save(@RequestBody Book book){
              System.out.println("book save..." + book);
              return "{'module':'book save'}";
          }
          //@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
          @DeleteMapping("/{id}")
          public String delete(@PathVariable Integer id){
              System.out.println("book delete..." + id);
              return "{'module':'book delete'}";
          }
      //@RequestMapping(method = RequestMethod.PUT)
      
       /*   名稱 @RestController
          類型 類注解
          位置 基于SpringMVC的RESTful開發(fā)控制器類定義上方
          作用 設(shè)置當(dāng)前控制器類為RESTful風(fēng)格,
          等同于@Controller與@ResponseBody兩個(gè)注解組合功能
          對(duì)于剛才的問題,我們都有對(duì)應(yīng)的解決方案:
          問題1:每個(gè)方法的@RequestMapping注解中都定義了訪問路徑/books,重復(fù)性太高。
          問題2:每個(gè)方法的@RequestMapping注解中都要使用method屬性定義請(qǐng)求方式,重復(fù)性太高。
          問題3:每個(gè)方法響應(yīng)json都需要加上@ResponseBody注解,重復(fù)性太高。
          知識(shí)點(diǎn)1:@RestController
          知識(shí)點(diǎn)2:@GetMapping @PostMapping @PutMapping @DeleteMapping*/
          @PutMapping
          public String update(@RequestBody Book book){
              System.out.println("book update..." + book);
              return "{'module':'book update'}";
          }
          //@RequestMapping(value = "/{id}",method = RequestMethod.GET)
          @GetMapping("/{id}")
          public String getById(@PathVariable Integer id){
              System.out.println("book getById..." + id);
              return "{'module':'book getById'}";
          }
          //@RequestMapping(method = RequestMethod.GET)
          @GetMapping
          public String getAll(){
              System.out.println("book getAll...");
              return "{'module':'book getAll'}";
          }
      }
      
      

      總結(jié)來說是使用了下面新的注解

      案例:基于RESTFUL頁面數(shù)據(jù)交互(后臺(tái)接口的開發(fā))

      package com.itheima.controller;
      
      import com.itheima.domain.Book;
      import org.springframework.web.bind.annotation.*;
      
      import java.util.ArrayList;
      import java.util.List;
      
      @RestController
      @RequestMapping("/books")
      public class BookController {
          //保存圖書
          @PostMapping
          //RequestBody注解表明參數(shù)從請(qǐng)求體重獲取
          public String save(@RequestBody Book book) {
              System.out.println("book-->" + book);
              return "'book':'book' ";
          }
          //查詢所有圖書
          @GetMapping
          public List<Book>getAll(){
              List<Book> list = new ArrayList<Book>();
              Book book1 = new Book();
              book1.setName("紅樓夢(mèng)");
              book1.setType("小說");
              book1.setDescription("一本好書");
              list.add(book1);
              Book book2 = new Book();
              book2.setName("西游記");
              book2.setType("小說");
              book2.setDescription("一本好書");
              list.add(book2);
              return list;
          }
      }
      
      


      案例:基于RESTFUL頁面數(shù)據(jù)交互(頁面訪問處理)

      1.放行非springmvc的請(qǐng)求
      當(dāng)我們直接訪問靜態(tài)頁面的時(shí)候?qū)o法封裝:

      因?yàn)槲覀儧]有在controller中給頁面配置請(qǐng)求地址

      解決方案

      • springMVC需要將靜態(tài)資源進(jìn)行放行。
      package com.itheima.config;
      
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
      
      @Configuration
      public class SpringMvcSupport extends WebMvcConfigurationSupport {
      //設(shè)置靜態(tài)資源訪問過濾,當(dāng)前類需要設(shè)置為配置類,并被掃描加載
      @Override
      protected void addResourceHandlers(ResourceHandlerRegistry registry) {
      //當(dāng)訪問/pages/????時(shí)候,從/pages目錄下查找內(nèi)容
      registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
      registry.addResourceHandler("/js/**").addResourceLocations("/js/");
      registry.addResourceHandler("/css/**").addResourceLocations("/css/");
      registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/")
      ;
      }
      }
      
      • 可以正常訪問了

      ajax請(qǐng)求可以實(shí)現(xiàn)異步發(fā)送請(qǐng)求,局部更新頁面
      下面以ajax請(qǐng)求舉例,前端發(fā)送ajax請(qǐng)求,后臺(tái)返回jason對(duì)象,然后前臺(tái)使用返回的數(shù)據(jù)進(jìn)行頁面的局部更新
      前端不熟悉,故不展開

      第四部分-SSM整合

      ssm-整合配置



      在配置方面好像就是spring將mybatis的配置放在自己配置里面一起加載。springmvc則自己加載。把這2方面放在servletconfig中各自加載

      ssm-功能模塊開發(fā)

      1.創(chuàng)建表并插入數(shù)據(jù)
      CREATE DATABASE ssm
      USE ssm
      CREATE TABLE tbl_book(
      id INT PRIMARY KEY AUTO_INCREMENT,
      TYPE VARCHAR(20),
      NAME VARCHAR(50),
      description VARCHAR(255)
      )

      INSERT INTO tbl_book(id,type,name,description) VALUES (1,'計(jì)算機(jī)理
      論','Spring實(shí)戰(zhàn) 第五版','Spring入門經(jīng)典教程,深入理解Spring原理技術(shù)內(nèi)幕'),(2,'計(jì)算機(jī)理
      論','Spring 5核心原理與30個(gè)類手寫實(shí)踐','十年沉淀之作,手寫Spring精華思想'),(3,'計(jì)算機(jī)理
      論','Spring 5設(shè)計(jì)模式','深入Spring源碼刨析Spring源碼中蘊(yùn)含的10大設(shè)計(jì)模式'),(4,'計(jì)算機(jī)
      理論','Spring MVC+Mybatis開發(fā)從入門到項(xiàng)目實(shí)戰(zhàn)','全方位解析面向Web應(yīng)用的輕量級(jí)框架,帶你
      成為Spring MVC開發(fā)高手'),(5,'計(jì)算機(jī)理論','輕量級(jí)Java Web企業(yè)應(yīng)用實(shí)戰(zhàn)','源碼級(jí)刨析
      Spring框架,適合已掌握J(rèn)ava基礎(chǔ)的讀者'),(6,'計(jì)算機(jī)理論','Java核心技術(shù) 卷Ⅰ 基礎(chǔ)知識(shí)(原書
      第11版)','Core Java第11版,Jolt大獎(jiǎng)獲獎(jiǎng)作品,針對(duì)Java SE9、10、11全面更新'),(7,'計(jì)算
      機(jī)理論','深入理解Java虛擬機(jī)','5個(gè)緯度全面刨析JVM,大廠面試知識(shí)點(diǎn)全覆蓋'),(8,'計(jì)算機(jī)理
      論','Java編程思想(第4版)','Java學(xué)習(xí)必讀經(jīng)典,殿堂級(jí)著作!贏得了全球程序員的廣泛贊譽(yù)'),
      (9,'計(jì)算機(jī)理論','零基礎(chǔ)學(xué)Java(全彩版)','零基礎(chǔ)自學(xué)編程的入門圖書,由淺入深,詳解Java語言
      的編程思想和核心技術(shù)'),(10,'市場(chǎng)營銷','直播就這么做:主播高效溝通實(shí)戰(zhàn)指南','李子柒、李佳
      奇、薇婭成長為網(wǎng)紅的秘密都在書中'),(11,'市場(chǎng)營銷','直播銷講實(shí)戰(zhàn)一本通','和秋葉一起學(xué)系列網(wǎng)
      絡(luò)營銷書籍'),(12,'市場(chǎng)營銷','直播帶貨:淘寶、天貓直播從新手到高手','一本教你如何玩轉(zhuǎn)直播的
      書,10堂課輕松實(shí)現(xiàn)帶貨月入3W+');

      SELECT * FROM tbl_book

      ssm整合--接口測(cè)試

      在開發(fā)中有2個(gè)環(huán)節(jié)需要停下來做測(cè)試:1.當(dāng)持業(yè)務(wù)層(即sevice和dao都寫完的時(shí)候)開發(fā)完成時(shí)需要使用junit做業(yè)務(wù)層接口的測(cè)試2.當(dāng)表現(xiàn)層測(cè)試完成需要使用postman做表現(xiàn)層接口的測(cè)試
      注意正規(guī)的junit測(cè)試還需要做斷言和匹配

      • 1.測(cè)試業(yè)務(wù)層
      • 2.測(cè)試表現(xiàn)層
      • 3.配置事務(wù)
        傳播行為等書寫,先不要配置看具體需求
      • ssm整合全套代碼
        建表語句看前面
      • config
      • jdbcconfig
      package com.itheima.config;
      
      import com.alibaba.druid.pool.DruidDataSource;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.jdbc.datasource.DataSourceTransactionManager;
      import org.springframework.transaction.PlatformTransactionManager;
      
      import javax.sql.DataSource;
      
      public class JdbcConfig {
          @Value("${jdbc.driver}")
          private String driver;
          @Value("${jdbc.url}")
          private String url;
          @Value("${jdbc.username}")
          private String username;
          @Value("${jdbc.password}")
          private String password;
          @Bean
          public DataSource getDataSource() {
              DruidDataSource dataSource = new DruidDataSource();
              dataSource.setDriverClassName(driver);
              dataSource.setUsername(username);
              dataSource.setPassword(password);
              dataSource.setUrl(url);
              return dataSource;
          }
          //配置事務(wù)管理器
          @Bean
          public PlatformTransactionManager getTransactionManager(DataSource dataSource){
              DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
              transactionManager.setDataSource(dataSource);//配置數(shù)據(jù)源
              return transactionManager;
          }
      }
      
      
      • mybatisconfig
      package com.itheima.config;
      
      import org.mybatis.spring.SqlSessionFactoryBean;
      import org.mybatis.spring.mapper.MapperScannerConfigurer;
      import org.springframework.context.annotation.Bean;
      
      import javax.sql.DataSource;
      
      public class MyBatisConfig {
          //將sqlSessionFactory交給spring
          @Bean
          public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){
              SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
              factoryBean.setDataSource(dataSource);//設(shè)置數(shù)據(jù)源
              factoryBean.setTypeAliasesPackage("com.itheima.domain");//設(shè)置別名
              return factoryBean;
          }
          //映射器
          @Bean
          public MapperScannerConfigurer getMapperScannerConfigurer(){
              MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
              mapperScannerConfigurer.setBasePackage("com.itheima.dao");//將dao包的路徑作為映射路徑
              return mapperScannerConfigurer;
          }
      }
      
      
      • servletconfig
      package com.itheima.config;
      
      
      import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
      
      //web容器配置類
      public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
          @Override
          protected Class<?>[] getRootConfigClasses() {
              return new Class[]{SpringConfig.class};
          }
      
          @Override
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
          @Override
          protected String[] getServletMappings() {
              return new String[]{"/"};//將該路徑的請(qǐng)求都交給springmvc
          }
      }
      
      
      • springconfig
      package com.itheima.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Import;
      import org.springframework.context.annotation.PropertySource;
      import org.springframework.transaction.annotation.EnableTransactionManagement;
      
      @Configuration
      @ComponentScan("com.itheima.service")//組件掃描
      @PropertySource("classpath:jdbc.properties")//導(dǎo)入配置文件
      @EnableTransactionManagement//開啟事務(wù)管理
      @Import({JdbcConfig.class,MyBatisConfig.class})//導(dǎo)入其他配置類
      public class SpringConfig {
      }
      
      
      • springmvcconfig
      package com.itheima.config;
      
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.EnableWebMvc;
      
      @Configuration
      @ComponentScan("com.itheima.controller")
      @EnableWebMvc//開啟web相關(guān)的功能
      public class SpringMvcConfig {
      }
      
      
      • bookcontroller
      package com.itheima.controller;
      import com.itheima.domain.Book;
      import com.itheima.service.BookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;
      
      import java.util.List;
      
      @RestController
      @RequestMapping("/books")
      public class BookController {
          @Autowired
          private BookService bookService;
          @PostMapping
          public boolean save(@RequestBody Book book) {
              System.out.println("保存的圖書信息:"+book);
              return bookService.save(book);
          }
          @PutMapping
          public boolean update(@RequestBody Book book) {
              return bookService.update(book);
          }
          @DeleteMapping("/{id}")
          public boolean delete(@PathVariable Integer id) {
              return bookService.delete(id);
          }
          @GetMapping("/{id}")
          public Book getById(@PathVariable Integer id) {
              return bookService.getById(id);
          }
          @GetMapping
      
          public List<Book> getAll() {
              return bookService.getAll();
          }
      }
      
      
      • bookdao
      package com.itheima.dao;
      
      import com.itheima.domain.Book;
      import org.apache.ibatis.annotations.Delete;
      import org.apache.ibatis.annotations.Insert;
      import org.apache.ibatis.annotations.Select;
      import org.apache.ibatis.annotations.Update;
      
      import java.util.List;
      
      public interface BookDao {
          @Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
          public void save(Book book);
      
          @Update("update tbl_book set type=#{type},name=#{name},description=#{description} where id=#{id}")
          public void update(Book book);
      
          @Delete("delete from tbl_book where id=#{id}")
          public void delete(Integer id);
      
          @Select("select * from tbl_book where id=#{id}")
          public Book getById(Integer id);
      
          @Select("select * from tbl_book")
          public List<Book> getAll();
      
      }
      
      
      • book
      package com.itheima.domain;
      
      public class Book {
          private Integer id;
          private String type;
          private String name;
          private String description;
      
          public Book() {
          }
      
          public Book(Integer id, String type, String name, String description) {
              this.id = id;
              this.type = type;
              this.name = name;
              this.description = description;
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設(shè)置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return type
           */
          public String getType() {
              return type;
          }
      
          /**
           * 設(shè)置
           * @param type
           */
          public void setType(String type) {
              this.type = type;
          }
      
          /**
           * 獲取
           * @return name
           */
          public String getName() {
              return name;
          }
      
          /**
           * 設(shè)置
           * @param name
           */
          public void setName(String name) {
              this.name = name;
          }
      
          /**
           * 獲取
           * @return description
           */
          public String getDescription() {
              return description;
          }
      
          /**
           * 設(shè)置
           * @param description
           */
          public void setDescription(String description) {
              this.description = description;
          }
      
          public String toString() {
              return "Book{id = " + id + ", type = " + type + ", name = " + name + ", description = " + description + "}";
          }
      }
      
      
      • bookservice
      package com.itheima.service;
      
      import com.itheima.domain.Book;
      import org.apache.ibatis.annotations.Delete;
      import org.apache.ibatis.annotations.Insert;
      import org.apache.ibatis.annotations.Select;
      import org.apache.ibatis.annotations.Update;
      import org.springframework.transaction.annotation.Transactional;
      
      import java.util.List;
      /*
      1.一般業(yè)務(wù)層方法名和持久層不同(需要一眼就知道是什么業(yè)務(wù)
      2.業(yè)務(wù)層刪除修改保存方法一般返回boolean)
      * */
      @Transactional//給所有的業(yè)務(wù)方法加上事務(wù)
      public interface BookService {
          public boolean save(Book book);
      
          public boolean update(Book book);
      
          public boolean delete(Integer id);
      
          public Book getById(Integer id);
      
          public List<Book> getAll();
      }
      
      
      • bookserviceimpl
      package com.itheima.service.impl;
      
      import com.itheima.dao.BookDao;
      import com.itheima.domain.Book;
      import com.itheima.service.BookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      import java.util.List;
      @Service
      public class BookServiceImpl implements BookService {
          @Autowired
          private BookDao bookDao;
      
          public boolean save(Book book) {
              bookDao.save(book);
              return true;
          }
      
          public boolean update(Book book) {
              bookDao.update(book);
              return true;
          }
      
          public boolean delete(Integer id) {
              bookDao.delete(id);
              return true;
          }
      
          public Book getById(Integer id) {
              return bookDao.getById(id);
          }
      
          public List<Book> getAll() {
              return bookDao.getAll();
          }
      }
      
      

      表現(xiàn)層與前端數(shù)據(jù)傳輸協(xié)議的定義


      前端將無法區(qū)分哪個(gè)是直接可以使用的數(shù)據(jù)

      • 但是可能還是存在下面問題

      • 最終的骨架
      • 封裝模型如下

      表現(xiàn)層與前端數(shù)據(jù)傳輸協(xié)議的實(shí)現(xiàn)

      我們需要定義的數(shù)據(jù)結(jié)果模型應(yīng)該是給表現(xiàn)層使用的,所以我們一般把result類放在controller包中
      在這個(gè)實(shí)現(xiàn)中,我們?cè)诓樵冎形覀儗⒎祷豱ull設(shè)置為查詢失敗,將返回非null設(shè)置為查詢成功(并不是表示代碼異常錯(cuò)誤的失敗)

      其實(shí)就是和前端通信的協(xié)議

      • 數(shù)據(jù)結(jié)果封裝類
      package com.itheima.controller;
      //數(shù)據(jù)結(jié)構(gòu)封裝模型
      public class Result {
          private Object data;//數(shù)據(jù)
          private Integer code;//狀態(tài)碼
          private String msg;//特殊信息
      //提供多種形式的構(gòu)造方法以方便我們使用
          public Result() {
          }
      
          public Result( Integer code,Object data) {
              this.data = data;
              this.code = code;
          }
      
          public Result(Integer code,Object data,  String msg) {
              this.data = data;
              this.code = code;
              this.msg = msg;
          }
      
          /**
           * 獲取
           * @return data
           */
          public Object getData() {
              return data;
          }
      
          /**
           * 設(shè)置
           * @param data
           */
          public void setData(Object data) {
              this.data = data;
          }
      
          /**
           * 獲取
           * @return code
           */
          public Integer getCode() {
              return code;
          }
      
          /**
           * 設(shè)置
           * @param code
           */
          public void setCode(Integer code) {
              this.code = code;
          }
      
          /**
           * 獲取
           * @return msg
           */
          public String getMsg() {
              return msg;
          }
      
          /**
           * 設(shè)置
           * @param msg
           */
          public void setMsg(String msg) {
              this.msg = msg;
          }
      
          public String toString() {
              return "Result{data = " + data + ", code = " + code + ", msg = " + msg + "}";
          }
      }
      
      
      package com.itheima.controller;
      //狀態(tài)碼類
      public class Code {
          public static final Integer SAVE_OK=20011;
          public static final Integer DELETE_OK=20021;
          public static final Integer UPDATE_OK=20031;
          public static final Integer GET_OK=20041;
      
      
          public static final Integer SAVE_ERR=20010;
          public static final Integer DELETE_ERR=20020;
          public static final Integer UPDATE_ERR=20030;
          public static final Integer GET_ERR=20040;
      
      }
      
      
      • 修改后的控制器類
      package com.itheima.controller;
      import com.itheima.domain.Book;
      import com.itheima.service.BookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;
      
      import java.util.List;
      
      @RestController
      @RequestMapping("/books")
      public class BookController {
          @Autowired
          private BookService bookService;
          @PostMapping
          public Result save(@RequestBody Book book) {
              final boolean flag = bookService.save(book);
              return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag);
          }
          @PutMapping
          public Result update(@RequestBody Book book) {
              final boolean flag = bookService.update(book);
              return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
          }
          @DeleteMapping("/{id}")
          public Result delete(@PathVariable Integer id) {
              final boolean flag = bookService.delete(id);
              return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);    }
          @GetMapping("/{id}")
          public Result getById(@PathVariable Integer id) {
              final Book book = bookService.getById(id);
             Integer code = book!=null?Code.GET_OK:Code.GET_ERR;
             String msg = book!=null?"":"查詢失敗";//對(duì)于查詢成功的msg可以隨便寫,前端不會(huì)去使用
              return new Result(code,book,msg);
          }
          @GetMapping
      
          public Result getAll() {
              final List<Book> bookList = bookService.getAll();
              Integer code = bookList!=null?Code.GET_OK:Code.GET_ERR;
              String msg = bookList!=null?"":"查詢失敗";//對(duì)于查詢成功的msg可以隨便寫,前端不會(huì)去使用
              return new Result(code,bookList,msg);
          }
      }
      
      

      ssm整合-異常處理器

      • 當(dāng)我們程序出現(xiàn)異常時(shí)-返回的前端的是什么呢?


      • 分析異常



        總結(jié)異常處理
      • 1.異常需要分類處理
      • 2.異常需要放在表現(xiàn)層處理
      • 3.異常需要使用AOP的思想處理
        我們不需要自己寫AOP,spring給我們提供了建議方法--異常處理器
      • 該節(jié)代碼基于前面的代碼
        我們的異常處理器是集中處理controller中的異常的,所以寫在contaroller包中比較好
      • 異常處理器類
      package com.itheima.controller;
      
      import org.springframework.web.bind.annotation.ExceptionHandler;
      import org.springframework.web.bind.annotation.RestControllerAdvice;
      
      //異常處理器
      @RestControllerAdvice//用于處理rest風(fēng)格開發(fā)的controller
      public class ProjectExceptionAdvice {
          @ExceptionHandler(Exception.class)//定義該方法用來處理哪一種異常
          public Result doException(Exception e){
      
              //此時(shí)還沒有設(shè)置異常的相關(guān)狀態(tài)碼(僅僅示意)
         return   new Result(666,null);//將異常包裝成結(jié)果返回給前端
          }
      
      }
      
      

      • 總結(jié)



      這時(shí)候我們正常情況和異常情況下都可以返回給前端統(tǒng)一的數(shù)據(jù),有利協(xié)調(diào)了前后的開發(fā)

      ssm整合--項(xiàng)目異常處理

      • 我們?cè)陧?xiàng)目中的異常處理



      • 完成處理方案的代碼編寫
      • 1.定義異常編碼

        2.我們需要自定義系統(tǒng)異常和業(yè)務(wù)異常
      package com.itheima.exception;
      
      public class BusinessException extends RuntimeException{
          private Integer code;
      
          public Integer getCode() {
              return code;
          }
      
          public BusinessException(Integer code, String message ) {
              super(message);
              this.code = code;
          }
      
          public BusinessException(Integer code, String message, Throwable cause) {
              super(message, cause);
              this.code = code;
          }
      
      
      
      }
      
      
      package com.itheima.exception;
      
      public class SystemException extends RuntimeException{
          private Integer code;
      
          public Integer getCode() {
              return code;
          }
      
          public SystemException(Integer code, String message ) {
              super(message);
              this.code = code;
          }
      
          public SystemException( Integer code,String message, Throwable cause) {
              super(message, cause);
              this.code = code;
          }
      
      
      
      }
      
      
      • 3.在controller中模擬出業(yè)務(wù)異常和系統(tǒng)異常
      @GetMapping("/{id}")
          public Result getById(@PathVariable Integer id) {
              //模擬業(yè)務(wù)異常
              if(id!=1){
                  throw new BusinessException(Code.BUSINESS_ERR,"請(qǐng)不要使用你的技術(shù)挑戰(zhàn)我們的耐性");
              }
              final Book book = bookService.getById(id);
              //模擬系統(tǒng)異常
              try {
                  int a=2/0;
              } catch (Exception e) {
                  //將出現(xiàn)的異常封裝成系統(tǒng)異常
                 throw new  SystemException(Code.SYSTEM_ERR,"服務(wù)區(qū)超時(shí),請(qǐng)重試",e);
              }
              Integer code = book!=null?Code.GET_OK:Code.GET_ERR;
             String msg = book!=null?"":"查詢失敗";//對(duì)于查詢成功的msg可以隨便寫,前端不會(huì)去使用
              return new Result(code,book,msg);
          }
      
      • 4.編寫不同種類的異常處理器
      package com.itheima.controller;
      
      import com.itheima.exception.BusinessException;
      import com.itheima.exception.SystemException;
      import org.springframework.web.bind.annotation.ExceptionHandler;
      import org.springframework.web.bind.annotation.RestControllerAdvice;
      
      //異常處理器
      @RestControllerAdvice//用于處理rest風(fēng)格開發(fā)的controller
      public class ProjectExceptionAdvice {
          //處理系統(tǒng)異常
          @ExceptionHandler(SystemException.class)//定義處理系統(tǒng)異常
          public Result doSystemException(SystemException e){
           //1.記錄日志
              // 2.發(fā)送消息給運(yùn)維
              //3.發(fā)送郵件給開發(fā)人員(將e這個(gè)對(duì)象發(fā)送給開發(fā)人員)
      
              //code和massage通過異常對(duì)象傳遞過來了
         return   new Result(e.getCode(),null,e.getMessage());//將異常包裝成結(jié)果返回給前端
          }
          //處理業(yè)務(wù)異常
          @ExceptionHandler(BusinessException.class)//定義處理系統(tǒng)異常
          public Result doBusinessSystemException(BusinessException e){
              //code和massage通過異常對(duì)象傳遞過來了
              return   new Result(e.getCode(),null,e.getMessage());//將異常包裝成結(jié)果返回給前端
          }
          //處理其他異常
          @ExceptionHandler(Exception.class)
          public Result doException(Exception e){
              //1.記錄日志
              // 2.發(fā)送消息給運(yùn)維
              //3.發(fā)送郵件給開發(fā)人員(將e這個(gè)對(duì)象發(fā)送給開發(fā)人員)
              //code和massage通過異常對(duì)象傳遞過來了
              return   new Result(Code.SYSTEM_UNKNOW_ERR,null,"系統(tǒng)繁忙,請(qǐng)稍后再試");//將異常包裝成結(jié)果返回給前端
          }
      }
      
      
      • 注意

        對(duì)于異常的封裝我們可以使用AOP來完成

      前后端協(xié)議聯(lián)調(diào)--列表查詢功能

      1.給直接訪問頁面的請(qǐng)求放行

      • 前端頁面發(fā)送

      前后端協(xié)議聯(lián)調(diào)(添加功能)

      • 1.彈出添加窗口


      前后端協(xié)議聯(lián)調(diào)(添加功能狀態(tài)處理)


      在已有的代碼中,我們的程序只可能是添加成功的

      修改:我們可以根據(jù)dao層中函數(shù)的返回值(收到影響的行數(shù))來判斷是否執(zhí)行成功,進(jìn)而通過這個(gè)決定servcie層的返回值

      • 我們現(xiàn)在實(shí)驗(yàn)添加失敗的情況

        但是我們點(diǎn)擊后,并沒有出現(xiàn)添加失敗的提示框
      • 我們?cè)诳刂婆_(tái)中刪除后臺(tái)返回的數(shù)據(jù):

      • 這里我們就把這個(gè)異常當(dāng)成是其他異常處理把
      • 一個(gè)小問題

      前后端協(xié)議聯(lián)調(diào)(修改功能)

      1.在修改編輯框中顯示修改前的元數(shù)據(jù)

      2.執(zhí)行更新操作

      前后端協(xié)議聯(lián)調(diào)(刪除功能)


      ssm整合標(biāo)準(zhǔn)總結(jié)


      第五部分:攔截器

      攔截器簡介




      攔截器入門案例


      建議將攔截器類下載controller中,因?yàn)閿r截器都是給表現(xiàn)層用的





      我們修改一下攔截器的配置,讓他可以攔截更多的東西

      • 注意

      攔截器配置的簡化

      我們可以將support類中的攔截器配置和靜態(tài)資源訪問放行的配置都放在springmvcconfig中配置,以后就不用寫support類了。
      但是感覺會(huì)造成springmvc類冗余,個(gè)人不建議這么做

      • 2種方式(有無使用攔截器)執(zhí)行流程在分析

      攔截器參數(shù)

      應(yīng)用的比較多是preHandle中的參數(shù)

      public class ProjectInterceptor implements HandlerInterceptor {
      
      //原始方法調(diào)用前執(zhí)行的內(nèi)容
          public boolean preHandle(HttpServletRequest request, HttpServletResponse
                  response, Object handler) throws Exception {
      
              final String header = request.getHeader("User-Agent");
              System.out.println("header:"+header);
              System.out.println("preHandle...");//1.獲取請(qǐng)求相關(guān)的信息
              //handler(真實(shí)類型:HandlerMethod)對(duì)象封裝了我們正在執(zhí)行的方法
              HandlerMethod hm = (HandlerMethod) handler;//強(qiáng)轉(zhuǎn)成真實(shí)類型
              final Method method = hm.getMethod();//2.此時(shí)可以得到我們需求執(zhí)行的方法
              System.out.println(method);
              //可以在該方法中做校驗(yàn),以確定該方法是返回true還是false
              return true;
          }
      
      //原始方法調(diào)用后執(zhí)行的內(nèi)容
          public void postHandle(HttpServletRequest request, HttpServletResponse
                  response, Object handler, ModelAndView modelAndView) throws Exception {
              System.out.println("postHandle...");
              //ModelAndView類封裝了進(jìn)行頁面跳轉(zhuǎn)的一些數(shù)據(jù)
          }
      
      //原始方法調(diào)用完成后執(zhí)行的內(nèi)容
          public void afterCompletion(HttpServletRequest request,
                                      HttpServletResponse response, Object handler, Exception ex) throws Exception
          {
              //ex中可以拿到原始程序執(zhí)行過程中拋出的異常
              System.out.println("afterCompletion...");
          }
      

      handle對(duì)象是對(duì)原始執(zhí)行方法的封裝,如果得到了handle對(duì)象,就可以對(duì)原始方法進(jìn)行操作了

      攔截器鏈配置



      • 我們將第一個(gè)攔截器的pre返回值改為fasle


        但是在實(shí)際開發(fā)中,攔截器配置一個(gè)就可以了。配置攔截器鏈的情況還是很少的
      posted @ 2024-01-01 15:21  一往而深,  閱讀(52)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产360激情盗摄全集| 国产日韩一区二区在线| 天堂а√在线最新版中文在线| 亚洲无人区一区二区三区| 成年女人免费毛片视频永久| 国产日韩综合av在线| 久久天堂无码av网站| 无码毛片一区二区本码视频| 欧美成人aaa片一区国产精品| 一级女性全黄久久片免费| 亚洲最大成人在线播放| 妓院一钑片免看黄大片| 图片区 小说区 区 亚洲五月 | 国内精品一区二区不卡| 蜜臀av午夜精品福利| 中文字幕在线亚洲日韩6页| 竹溪县| 国产精品午夜福利片国产| 性色欲情网站iwww九文堂| 国产精品亚洲а∨天堂2021| 成人区人妻精品一区二蜜臀| 亚洲欧美高清在线精品一区二区| 人人澡人人透人人爽| 无码av永久免费专区麻豆| 亚洲五月天一区二区三区| 国产成人无码AV片在线观看不卡| 亚洲精品美女一区二区| 粉嫩av一区二区三区蜜臀| 无码国产偷倩在线播放老年人| 精品视频福利| 日本不卡码一区二区三区| 国产一码二码三码区别| 国产欧美另类精品久久久 | 精品无码久久久久久尤物| 欧美人与性动交ccoo| 国产在线精品一区二区三区不卡| 午夜毛片不卡免费观看视频| 色偷偷亚洲男人的天堂| 人妻精品无码一区二区三区 | 国产av无码专区亚洲av软件| 无码中文字幕av免费放|