SpringMVC
1.什么是SpringMVC?
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架,
1.底层基于Spring (IOC和AOP)
IOC:
采用工厂模式(反射+读取配置文件)方式取代了之前是new创建对象的方式。
好处:解耦合。扩展性更强。
SPI机制:
1.SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。
2.Java的SPI机制就是将一些类信息写在约定的文件中,然后由特定的类加载器加载解析文件获取资源。
3.Java SPI 基于 “接口编程+策略模式+配置文件(约定)”组合实现的动态加载机制。
4.SPI的运用场景:
场景 说明
数据库驱动 数据库驱动加载接口实现类的加载 JDBC加载不同类型数据库的驱动
日志门面SLF4J接口实现类加载 SLF4J加载不同提供商的日志实现类
Spring Spring中大量使用了SPI,比如:对servlet3.0规范对ServletContainerInitializer的实现、
自动类型转换Type Conversion SPI(Converter SPI、Formatter SPI)等
Dubbo Dubbo中也大量使用SPI的方式实现框架的扩展, 不过它对Java提供的原生SPI做了封装, 允许用户扩展实现Filter接口
SpringBoot SpringBoot基于SPI思想实现自动装配
2.封装了web三大组件(Servlet,Filter,Listener)
优点:
使用简单,开发便捷(相比于Servlet)
灵活性强
MVC模型:
MVC(Model View Controller):
- Model(模型):负责封装应用的状态,并实现应用的功能。通常分为:数据模型、业务逻辑模型
- View(视图):页面视图,用于展示数据
- Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑
轻量级:与EJB(enterprice javabean)对比,依赖资源少,消耗的资源少。
Web框架:
Web框架旨在帮助开发Web应用程序,包括Web管理,Web资产和Web [API](https://so.csdn.net/so/search?q=API&spm=1001.2101.3001.7020)。 因此,框架就是可以帮助您更快,更智能地构建应用程序的库。
SpringMVC是Web框架的一种。
2、组件及其作用
前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU;
处理器映射器(HandlerMapping):根据URL去查找处理器;
处理器(Handler):需要程序员去写代码处理逻辑;
处理器适配器(HandlerAdapter):把处理器包装成适配器,这样就可以支持多种类型的处理器,类比笔记本的适配器(适配器模式的应用);
视图解析器(ViewResovler):进行视图解析,将返回的字符串进行处理,可以解析成对应的页面。
3、工作原理
第一步:用户发起请求到前端控制器(DispatcherServlet);
第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle,通过xml配置或者注解进行查找);
第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain);
第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler);
第五步:处理器适配器去执行Handler;
第六步:Handler执行完给处理器适配器返回ModelAndView;
第七步:处理器适配器向前端控制器返回ModelAndView;
第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析;
第九步:视图解析器像前端控制器返回View;
第十步:前端控制器对视图进行渲染;
第十一步:前端控制器向用户响应结果。
4.操作步骤
导入坐标(SpringMVC依赖、Servlet依赖)
创建SpringMVC控制器类(等同于Servlet)
初始化SpringMVC环境
初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径
底层加载特定接口实现类MATEINFO Servilet文件夹的类获取全限定名反射创建对象
extends AbstractDispatcherServletInitializer
或者 extendsAbstractAnnotationConfigDispatcherServletInitializer
代码示例:
SpringMVC控制器类
@Controller
@RequestMapping("/role")
public class RoleController {
@RequestMapping(value = "/save", method = RequestMethod.GET)
@ResponseBody
public String save(){
System.out.println("RoleController save...");
return "save success";
}
@RequestMapping(path = "/delete", method = RequestMethod.POST)
@ResponseBody
public String delete(){
System.out.println("RoleController delete...");
return "delete success";
}
}
SpringMVC配置类
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringmvcConfig {
}
Web容器配置类
使用AbstractDispatcherServletInitializer的子类简化SpringMVC的容器配置类
- 子类:AbstractAnnotationConfigDispatcherServletInitializer
//web容器配置类
public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载SpringMVC配置
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringmvcConfig.class};
}
//设置由springmvc控制器处理的请求映射路径
@Override
protected String[] getServletMappings() {
return new String[]{"/"};//SpringMVC控制器处理所有的请求
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
}
5.SpringMVC的请求处理
SpringMVC的请求处理介绍
SpringMVC主要应用在三层架构中的表现层(web层)。作用就是:
- 接收请求
- 业务处理(交给业务层)
- 响应数据
SpringMVC的请求处理可以分为两大类:
同步请求
- 请求参数通常以url格式为主
GET :http://localhost:8080/save?username=itheima&password=123
POST :http//localhost:8080/save
请求体:username=itheima&password=123
- 特点:同步请求的响应内容会刷新整个网页
- 响应:跳转页面
异步请求
- 请求参数通常有:url格式、json格式
- 特点:请求的响应内容只会让页页局部刷新
- 响应:字符串数据、json格式数据
SpringMvc对请求和响应进行了封装:
- 控制器类中的方法可以接收请求参数
请求携带以下类型的数据时SpringMVC会自动接收,并在解析之后传递给方法进行使用
- 基本数据类型、String
- pojo类型
- 数组类型
- 集合类型
- 使用方式:直接在方法上定义形参
@RequestMapping(value = "/login")
@ResponseBody
public String login(String username,String password){
return "login success";
}
注意:方法上的形参名称必须要和请求参数名称保持一致
URL格式的GET请求: http://localhost:8080/login?username=itheima&password=123
6.SpringMVC的url格式请求参数
url格式的请求参数类型:
基本数据类型、String
普通参数:请求参数与形参名称对应即可完成参数传递Pojo类型
嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递举例:pojo类 private String name; private int age; private Address address(adress是一个实体类) 前端输入数据:name = 张三 age =18 address.province address.city 即可完成封装
- 数组类型
数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中hobbies = 爬山 hobbies = 游泳
- 集合类型
请求参数名与形参集合对象名相同且请求参数为多个,使用 @RequestParam绑定参数关系public String listParam(@RequestParam List<String> likes){}
代码实例:
控制器类
@Controller
public class UserController {
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "commonParam";
}
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "pojoParam";
}
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "pojoContainPojoParam";
}
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "arrayParam";
}
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "listParam";
}
}
Pojo类
public class Address {
private String province;//省份
private String city;//城市
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
public class User {
private String name;
private Integer age;
public Address address;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
使用postman工具,测试请求参数:
- 基本数据类型、String
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "commonParam";
}
Pojo类型
- 请求参数名与方法形参对象属性名相同(定义POJO类型形参即可接收参数)
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "pojoParam";
}
嵌套POJO参数:请求参数名与形参对象属性名相同(按照对象层次结构关系即可接收嵌套POJO属性参数)
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "pojoContainPojoParam";
}
数组类型
- 请求参数名与方法形参数组名相同且请求参数为多个(定义数组类型形参即可接收参数)
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "arrayParam";
}
集合类型
- 请求参数名与形参集合对象名相同且请求参数为多个,使用@RequestParam绑定参数关系
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "listParam";
}
7.SpringMVC的json格式请求参数
Json知识介绍
json格式数据:
- 对象 :{ }
- 数组 :[ ]
json格式请求参数常见类型:
1.json对象
User
{"name":"zs","age" : 18}
2.json数组
String[]
["a","b","c"]
3.json数组(POJO)
List<User>
[{"name":"zs","age" : 18},{"name":"ls","age":19}]
java中的json转换工具:
- FastJson
- JackSon (SpringMVC底层使用)
SpringMVC接收json请求参数的步骤
1.导入坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
2.开启json数据自动转换
//开启json数据类型自动转换
@EnableWebMvc
3.接收json数据:使用@RequestBody注解把json数据映射到方法形参上
public String pojoParamForJson(@RequestBody User user)
获取json格式的请求参数
代码示例:
- SpringMVC配置类
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc //@EnableWebMvc注解整合了多个功能,此处仅使用json数据进行自动类型转换
public class SpringmvcConfig {
}
SpringMVC控制器类
@Controller
public class UserController {
//POJO参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "pojoParamForJson";
}
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "listParamForJson";
}
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "listPojoParamForJson";
}
}
使用postman工具,测试请求参数:
- POJO参数:json数据与形参对象属性名相同 (定义POJO类型形参即可接收参数)
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "pojoParamForJson";
}
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "listPojoParamForJson";
}
关键API总结
url格式请求参数
- @RequestParam (接收集合类型的参数)
json格式请求参数
- @EnableWebMvc //开启webmvc功能(功能之一: 自动实现json和pojo转换)
- @RequestBody //在参数前面添加,用于接收json格式参数映射到pojo上
8.SpringMVC的特殊情况请求参数
1.当请求的参数名和目标方法中的形参名不一致时, 使用
@RequestParam注解,建立请求参数名与形参名称之间的关系
public String commonParam(@RequestParam("name") String username ,
@RequestParam("age") int userage)
2.post请求乱码解决 (get请求:Tomcat8版本开始已解决)
<br />
在ServletContainersInitConfig配置类中进行配置即可
@Override
protected Filter[] getServletFilters() {
//spring封装的过滤器, 拦截所有的请求,如果是post请求,就将编码修改为指定编码
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding(“UTF-8”);
return new Filter[]{filter};
}
3.日期类型数据基于系统不同格式也不尽相同
使用注解: @DateTimeFormat
根据请求传入的格式设置对应的pattern
public String dateParam(
Date date1,
@DateTimeFormat(pattern = "yyyy-MM-dd") Date date2,
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date3)
9.SpringMVC的响应处理
使响应的内容当作响应体使用 @ResponseBody 注解
可以响应 String ,pojo实体类 , list集合
特殊://返回值为String类型,设置返回值为页面名称,即可实现页面跳转
//前后端分离后不常用(了解)
10.SpringMVC的RESTful风格
<br />
介绍 :一种网络资源的访问风格,定义了网络资源的访问方式
REST风格访问路径:
http ://localhost/user/1
可以具有多个含义:
既可以是查询,也可以是删除,也可以是修改,也可以是添加(别人根本就不知道开发者在干嘛)
RESTful风格请求
当同一个请求路径,想访问不同的资源是,restful风格依据发送的请求类型来区别:
添加:
@RequestMapping(value = "/rest",method = RequestMethod.POST)
修改:
@RequestMapping(value = "/rest",method = RequestMethod.PUT)
删除:
@RequestMapping(value = "/rest",method = RequestMethod.DELETE)
查询:
@RequestMapping(value = "/rest",method = RequestMethod.GET)
当使用的请求方式需要带参数,可以使用参数表达式,并在获取的方法形参列表添加一个注解
.@PathVariable
一个参数:
@RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
||
||
\/
public String deleteById(@PathVariable Integer id){
两个参数:
@RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
||
||
\/
public List<User> findByPage(@PathVariable Integer page, @PathVariable Integer pageSize){
restful 组合注解优化
@RestController= @Controller + @ResponceBody
@GetMapping("/rest") = @RequestMapping(value = "/rest",method = RequestMethod.GET)
以此类推...........
综合案例 vue项目创建步骤
html页面
1导入css ,js库,elementui.....
2.引入css样式,vue组件
<link rel="stylesheet" href="../plugins/elementui/index.css">
<link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../css/style.css">
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
3.<body>区域写试图 <div class="app"><div/>
4.div外写scrip脚本
<script>
//vue对象
new Vue({
//绑定视图
el:'#app',
//页面数据源
data:{},
//函数
methods:{}
})
</script>
5.映入elment ui需要的内容进行修改
SSM框架整合流程
SSM整合:
搭建Spring环境
步骤:1. 导入坐标:spring-webmvc ```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_day02-ssm</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <!-- 依赖管理 --> <dependencies> <!-- SpringMVC(底层依赖Spring)--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency> </dependencies> </project>
```
在spring-webmvc依赖中包含了:spring-context
2. 编写Spring配置类(注解开发)
```java
/* Spring IoC容器(父容器)
1. 管理除Controller包之外的所有bean
2. spring的组件扫描 : 扫描controller包之外的其他包
1). 方案一: 一个个配置,就是不配置controller包
2). 方案二: 全扫描,排除controller包
ComponentScan
I. value : 要扫描的包
II. excludeFilters : 排除不扫描 Controller和 RestController注解
a. type : 要排除的类型 (注解)
b. classes : 要排除的类
*/
/*@ComponentScan(value = "com.itheima",
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = {Controller.class, RestController.class}
)
}
)*/
//Spring配置类 (添加到IoC容器中)
@Configuration
@ComponentScan({"com.itheima.service"}) //扫描service层包
public class SpringConfig {
}
加载MybatisConfig配置类
```java
//Mybatis配置类
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource ds){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
//设置pojo的包扫描
factoryBean.setTypeAliasesPackage("com.itheima.domain");
//设置连接池
factoryBean.setDataSource(ds);
return factoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//设置dao层的接口扫描
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
```
加载JdbcConfig配置类
```java
//配置:连接池、事务管理器
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 dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
//设置事务管理器 (声明式事务)
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
//PlatformTransactionManager是DataSourceTransactionManager的父接口
DataSourceTransactionManager dstm = new DataSourceTransactionManager();
dstm.setDataSource(dataSource);
return dstm;
}
}
```
加载service层的bean到IOC容器
开启事务管理支持
加载外部资源配置文件
Spring和Mybatis整合 步骤:
- 导入坐标:mysql、mybatis、druid、mybatis-spring、spring-jdbc
- 编写配置类:MybatisConfig、JdbcConfig MybatisConfig:代替mybatis-config.xml 封装SqlSessionFactory、SqlSession 指定要扫描的dao层 配置pojo类别名 JdbcConfig:连接池、声明式事务 @EnableTransactionManagement
- 编写dao层
- 编写service 添加 @Service,表示业务类由SpringIoC容器管理 添加BookDao依赖注入
- 导入坐标:mysql、mybatis、druid、mybatis-spring、spring-jdbc
Spring和SpringMVC整合
- 步骤:
- 导入坐标:servlet、jackson
- 编写配置类:SpringMVC配置类、Web容器配置类
- SpringMVC配置类:
- 加载controller层的bean到ioc容器
- 开启json和javabean之间的互相转换
- Web容器配置类:Tomcat启动时,基于SPI机制,会自动加载
- 加载SpringConfig配置类
- 加载SpringmvcConfig配置
- 配置请求路径(所有请求)
- 处理中文乱码
- 编写Controller
- 使用浏览器/postman测试 ```
- 步骤: