文章目录
SpringMVC 学习
一. spingMVC 使用步骤
1.导入依赖 jar 包
- 插件坐标 本质就是
web
项目需要servlet
容器 , 因为这就是一个web 框架
servlet 容器
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<!--<uriEncoding>UTF-8</uriEncoding>-->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
- spirngMVC 本质也是一个本质也是一个
web
项目 , 依赖这四个项目
servlet
spring-context
spring-webmvc
junit
<dependencies>
<!--导入对应的坐标来启动程序开发-->
<!--1.本项目的工件名称和版本-->
<!--2.导入 junit 来进行测试-->
<!--3.导入 servlet 作为 control
备注 : scope子标签设置为 provided-->
<!--4.导入 tomcat 作为 servlet 容器-->
<!--5.导入框架 springMVC 整合 servlet 开发-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
-
关系图
- 其他配置
设置属性
- 设置
war
包
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
2.创建 control bean 对象
@Controller
public class UserControl {
@RequestMapping("/operate/save")
@ResponseBody
public String save() {
System.out.println("save success ...");
return "save success ...";
}
@RequestMapping("/operate/delete")
@ResponseBody
public String delete() {
System.out.println("delete success ...");
return "delete success ...";
}
}
@Controller
控制器类 , 和@WebServlet(urlPatterns = {"/demo1"})
是一个意思 , 本质就是spring
版本的servlet
类@RequestMapping("/operate/save")
请求路径映射 ,绑定在方法上
一旦有request
就调用该方法
."/*"
接受所有请求 .@ResponseBody
这个注解在方法
有response
的时候加上 , 告诉servlet 容器
- 声明
@control
类 , 给类方法
加入@RequestMapping("/operate/save")
,如果control类方法
有response
,给类方法加上@response
3.创建 spring 配置类
- 创建
spring-ioc 容器
Inversion of controller
反转控制容器 , 管理bean
, 有注解
和xml
两种配置方式 , 这里用注解
@Configuration // ioc 容器配置注解 .
@ComponentScan(value = {"com.itheima"}, excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)) /* 扫描器扫描 bean 纳入管理 , 如果扫到了带有 @Configuration 的类 , 会把对方的 bean 纳入管理 . */
public class SpringConfig {
}
4.初始化 servlet 容器 , 加载 springMVC 环境
-
核心是新建类 继承类
AbstractAnnotationConfigDispatcherServletInitializer
-
包括
映射路径
就是拦截
请求的路径 ,"/"
接受所有路径请求 . 逻辑就是 ,request
如果和配置的路径
相符合就可以拦截下来
去和@Controller
类的方法@RequestMapping
对应 , 对应上了就调用方法就完事了 . -
包括
ioc 容器
-
包括
控制器类
package com.itheima.config;
import com.itheima.control.UserControl;
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;
public class ServletContextConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{UserControl.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/operate/delete", "/operate/save"};
}
// 方法2 : 继承 AbstractDispatcherServletInitializer
1.加载 SpringMVC 配置
//@Override
//protected WebApplicationContext createServletApplicationContext() {
// AnnotationConfigWebApplicationContext wc = new AnnotationConfigWebApplicationContext();
// wc.register(SpringMVCConfig.class);
// return wc;
//}
//
2.设置那些请求归属 SpringMVC
//@Override
//protected String[] getServletMappings() {
// return new String[]{"/operate/delete"};
//}
//
3.加载 Spring 容器
//@Override
//protected WebApplicationContext createRootApplicationContext() {
// AnnotationConfigWebApplicationContext wc = new AnnotationConfigWebApplicationContext();
// wc.register(SpringConfig.class);
// return wc;
//}
}
5.技术总结
- 导入
依赖坐标
主要是servlet
tomcat 插件
spring-context
sping-webmvc
junit
springframework
项目需要配置ioc 容器
inversion of control
管理对应的bean
spring-webmvc
需要配置对应的@Controller
类 , 通过类的@RequestMapping("\URI")
方法
来响应
对应的请求 ,@ReponseBody
来标记有response
的方法
.- 配置初始化
servlet 容器
, 通过类继承AbstractDispatcherServletInitializer
或者AbstractAnnotationConfigDispatcherServletInitializer
初始化类来实现 . 导入坐标
-->编写 ioc容器
-->编写 @Controller
-->初始化 servlet 容器
- 开发模式是
N + 1
,导入坐标 , ioc 容器 , servlet , 初始化 servlet 容器
都只需要一次
即可 , 往后在@Controller
类里面编写方法即可 .
二.包扫描排除
1.情况说明
- 包结构如下图所示
- 问题分析
springMVCConfig
需要的表现层
的bean
springConfig
需要的是业务
bean
- 大家都是扫描
com.itheima
就会导致导入不合理
2.问题解决
方案 1 :
配置类扫描特定的类包
即可方案 2 :
扫描包名
通过特定排除
即可完成需求
@ComponentScan({"com.itheima.service", "com.itheima.dao"})
@ComponentScan("com.itheima.control")
@ComponentScan(value = {"com.itheima"}, excludeFilters = @ComponentScan.Filter( type = FilterType.ANNOTATION, classes = Controller.class ))
通过注解排除 , 但是SpringMVCConfig
类不能加上注解@Configuration
否则会重新加载回来
3.开发标准
用 方案 1 :
开发
三.@Controller 的路径重复
1.问题描述
在开发过程中 , 不同的朋友使用相同的访问路径
即 @RequestMapping
的路径相同 , 导致运行错误
2.解决方法
路径 = 模块名 + 方法名
eg :
类名为BookControl
的delete
方法@RequestMapping("/book/delete")
3.请求路径前缀
每次都要写 模块名
太麻烦了 , 偷懒方法就是在类上写请求 路径的前缀
, 方法上写请求后缀
package com.itheima.control;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
// 前缀 "/user"
@Controller
@RequestMapping("/user")
public class UserControl {
// 后缀 "/save"
@RequestMapping("/save")
@ResponseBody
public String save() {
System.out.println("save success ...");
return "save success ...";
}
// 后缀 "/delete"
@RequestMapping("/delete")
@ResponseBody
public String delete() {
System.out.println("delete success ...");
return "delete success ...";
}
// 后缀 "/*" 拦截到的请求如果没有匹配的都来这里
@RequestMapping("/*")
@ResponseBody
public String all() {
System.out.println("all success ...");
return "all success ...";
}
}