SpringMVC
1.前置知识回顾
MVC:是一种开发模式,使用该模式将应用分为模型层、控制层、视图层以更好的实现各层分离达到高内聚低耦合的效果
M(Model):Model层,主要指service|Dao|Model,主要用于进行业务处理
V(View):视图层,主要指HTML/JS/JSP,主要用于界面展示
C(Controller):控制层,主要指Servlet,主要用于协调Model和View,用于获取请求并向页面响应的
MVC框架:
- struts框架,比较古老的优秀的MVC框架,属于apache的一个项目
- WebWork框架,基于MVC的企业框架技术,由于webwork使用较少,但其内核优秀,后期apache对webwork进行改造,出现后期流行一时另一个框架技术struts2
- Struts2框架,是一个流行一时框架技术,struts2和之前的struts其实没有任何关系,只是借助于struts名气而已,属于apache的一个项目
- SpringMVC框架,该框架是基于Spring的一套框架技术,目前比较流行,它是springBoot所使用MVC技术
###2.什么是SpringMVC?
-
SpringMVC属于Spring体系中的一个模块
-
SpringMVC是基于MVC的一个框架技术
-
SpringMVC提供了一套强大的控制器体系,通过这套控制器可以大大简化Web应用的开发,SpringMVC它将一些比较繁琐的逻辑实现了自动化处理,不在需要开发人员手动编写,如:参数自动封装、JSON转换等
###3.Spring体系结构图
![image-20210115123930097](https://i-blog.csdnimg.cn/blog_migrate/e48e14ead14b118d228a26a93e0ce181.png)
4.SpringMVC工作流程?
-
自定义核心Servlet流程图
-
SpringMVC工作流程图
-
流程描述
1. 客户端发送请求给核心控制器,核心控制器获得请求后,根据请求的url在处理器映射器中查找对应handler对象(控制器对象)
1. 处理器映射器将找到的Handler对象返回给核心控制器
2. 核心控制器委派处理器适配器HandlerAdapter执行Handler
3. 处理器适配器HandlerAdapter将请求转给Handler对象执行具体业务
4. 处理器对象Handler,调用Model层进行业务处理,将结果返回给处理器适配器HandlerAdapter,返回的结果为ModelAndView对象(Model指数据,view指视图)
5. 处理器适配器HandlerAdapter,将ModelAndView对象返回给核心控制器
6. 核心控制器调用视图解析器对View进行解析,视图解析器根据核心控制器发送来的逻辑视图解析为一个物理视图并将物理视图返回给核心控制器
7. 核心控制器调用视图渲染器将视图渲染(将model数据加载到特定的对象如request)
8. 核心控制器向客户端响应
5 .使用SpringMvc
-
基于XML方式
-
基于编程和注解方式(推荐)
(1) 新建一个基于Maven的Web应用
(2)新建web应用后,pom.xml的添加的内容
<1> servlet-api:
JavaWeb的支持包
<2> SpringWebMVC:
SpringMVC的核心包
导入Spring Web MVC核心包后,其他依赖包
如:aop/core/breans/context/web/expression包会自动导入
<3> Jackson-databind:
是一个JSON处理包,Jackson包与SpringMVC自动绑定
SpringMVC中所使用的默认JSON处理为Jackson,无需单独设置,如果你要使用其他的
JSON库,则需要单独设置
<dependencies>
<!-- javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--
spring-webmvc
引入SpringWebMVC依赖包后,其他Spring相关的依赖包会同步引入
1.spring-core
2.spring-beans
3.spring-context
4.spring-aop
5.spring-expression
6.spring-web
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--
jackson-databind,Spring与jackson绑定的依赖包
SpringMVC默认使用jackson进行JSON数据格式转换
它会自动将jackson的jackson-core包和jackson-annotations包自动导入 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies>
(3)配置tomcat,发布测试
(4)创建SpringMVC的初始化器
在基于XML的配置中,需要在Web.xml中配置DispatcherServlet,配置后SpringMVC跟随tomcat的启动自动启动
基于编程式的方式只要编写SpringMVC的初始化器(类),当tomcat启动时会自动启动SpringMVC(加载初始化器)
package com.jiazhong.spring.cfg;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* @Description: 初始化类,该类用于初始化Spring环境并加载Spring中的相关配置类
* 配置SpringMVC的映射路径
* 配置类:
* 1.根容器配置类
* 2.web容器配置类
*/
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/***
* 初始化根容器配置类
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
/***
* 初始化web容器配置类
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MVCConfig.class};
}
/***
* 配置SpringMVC的映射路径(访问路径)
* 配置SpringMVC拦截那些请求(那些请求应该交给DispatcherServlet来处理)
* "/"表示拦截所有请求,除jsp
* "/*"表示拦截所有请求
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
(5)创建相关配置类
根容器配置类:
package com.jiazhong.spring.cfg;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author: 加中实训
* @Date:2020/8/2 19:25
* @Description: 根容器配置类,它是spring的一个配置类,
* 其中主要用于配置spring及service、dao等业务层配置
*/
@Configuration//配置类注解
@ComponentScan("com.jiazhong.spring.service")
public class RootConfig {
}
web容器配置类:
package com.jiazhong.spring.cfg;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.Charset;
import java.util.List;
/**
* @Description: Web容器配置类,该类主要配置Web应用相关的配置 (Controller/请求响应有关)
*/
@Configuration
//配置控制器扫描器
@ComponentScan(basePackages = "com.jiazhong.spring.controller")
@EnableWebMvc//启动SpringMVC,开启后我们就可以使用SpringMVC提供的注解
public class MVCConfig implements WebMvcConfigurer {
/***
* 使用继承的方式重写我们需要调整的转换器
* 使用该方法后会将我们自定义的转换器加入到springMVC的默认转换器列表中,并替换已有的转换器
* @param converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//创建一个字符串转换器对象(可以将请求的报文转换为字符串,也可以将字符串转换为响应报文)
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
//设置默认编码
stringHttpMessageConverter.setDefaultCharset(Charset.forName("UTF-8"));
//将字符串转换器添加到消息转换器列表中
converters.add(0,stringHttpMessageConverter);
//JSON转换器,配置SpringMVC使用FastJSON进行转换(默认使用JACKSON进行转换)
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
converters.add(1, converter);
}
/**
* 放行静态资源
* @param configurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
(6)创建Controller控制器对象
package com.jiazhong.spring.controller;
import com.jiazhong.spring.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: 加中实训
* @Date:2020/8/2 19:50
* @Description: 该类为一个控制器类,该类不需要继承任何类或实现任何接口
*/
@Controller//控制器注解
public class DemoController {
@RequestMapping("/demo1")//控制器访问路径
@ResponseBody//将方法的返回值做为响应体直接响应到页面,会使用SpringMVC内置的转换器将返回结果转换JSON
public String demo1(){
System.out.println("控制器开始执行.....");
return "Hello!你好啊!";
}
@RequestMapping("/demo2")
@ResponseBody
public List<String> demo2(){
List<String> stringList = new ArrayList<>();
stringList.add("aaa");
stringList.add("bbb");
stringList.add("ccc");
return stringList;
}
@RequestMapping("/demo3")
@ResponseBody
public Map<String,String> demo3(){
Map<String,String> map = new HashMap<>();
map.put("key1","val1");
map.put("key2","val2");
map.put("key3","val3");
return map;
}
@RequestMapping("/demo4")
@ResponseBody
public String demo4(){
return "你好";
}
}
6.SpringMVC常用注释
@Configuration:表示类为一个配置类
@ComponentScan:包扫描器注解
@EnableWebMvc:开启SpringMVC默认配置注解
@Bean:标识方法的返回值为spring管理的一个Bean对象
@Controller:控制器注解
@RequestMapping:控制器访问路径注解
@ResponseBody:设置方法返回值为响应体并自动进行JSON转换注解
@RestController:@Controller+@ResponseBody两个注解组合
@SessionAttributes:设置session作用域存储的属性注解
@RequestParam("userAge"):从请求参数中获取参数名为userAge的值并复制其后的变量
@MapperScan():mybaits映射器扫描器
@Transactional:开启Spring声明式事务
@PropertySource("classpath:/db.properties"):引入外部文件
@RequestBody:在参数中使用的注解,用于解析客户端传入的payload格式的数据
7.Spring、SpringMVC、MyBatis整合
-
三个框架整合需要依赖的库文件
(1) SpringWebMVC:SpringMVC的核心包,该包包含Spring的相关核心包,如core、bean、aop…
(2) Servlet API:Web应用的基础包
(3) FastJSON:可以不使用,使用jackson Databind替换
(4) MySQL
(5) MyBatis
(6) MyBatis-Spring整合包
(7) Druid
(8) Log4j2
(9) PageHelper:基于MyBatis的分页插件包
(10) TranscationManager:Spring的事务处理包Spring-tx
(11) Spring-jdbc
(12) aspectjweaver
-
编写相关的配置文件及配置类
1 ,导入依赖
<!-- javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--
spring-webmvc
引入SpringWebMVC依赖包后,其他Spring相关的依赖包会同步引入
1.spring-core
2.spring-beans
3.spring-context
4.spring-aop
5.spring-expression
6.spring-web
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--
jackson-databind,Spring与jackson绑定的依赖包
SpringMVC默认使用jackson进行JSON数据格式转换
它会自动将jackson的jackson-core包和jackson-annotations包自动导入
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<!-- aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
<scope>runtime</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.4</version>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- spring-tx事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!-- log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.0</version>
</dependency>
<!-- pagehelper Aop-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
2.构建项目结构
rootConfig, webAppinitializer, webConfig如上文相同注意添加注解
![image-20210116144228662](https://i-blog.csdnimg.cn/blog_migrate/e02c730997cd3a1964cd79240fc4046b.png)
![image-20210116144252090](https://i-blog.csdnimg.cn/blog_migrate/6f9cf72a3d55ca4f22ad770052331470.png)
dao service类
![image-20210116145021332](https://i-blog.csdnimg.cn/blog_migrate/0bb90978abe692511273cbbeb14376c8.png)
controller类:
@RestController
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@RequestMapping("/getGoodsList")
public List<Goods> getGoodsList(){
return goodsService.getGoodsList();
}
}
-----------前端-------
<!--index.html页面-->
<div id="goodsApp">
<table>
<thead>
<tr>
<th>商品编号</th>
<th>商品名称</th>
<th>商品单价</th>
<th>上架时间</th>
</tr>
</thead>
<tbody>
<tr v-for="goods in goodsList">
<td>{{goods.g_id}}</td>
<td>{{goods.g_name}}</td>
<td>{{goods.g_price}}</td>
<td>{{goods.g_date}}</td>
</tr>
</tbody>
</table>
</div>
<script src="js/vue.min.js"></script>
<script src="js/axios.min.js"></script>
<script>
new Vue({
el:'#goodsApp',
data:{
goodsList:[],//goods数组
},
methods:{
/**
* 使用ajax访问服务端
* 在VUE中使用axios库来与服务端交互,axios是一个轻量级的ajax库
*/
getGoodsList(){
axios.get('goods/getGoodsList')
.then(response=>{//当请求和响应正常时执行
//将服务端响应的数据设置到goodsList属性中
this.goodsList=response.data;
})
.catch(err => {//当请求或响应错误时执行
alert(err);
});
}
},
mounted(){//加载方法,当页面执行完毕后加载该方法(等同于onload事件)
this.getGoodsList();
}
});
</script>
<body>
<div id="app">
{{name}}
<input type="text" v-model="name" />
<button type="button" @click="test">测试</button>
<ul>
<li v-for="str in strArr">
<a href="" v-if="str=='bbb'">{{str}}</a>
</li>
</ul>
</div>
package com.jiazhong.cfg;
@Configuration
@ComponentScan("com.jiazhong.service")//Service组件扫描器
@MapperScan("com.jiazhong.dao")//映射器扫描器
public class RootConfig {
/**
* 配置数据源
*/
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/goods");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setInitialSize(10);
dataSource.setMinIdle(10);
dataSource.setMaxWait(1000);
dataSource.setMaxActive(30);
return dataSource;
}
/**
* 配置SqlSessionFactory
* @param dataSource
*/
@Bean
@Autowired
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
//创建SqlSessionFactoryBean对象
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//配置resource下的mapper.xml
Resource resource = new ClassPathResource("mapper/GoodsMapper.xml");
sqlSessionFactoryBean.setMapperLocations(resource);
//配置PageHelper分页插件
PageInterceptor pageInterceptor = new PageInterceptor();
//属性资源对象,等同于资源文件,其中使用key-value的形式保存数据(内部是一个map集合)
Properties properties = new Properties();
properties.setProperty("helperDialect","mysql");//配置方言,指定所使用的数据库
/**
* 是否启用分页合理化配置
* 此配置开启后,当访问的页面小于1时自动访问第一页,当访问的页码大于最后一页时,会自动访问最后一页
*/
properties.setProperty("reasonable","true");
pageInterceptor.setProperties(properties);
//将pageHelper添加到sqlSessionFactoryBean的插件中
sqlSessionFactoryBean.setPlugins(pageInterceptor);
return sqlSessionFactoryBean.getObject();
}
/**
* 事务管理器
* @param dataSource
* @return
*/
@Bean
@Autowired
public TransactionManager txManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
properties.setProperty(“reasonable”,“true”);
pageInterceptor.setProperties(properties);
//将pageHelper添加到sqlSessionFactoryBean的插件中
sqlSessionFactoryBean.setPlugins(pageInterceptor);
return sqlSessionFactoryBean.getObject();
}
/**
* 事务管理器
* @param dataSource
* @return
*/
@Bean
@Autowired
public TransactionManager txManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}