Spring MVC学习随笔-第一个Spring MVC程序(父子项目结构、Tomcat配置、Vie ...

水军大提督  金牌会员 | 2024-1-12 04:06:06 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 891|帖子 891|积分 2673

学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅
第二章、第一个SpringMVC程序的开发

2.1开发版本


  • JDK1.8+
  • Maven3.6+
  • IDEA2021+
  • SpringFramework 5.1.4
  • Tomcat8.5.29
  • MySQL5.7.18
按照父子项目的结构,管理和创建项目,创建一个空Project作为父项目,pom文件如下
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>com.baizhi</groupId>
  7.     <artifactId>baizhi-mvc-parent</artifactId>
  8.     <packaging>pom</packaging>
  9.     <version>1.0-SNAPSHOT</version>
  10.     <modules>
  11.         <module>baizhi-mvc-01</module>
  12.     </modules>
  13.     <properties>
  14.         <maven.compiler.source>8</maven.compiler.source>
  15.         <maven.compiler.target>8</maven.compiler.target>
  16.     </properties>
  17. </project>
复制代码
创建子项目Module:

子项目pom文件:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.     <parent>
  4.         <artifactId>baizhi-mvc-parent</artifactId>
  5.         <groupId>com.baizhi</groupId>
  6.         <version>1.0-SNAPSHOT</version>
  7.     </parent>
  8.     <modelVersion>4.0.0</modelVersion>
  9.     <artifactId>baizhi-mvc-01</artifactId>
  10.     <packaging>war</packaging>
复制代码
注意:初次创建web项目时,WEB-INF包下的web.xml引入的servlet规范的版本还是2.3,而我们使用的tomcat8至少需要3.0以上的规范,所以需要修复,删除此文件后在Project Settings设置,如图:

Tomcat配置


2.2 环境搭建

2.2.1 引入相关jar
  1. <dependencies>
  2.     <dependency>
  3.         <groupId>org.springframework</groupId>
  4.         <artifactId>spring-webmvc</artifactId>
  5.         <version>5.3.27</version>
  6.     </dependency>
  7.     <dependency>
  8.         <groupId>javax.servlet</groupId>
  9.         <artifactId>javax.servlet-api</artifactId>
  10.         <version>3.1.0</version>
  11.     </dependency>
  12.     <dependency>
  13.         <groupId>javax.servlet</groupId>
  14.         <artifactId>jstl</artifactId>
  15.         <version>1.2</version>
  16.     </dependency>
  17.     <dependency>
  18.         <groupId>javax.servlet.jsp</groupId>
  19.         <artifactId>javax.servlet.jsp-api</artifactId>
  20.         <version>2.3.1</version>
  21.     </dependency>
  22.     <dependency>
  23.         <groupId>org.springframework</groupId>
  24.         <artifactId>spring-web</artifactId>
  25.         <version>5.3.27</version>
  26.     </dependency>
  27.     <dependency>
  28.         <groupId>org.springframework</groupId>
  29.         <artifactId>spring-core</artifactId>
  30.         <version>5.3.27</version>
  31.     </dependency>
  32.     <dependency>
  33.         <groupId>org.springframework</groupId>
  34.         <artifactId>spring-beans</artifactId>
  35.         <version>5.3.27</version>
  36.     </dependency>
  37.     <dependency>
  38.         <groupId>org.springframework</groupId>
  39.         <artifactId>spring-test</artifactId>
  40.         <version>5.3.27</version>
  41.     </dependency>
  42.     <dependency>
  43.         <groupId>org.springframework</groupId>
  44.         <artifactId>spring-tx</artifactId>
  45.         <version>5.3.27</version>
  46.     </dependency>
  47.     <dependency>
  48.         <groupId>org.springframework</groupId>
  49.         <artifactId>spring-jdbc</artifactId>
  50.         <version>5.3.27</version>
  51.     </dependency>
  52.     <dependency>
  53.         <groupId>org.mybatis</groupId>
  54.         <artifactId>mybatis-spring</artifactId>
  55.         <version>2.1.1</version>
  56.     </dependency>
  57.     <dependency>
  58.         <groupId>com.alibaba</groupId>
  59.         <artifactId>druid</artifactId>
  60.         <version>1.1.19</version>
  61.     </dependency>
  62.     <dependency>
  63.         <groupId>mysql</groupId>
  64.         <artifactId>mysql-connector-java</artifactId>
  65.         <version>5.1.47</version>
  66.     </dependency>
  67.     <dependency>
  68.         <groupId>org.mybatis</groupId>
  69.         <artifactId>mybatis</artifactId>
  70.         <version>3.5.13</version>
  71.     </dependency>
  72.     <dependency>
  73.         <groupId>junit</groupId>
  74.         <artifactId>junit</artifactId>
  75.         <version>4.11</version>
  76.         <scope>test</scope>
  77.     </dependency>
  78.     <dependency>
  79.         <groupId>org.springframework</groupId>
  80.         <artifactId>spring-context</artifactId>
  81.         <version>5.3.27</version>
  82.     </dependency>
  83.     <dependency>
  84.         <groupId>org.springframework</groupId>
  85.         <artifactId>spring-aop</artifactId>
  86.         <version>5.3.27</version>
  87.     </dependency>
  88.     <dependency>
  89.         <groupId>org.aspectj</groupId>
  90.         <artifactId>aspectjrt</artifactId>
  91.         <version>1.8.8</version>
  92.     </dependency>
  93.     <dependency>
  94.         <groupId>org.aspectj</groupId>
  95.         <artifactId>aspectjweaver</artifactId>
  96.         <version>1.8.3</version>
  97.     </dependency>
  98.     <dependency>
  99.         <groupId>org.slf4j</groupId>
  100.         <artifactId>slf4j-api</artifactId>
  101.         <version>1.7.36</version>
  102.     </dependency>
  103.     <dependency>
  104.         <groupId>ch.qos.logback</groupId>
  105.         <artifactId>logback-classic</artifactId>
  106.         <version>1.2.12</version>
  107.     </dependency>
  108.     <dependency>
  109.         <groupId>ch.qos.logback</groupId>
  110.         <artifactId>logback-core</artifactId>
  111.         <version>1.2.12</version>
  112.     </dependency>
  113.     <dependency>
  114.         <groupId>org.logback-extensions</groupId>
  115.         <artifactId>logback-ext-spring</artifactId>
  116.         <version>0.1.5</version>
  117.     </dependency>
  118.     <dependency>
  119.         <groupId>org.yaml</groupId>
  120.         <artifactId>snakeyaml</artifactId>
  121.         <version>1.30</version>
  122.     </dependency>
  123. </dependencies>
复制代码
注意:SpringMVC比前面所学习的Spring,就多引入了一个jar包,叫做spring-webmvc.jar
2.2.2 配置文件

SpringMVC的配置文件,就是Spring的配置文件
注意事项:

  • 名字可以随便命名,本次课程取名dispatcher.xml
  • 放置路径可以根据需要,随意放置,本次课程放置在资源文件夹的根下.
2.2.3 初始化配置


  • web.xml
  1. <servlet>
  2.     <servlet-name>dispatcherServlet</servlet-name>
  3.    
  4.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  5.    
  6.     <init-param>
  7.         <param-name>contextConfigLocation</param-name>
  8.         <param-value>classpath:dispatcher.xml</param-value>
  9.     </init-param>
  10.    
  11.     <load-on-startup>1</load-on-startup>
  12. </servlet>
  13. <servlet-mapping>
  14.     <servlet-name>dispatcherServlet</servlet-name>
  15.     <url-pattern>/</url-pattern>
  16. </servlet-mapping>
复制代码

  • DispatcherServlet称为前端控制器(中央控制器)
  • DispatcherServlet的核心作用:

    • 用于创建Spring的工厂(容器)
      等效于:ApplicationContext ctx = new ClassPathXmlApplicationContext(”dispatcher.xml”);
      因为DispatcherServlet封装的Spring工厂只能读取xml,所以无法迁移到纯注解编程
    • 控制SpringMVC内部的运行流程

SpringMVC的配置文件dispatcher.xml
  1.     <context:component-scan base-package="com.baizhi"/>
  2.    
  3.     <mvc:annotation-driven/>
复制代码

mvc:annotaion-driven这段配置的主要作用:引入SpringMVC的核心功能
主要引入了2个核心类型:1.RequestMappingHandlerMapping 2.RequestMappingHandlerAdapter

  • RequestMappingHandlerMapping实现了HandlerMapping接口
    它会处理@RequestMapping注解,并将其注册到请求映射表中
  • RequestMappingHandlerAdapter实现了 HandlerAdapter接口
    它是处理请求的适配器,确定调用某个符合要求的控制器类中具体服务的方法
SpringMVC对mvc:annotaion-driven的封装

context:component-scan

  • 进行注解扫描
  • DispatcherServlet所创建的工厂需要读取XML的配置文件,不能使用纯注解的开发。所以目前使用Spring配置文件+基础注解的形式,进行开发
    基础注解可以用Component @Service @Repository,@Controller,@Scope,@Transsactional等
    高级注解无效:@Configuration,@Bean,@ComponentScan
2.3编程思路

2.3.1 思路分析


基本流程

  • 开发一个类在上面加入@Controller注解
  • 提供一个控制器方法:参数是HttpServletRequest,HttpServletResponse,返回值是String的,同时加入@RequestMapping注解定义请求路径
  • 在控制方法中,完成核心开发功能,把对应JSP页面的路径,作为方法的返回值返回
2.3.2 编码
  1. @Controller
  2. public class FirstController {
  3.     @RequestMapping("/first")
  4.     public String first(HttpServletRequest request, HttpServletResponse response) {
  5.         System.out.println("FirstController.first");
  6.         return "/result.jsp";
  7.     }
  8. }
  9. 必须要进行@Controller注解的扫描,配置文件中:<context:component-scan base-package="com.baizhi"/>
复制代码
2.3.3 一个控制器中,提供多个服务方法


  • Servlet作为控制器,一个类中只能提供一个服务方法
    在原来的Servlet开发中,明确控制器的方法必须实现接口规定的service(HttpServletRequest request, HttpServletResponse response)方法,一个类中只能实现一次,所以一个类中只能有一个服务方法

  • SpringMVC的控制器,一个类中可以提供多个对外服务的方法

    • SpringMVC控制器,没有对于方法名的限制,所以可以提供多个服务方法
      1. http://localhost:8989/basic/first
      2. http://localhost:8989/basic/second
      3. @Controller
      4. public class FirstController {
      5.     @RequestMapping("/first")
      6.     public String first(HttpServletRequest request, HttpServletResponse response) {
      7.         System.out.println("FirstController.first");
      8.         return "/result.jsp";
      9.     }
      10.     @RequestMapping(value="/second")
      11.     public String second(HttpServletRequest request, HttpServletResponse response) {
      12.         System.out.println("FirstController.second");
      13.         return "/result.jsp";
      14.     }
      15. }
      复制代码

2.3.4 注意

SpringMVC中我们开发的Controller,也称之为Handler(SpringMVC内部的叫法)
2.4 第一个程序的细节分析

2.4.1 一种类型的SpringMVC控制器被创建几次?


  • 回顾:Servlet控制器被创建的次数
    一种类型的Servlet,只会被Tomcat创建一次,所以Servlet是单实例。
  • Servlet是单实例并不是单例设计模式
  • SpringMVC的控制器被Spring创建的次数
    控制器创建的次数,是由@Scope注解决定的,可以是一次也可以是多次
  • 默认情况下SpringMVC的控制器只会被创建一次,会存在线程安全的问题
2.4.2@RequestMapping注解

核心作用:为控制器方法提供外部访问的url路径
http://localhost:8989/basic/first
@RequestMappring(”/first”)
public String first(HttpServletRequest request, HttpServletResponse response)

  • 路径分隔符 /可以省略
    1. @RequestMapping(value="suns/second")
    2. public String second(HttpServletRequest request, HttpServletResponse response) {
    3.     System.out.println("FirstController.second");
    4.     return "/result.jsp";
    5. }
    6. # 注意 多级目录开头可以不写/
    复制代码
  • 在一个控制器方法上映射多个路径
    1. @Controller
    2. public class FirstController {
    3.     @RequestMapping(**value={"first","third"}**)
    4.     public String first(HttpServletRequest request, HttpServletResponse response) {
    5.         System.out.println("FirstController.first");
    6.         return "/result.jsp";
    7.     }
    8. }
    复制代码
  • Controller类上加入@RequestMapping注解
    1. http://localhost:8989/basic/user/first
    2. http://localhost:8989/basic/user/second
    3. @Controller
    4. @RequestMapping("/user")
    5. public class FirstController {
    6.     @RequestMapping("/addUser")
    7.     public String addUser(HttpServletRequest request, HttpServletResponse response) {
    8.         System.out.println("FirstController.addUser");
    9.         return "/result.jsp";
    10.     }
    11.     @RequestMapping(value="/deleteUser")
    12.     public String deleteUser(HttpServletRequest request, HttpServletResponse response) {
    13.                 System.out.println("FirstController.deleteUser");
    14.         return "/result.jsp";
    15.     }
    16. }
    复制代码
设计目的

满足单一职能原则,可以更好的按照功能,进行不同模块的区分,有利于项目的管理。

  • @RequestMapping限定用户的请求方式

    • 请求方式

      • 所谓请求方式指的就是Web开发中的 POST请求与GET请求
        回顾:Web开发中的POST请求与GET请求的区别
      两种请求提交数据的区别

      • GET请求:通过请求行(地址栏)提交数据(QueryString),明文数据提交,不安全,提交的数据量小(不超过2048字节)
      • POST请求:通过请求体提交数据,密文提交(不是加密,指的是一般用户不可见),相对安全,提交数据量大(理论上没有限制)


两种请求发起方式的区别


  • RequestMapping如何限定用户的请求方式

    • 默认情况下:@RequestMapping注解接受所有请求方式的访问(Post、Get、…
    • 通过@RequestMapping的参数可以限定某个控制器方法只接受特定的请求方式
      @RequestMapping(value = "/m1",method = {RequestMethod.POST})
    • 可以同时限定多种请求方式的访问
      @RequestMapping(value = "/m1",method = {RequestMethod.POST,RequestMethod.GET})
    • 当用户发起了@RequestMapping不支持的请求操作
      SrpingMVC在服务器端抛出一个405错误 Method Not Allowed

  • Http协议中其他的请求方式【了解】

    • 除常规的POST、GET请求外,Http协议还提供了其他的请求方式:PUT、DELETE、OPTIONS….
    • @RequestMapping注解,默认情况也支持其他请求方式的访问,同时也可以根据需要进行限定
    • 除POST、GET这2种请求方式外,其他的请求方式在浏览器支持的不好,所以可以使用专属工具(PostMan)或者库进行测试
    • 其他的请求方式,大多数不支持响应视图技术(JSP,Thymeleaf),只能返回简单字符串或者JSON数据


2.4.3 控制器方法参数

SpringMVC在控制器方法参数设计的过程中,非常灵活,可以支持多种参数的设置方式,非常强大,它也把这种设计,叫做数据绑定。可以设置无参,也可以设置多个参数

  • 代码
    1. @RequestMapping("first")
    2. public String first(HttpServletRequest request, HttpServletResponse response)
    3. @RequestMapping("first")
    4. public String first(HttpServletRequest request)
    5. @RequestMapping("first")
    6. public String first(HttpServletResponse response)
    7. @RequestMapping("first")
    8. public String first(HttpServletRequest request, HttpServletResponse response, HttpSession session)
    9. @RequestMapping("first")
    10. public String first()
    11. 注意:HttpSession也可以单独使用 或者 组合使用
    12.                         ServletContext(application) 不能应用在控制器方法中 做形参
    13. 获取方法:session.getServletContext();
    14.                                         request.getSession().getServletContext();
    复制代码
    思考:上述五种代码形式,在后续开发中最常用哪种?
    1.     前四种不推荐的原因:与Servlet API存在耦合
    复制代码
    第五种不推荐的原因:无法接受client的请求参数
2.4.4 视图解析器(页面跳转)


  • 目前页面跳转存在的问题
    控制器中的跳转路径与实际视图路径存在耦合

  • 视图解析器ViewResolver
    通过视图解析器可以解决跳转路径的耦合

    视图解析器将前缀(路径)和后缀(文件类型)进行封装,跟返回的页面Name进行拼接,因此能访问,并解耦合
    1. @Controller
    2. @RequestMapping("/view")
    3. public class ViewController {
    4.     @RequestMapping("m1")
    5.     public String m1(HttpSession session) {
    6.         System.out.println("session = " + session);
    7.         return "result";
    8.     }
    9. }
    复制代码
    配置文件:

    注解开发
    1. @Configuration
    2. public class AppConfig {
    3.     @Bean
    4.     public InternalResourceViewResolver viewResolver() {
    5.         InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    6.         viewResolver.setPrefix("/");
    7.         viewResolver.setSuffix(".jsp");
    8.         return viewResolver;
    9.     }
    10. }
    11. **注意:
    12.                 1. AppConfig配置Bean应该放置到<context:component-scan/>扫描的路径下
    13.                 2.结合前面所讲,目前因为DispatcherServlet封装的Spring工厂(容器)只能读取xml,所以无法进行纯注解替换。**
    复制代码
    2.4.5 SpringMVC配置文件的默认设置【了解】


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表