Spring MVC学习随笔-第一个Spring MVC程序(父子项目结构、Tomcat配置、Vie
学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅第二章、第一个SpringMVC程序的开发
2.1开发版本
[*]JDK1.8+
[*]Maven3.6+
[*]IDEA2021+
[*]SpringFramework 5.1.4
[*]Tomcat8.5.29
[*]MySQL5.7.18
按照父子项目的结构,管理和创建项目,创建一个空Project作为父项目,pom文件如下
<?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.baizhi</groupId>
<artifactId>baizhi-mvc-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>baizhi-mvc-01</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>创建子项目Module:
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126102748823-441179887.png
子项目pom文件:
<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">
<parent>
<artifactId>baizhi-mvc-parent</artifactId>
<groupId>com.baizhi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>baizhi-mvc-01</artifactId>
<packaging>war</packaging>注意:初次创建web项目时,WEB-INF包下的web.xml引入的servlet规范的版本还是2.3,而我们使用的tomcat8至少需要3.0以上的规范,所以需要修复,删除此文件后在Project Settings设置,如图:
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126102811110-329026885.png
Tomcat配置
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126102921006-896715040.png
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126102931546-588871123.png
2.2 环境搭建
2.2.1 引入相关jar
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.27</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>0.1.5</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.30</version>
</dependency>
</dependencies>注意:SpringMVC比前面所学习的Spring,就多引入了一个jar包,叫做spring-webmvc.jar
2.2.2 配置文件
SpringMVC的配置文件,就是Spring的配置文件
注意事项:
[*]名字可以随便命名,本次课程取名dispatcher.xml
[*]放置路径可以根据需要,随意放置,本次课程放置在资源文件夹的根下.
2.2.3 初始化配置
[*]web.xml
<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:dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
[*]DispatcherServlet称为前端控制器(中央控制器)
[*]DispatcherServlet的核心作用:
[*]用于创建Spring的工厂(容器)
等效于:ApplicationContext ctx = new ClassPathXmlApplicationContext(”dispatcher.xml”);
因为DispatcherServlet封装的Spring工厂只能读取xml,所以无法迁移到纯注解编程
[*]控制SpringMVC内部的运行流程
SpringMVC的配置文件dispatcher.xml
<context:component-scan base-package="com.baizhi"/>
<mvc:annotation-driven/>https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103036020-1967294548.png
mvc:annotaion-driven这段配置的主要作用:引入SpringMVC的核心功能
主要引入了2个核心类型:1.RequestMappingHandlerMapping 2.RequestMappingHandlerAdapter
[*]RequestMappingHandlerMapping实现了HandlerMapping接口
它会处理@RequestMapping注解,并将其注册到请求映射表中
[*]RequestMappingHandlerAdapter实现了 HandlerAdapter接口
它是处理请求的适配器,确定调用某个符合要求的控制器类中具体服务的方法
SpringMVC对mvc:annotaion-driven的封装
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103052704-1707024632.png
context:component-scan
[*]进行注解扫描
[*]DispatcherServlet所创建的工厂需要读取XML的配置文件,不能使用纯注解的开发。所以目前使用Spring配置文件+基础注解的形式,进行开发
基础注解可以用:@Component @Service @Repository,@Controller,@Scope,@Transsactional等
高级注解无效:@Configuration,@Bean,@ComponentScan
2.3编程思路
2.3.1 思路分析
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103104278-1158763037.png
基本流程
[*]开发一个类在上面加入@Controller注解
[*]提供一个控制器方法:参数是HttpServletRequest,HttpServletResponse,返回值是String的,同时加入@RequestMapping注解定义请求路径
[*]在控制方法中,完成核心开发功能,把对应JSP页面的路径,作为方法的返回值返回
2.3.2 编码
@Controller
public class FirstController {
@RequestMapping("/first")
public String first(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.first");
return "/result.jsp";
}
}
必须要进行@Controller注解的扫描,配置文件中:<context:component-scan base-package="com.baizhi"/>2.3.3 一个控制器中,提供多个服务方法
[*]Servlet作为控制器,一个类中只能提供一个服务方法
在原来的Servlet开发中,明确控制器的方法必须实现接口规定的service(HttpServletRequest request, HttpServletResponse response)方法,一个类中只能实现一次,所以一个类中只能有一个服务方法
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103152761-1999193950.png
[*]SpringMVC的控制器,一个类中可以提供多个对外服务的方法
[*]SpringMVC控制器,没有对于方法名的限制,所以可以提供多个服务方法http://localhost:8989/basic/first
http://localhost:8989/basic/second
@Controller
public class FirstController {
@RequestMapping("/first")
public String first(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.first");
return "/result.jsp";
}
@RequestMapping(value="/second")
public String second(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.second");
return "/result.jsp";
}
}
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)
[*]路径分隔符 /可以省略
@RequestMapping(value="suns/second")
public String second(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.second");
return "/result.jsp";
}
# 注意 多级目录开头可以不写/
[*]在一个控制器方法上映射多个路径
@Controller
public class FirstController {
@RequestMapping(**value={"first","third"}**)
public String first(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.first");
return "/result.jsp";
}
}
[*]Controller类上加入@RequestMapping注解
http://localhost:8989/basic/user/first
http://localhost:8989/basic/user/second
@Controller
@RequestMapping("/user")
public class FirstController {
@RequestMapping("/addUser")
public String addUser(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.addUser");
return "/result.jsp";
}
@RequestMapping(value="/deleteUser")
public String deleteUser(HttpServletRequest request, HttpServletResponse response) {
System.out.println("FirstController.deleteUser");
return "/result.jsp";
}
}
设计目的
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103301886-1960538376.png
满足单一职能原则,可以更好的按照功能,进行不同模块的区分,有利于项目的管理。
[*]@RequestMapping限定用户的请求方式
[*]请求方式
[*]所谓请求方式指的就是Web开发中的 POST请求与GET请求
回顾:Web开发中的POST请求与GET请求的区别
两种请求提交数据的区别
[*]GET请求:通过请求行(地址栏)提交数据(QueryString),明文数据提交,不安全,提交的数据量小(不超过2048字节)
[*]POST请求:通过请求体提交数据,密文提交(不是加密,指的是一般用户不可见),相对安全,提交数据量大(理论上没有限制)
两种请求发起方式的区别
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103314929-1524889826.png
[*]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数据
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103343063-1621268553.png
2.4.3 控制器方法参数
SpringMVC在控制器方法参数设计的过程中,非常灵活,可以支持多种参数的设置方式,非常强大,它也把这种设计,叫做数据绑定。可以设置无参,也可以设置多个参数
[*]代码
@RequestMapping("first")
public String first(HttpServletRequest request, HttpServletResponse response)
@RequestMapping("first")
public String first(HttpServletRequest request)
@RequestMapping("first")
public String first(HttpServletResponse response)
@RequestMapping("first")
public String first(HttpServletRequest request, HttpServletResponse response, HttpSession session)
@RequestMapping("first")
public String first()
注意:HttpSession也可以单独使用 或者 组合使用
ServletContext(application) 不能应用在控制器方法中 做形参
获取方法:session.getServletContext();
request.getSession().getServletContext();思考:上述五种代码形式,在后续开发中最常用哪种?
前四种不推荐的原因:与Servlet API存在耦合第五种不推荐的原因:无法接受client的请求参数
2.4.4 视图解析器(页面跳转)
[*]目前页面跳转存在的问题
控制器中的跳转路径与实际视图路径存在耦合
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103356593-1363144763.png
[*]视图解析器ViewResolver
通过视图解析器可以解决跳转路径的耦合
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103424326-1163120387.png
视图解析器将前缀(路径)和后缀(文件类型)进行封装,跟返回的页面Name进行拼接,因此能访问,并解耦合
@Controller
@RequestMapping("/view")
public class ViewController {
@RequestMapping("m1")
public String m1(HttpSession session) {
System.out.println("session = " + session);
return "result";
}
}配置文件:
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103442056-1207819484.png
注解开发
@Configuration
public class AppConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
**注意:
1. AppConfig配置Bean应该放置到<context:component-scan/>扫描的路径下
2.结合前面所讲,目前因为DispatcherServlet封装的Spring工厂(容器)只能读取xml,所以无法进行纯注解替换。**2.4.5 SpringMVC配置文件的默认设置【了解】
https://img2023.cnblogs.com/blog/3321544/202311/3321544-20231126103456701-232046240.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]