目录
整合Mybatis,Spring,SpringMVC三个框架。
- <dependencies>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webmvcartifactId>
- <version>5.2.10.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-jdbcartifactId>
- <version>5.2.10.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-testartifactId>
- <version>5.2.10.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.6version>
- dependency>
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatis-springartifactId>
- <version>1.3.0version>
- dependency>
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>5.1.47version>
- dependency>
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>druidartifactId>
- <version>1.1.16version>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.12version>
- <scope>testscope>
- dependency>
-
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>3.1.0version>
- <scope>providedscope>
- dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.9.0version>
- dependency>
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.tomcat.mavengroupId>
- <artifactId>tomcat7-maven-pluginartifactId>
- <version>2.1version>
- <configuration>
- <port>80port>
- <path>/path>
- configuration>
- plugin>
- plugins>
- build>
config 目录存放的是相关的配置类controller 编写的是 Controller 类dao 存放的是 Dao 接口,因为使用的是 Mapper 接口代理方式,所以没有实现类包service 存的是 Service 接口, impl 存放的是 Service 实现类resources: 存入的是配置文件,如 Jdbc.propertieswebapp: 目录可以存放静态资源test/java: 存放的是测试类
- @Configuration
- @ComponentScan({"com.itheima.service"})
- @PropertySource("classpath:jdbc.properties")
- @Import({JdbcConfig.class,MyBatisConfig.class})
- @EnableTransactionManagement
- public class SpringConfig {
- }
- 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){
- DataSourceTransactionManager ds = new DataSourceTransactionManager();
- ds.setDataSource(dataSource);
- return ds;
- }
- }
- public class MyBatisConfig {
-
- @Bean
- public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
- SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
- factoryBean.setDataSource(dataSource);
- factoryBean.setTypeAliasesPackage("com.itheima.domain");
- return factoryBean;
- }
-
- @Bean
- public MapperScannerConfigurer mapperScannerConfigurer(){
- MapperScannerConfigurer msc = new MapperScannerConfigurer();
- msc.setBasePackage("com.itheima.dao");
- return msc;
- }
-
- }
- jdbc.driver=com.mysql.jdbc.Driver
- jdbc.url=jdbc:mysql://localhost:3306/ssm_db
- jdbc.username=root
- jdbc.password=root
- @Configuration
- @ComponentScan("com.itheima.controller")
- @EnableWebMvc
- public class SpringMvcConfig {
- }
- public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
- protected Class>[] getRootConfigClasses() {
- return new Class[]{SpringConfig.class};
- }
-
- protected Class>[] getServletConfigClasses() {
- return new Class[]{SpringMvcConfig.class};
- }
-
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
-
- @Override
- protected Filter[] getServletFilters() {
- CharacterEncodingFilter filter = new CharacterEncodingFilter();
- filter.setEncoding("UTF-8");
- return super.getServletFilters();
- }
- }
- -- ----------------------------
- -- Table structure for tbl_book
- -- ----------------------------
- DROP TABLE IF EXISTS `tbl_book`;
- CREATE TABLE `tbl_book` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE
- ) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Records of tbl_book
- -- ----------------------------
- INSERT INTO `tbl_book` VALUES (1, '计算机理论', 'Spring实战 第5版', 'Spring入门经典教程,深入理解Spring原理技术内幕');
- INSERT INTO `tbl_book` VALUES (2, '计算机理论', 'Spring 5核心原理与30个类手写实战', '十年沉淀之作,手写Spring精华思想');
- INSERT INTO `tbl_book` VALUES (3, '计算机理论', 'Spring 5 设计模式', '深入Spring源码剖析Spring源码中蕴含的10大设计模式');
- INSERT INTO `tbl_book` VALUES (4, '计算机理论', 'Spring MVC+MyBatis开发从入门到项目实战', '全方位解析面向Web应用的轻量级框架,带你成为Spring MVC开发高手');
- INSERT INTO `tbl_book` VALUES (5, '计算机理论', '轻量级Java Web企业应用实战', '源码级剖析Spring框架,适合已掌握Java基础的读者');
- INSERT INTO `tbl_book` VALUES (6, '计算机理论', 'Java核心技术 卷I 基础知识(原书第11版)', 'Core Java 第11版,Jolt大奖获奖作品,针对Java SE9、10、11全面更新');
- INSERT INTO `tbl_book` VALUES (7, '计算机理论', '深入理解Java虚拟机', '5个维度全面剖析JVM,大厂面试知识点全覆盖');
- INSERT INTO `tbl_book` VALUES (8, '计算机理论', 'Java编程思想(第4版)', 'Java学习必读经典,殿堂级著作!赢得了全球程序员的广泛赞誉');
- INSERT INTO `tbl_book` VALUES (9, '计算机理论', '零基础学Java(全彩版)', '零基础自学编程的入门图书,由浅入深,详解Java语言的编程思想和核心技术');
- INSERT INTO `tbl_book` VALUES (10, '市场营销', '直播就该这么做:主播高效沟通实战指南', '李子柒、李佳琦、薇娅成长为网红的秘密都在书中');
- INSERT INTO `tbl_book` VALUES (11, '市场营销', '直播销讲实战一本通', '和秋叶一起学系列网络营销书籍');
- INSERT INTO `tbl_book` VALUES (12, '市场营销', '直播带货:淘宝、天猫直播从新手到高手', '一本教你如何玩转直播的书,10堂课轻松实现带货月入3W+');
- package com.itheima.domain;
-
- public class Book {
- private Integer id;
- private String type;
- private String name;
- private String description;
-
- @Override
- public String toString() {
- return "Book{" +
- "id=" + id +
- ", type='" + type + '\'' +
- ", name='" + name + '\'' +
- ", description='" + description + '\'' +
- '}';
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
- }
- package com.itheima.dao;
-
- import com.itheima.domain.Book;
- import org.apache.ibatis.annotations.Delete;
- import org.apache.ibatis.annotations.Insert;
- import org.apache.ibatis.annotations.Select;
- import org.apache.ibatis.annotations.Update;
-
- import java.util.List;
-
- public interface BookDao {
-
- // @Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
- @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
- public void save(Book book);
-
- @Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
- public void update(Book book);
-
- @Delete("delete from tbl_book where id = #{id}")
- public void delete(Integer id);
-
- @Select("select * from tbl_book where id = #{id}")
- public Book getById(Integer id);
-
- @Select("select * from tbl_book")
- public List
getAll(); - }
- package com.itheima.service;
-
- import com.itheima.domain.Book;
- import org.springframework.transaction.annotation.Transactional;
-
- import java.util.List;
-
- @Transactional
- public interface BookService {
-
- /**
- * 保存
- * @param book
- * @return
- */
- public boolean save(Book book);
-
- /**
- * 修改
- * @param book
- * @return
- */
- public boolean update(Book book);
-
- /**
- * 按id删除
- * @param id
- * @return
- */
- public boolean delete(Integer id);
-
- /**
- * 按id查询
- * @param id
- * @return
- */
- public Book getById(Integer id);
-
- /**
- * 查询全部
- * @return
- */
- public List
getAll(); - }
- package com.itheima.service.impl;
-
- import com.itheima.dao.BookDao;
- import com.itheima.domain.Book;
- import com.itheima.service.BookService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
-
- import java.util.List;
-
- @Service
- public class BookServiceImpl implements BookService {
- @Autowired
- private BookDao bookDao;
-
- public boolean save(Book book) {
- bookDao.save(book);
- return true;
- }
-
- public boolean update(Book book) {
- bookDao.update(book);
- return true;
- }
-
- public boolean delete(Integer id) {
- bookDao.delete(id);
- return true;
- }
-
- public Book getById(Integer id) {
- return bookDao.getById(id);
- }
-
- public List
getAll() { - return bookDao.getAll();
- }
- }
说明 :bookDao在Service中注入的会提示一个红线提示,为什么呢?BookDao 是一个接口,没有实现类,接口是不能创建对象的,所以最终注入的应该是代理对象代理对象是由 Spring 的 IOC 容器来创建管理的IOC 容器又是在 Web 服务器启动的时候才会创建IDEA 在检测依赖关系的时候,没有找到适合的类注入,所以会提示错误提示但是程序运行的时候,代理对象就会被创建,框架会使用 DI 进行注入,所以程序运行无影响。如何解决上述问题?可以不用理会,因为运行是正常的设置错误提示级别

步骤5:编写Contorller类
- package com.itheima.controller;
-
- import com.itheima.domain.Book;
- import com.itheima.service.BookService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- import java.util.List;
-
- @RestController
- @RequestMapping("/books")
- public class BookController {
-
- @Autowired
- private BookService bookService;
-
- @PostMapping
- public boolean save(@RequestBody Book book) {
- return bookService.save(book);
- }
-
- @PutMapping
- public boolean update(@RequestBody Book book) {
- return bookService.update(book);
- }
-
- @DeleteMapping("/{id}")
- public boolean delete(@PathVariable Integer id) {
- return bookService.delete(id);
- }
-
- @GetMapping("/{id}")
- public Book getById(@PathVariable Integer id) {
- return bookService.getById(id);
- }
-
- @GetMapping
- public List
getAll() { - return bookService.getAll();
- }
- }
-
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(classes = SpringConfig.class)
- public class BookServiceTest {
-
-
-
- }
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(classes = SpringConfig.class)
- public class BookServiceTest {
-
- @Autowired
- private BookService bookService;
-
- }
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(classes = SpringConfig.class)
- public class BookServiceTest {
-
- @Autowired
- private BookService bookService;
-
- @Test
- public void testGetById(){
- Book book = bookService.getById(1);
- System.out.println(book);
- }
-
- @Test
- public void testGetAll(){
- List
all = bookService.getAll(); - System.out.println(all);
- }
-
- }
1.5PostMan测试

修改

删除

查询单个

查询所有

为了方便前端对数据进行处理,我们需要在表现层对数据结果进行封装,具体封装形式如下:
- public class Result{
- private Object data;
- private Integer code;
- private String msg;
- }

借用上面的SSM整合
- public class Result {
- //描述统一格式中的数据
- private Object data;
- //描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
- private Integer code;
- //描述统一格式中的消息,可选属性
- private String msg;
-
- public Result() {
- }
-
- public Result(Integer code,Object data) {
- this.data = data;
- this.code = code;
- }
-
- public Result(Integer code, Object data, String msg) {
- this.data = data;
- this.code = code;
- this.msg = msg;
- }
-
- public Object getData() {
- return data;
- }
-
- public void setData(Object data) {
- this.data = data;
- }
-
- public Integer getCode() {
- return code;
- }
-
- public void setCode(Integer code) {
- this.code = code;
- }
-
- public String getMsg() {
- return msg;
- }
-
- public void setMsg(String msg) {
- this.msg = msg;
- }
- }
- package com.itheima.controller;
-
- //状态码
- public class Code {
- public static final Integer SAVE_OK = 20011;
- public static final Integer DELETE_OK = 20021;
- public static final Integer UPDATE_OK = 20031;
- public static final Integer GET_OK = 20041;
-
- public static final Integer SAVE_ERR = 20010;
- public static final Integer DELETE_ERR = 20020;
- public static final Integer UPDATE_ERR = 20030;
- public static final Integer GET_ERR = 20040;
- }
- package com.itheima.controller;
-
- import com.itheima.domain.Book;
- import com.itheima.service.BookService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- import java.util.List;
-
- //统一每一个控制器方法返回值
- @RestController
- @RequestMapping("/books")
- public class BookController {
-
- @Autowired
- private BookService bookService;
-
- @PostMapping
- public Result save(@RequestBody Book book) {
- boolean flag = bookService.save(book);
- return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
- }
-
- @PutMapping
- public Result update(@RequestBody Book book) {
- boolean flag = bookService.update(book);
- return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
- }
-
- @DeleteMapping("/{id}")
- public Result delete(@PathVariable Integer id) {
- boolean flag = bookService.delete(id);
- return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
- }
-
- @GetMapping("/{id}")
- public Result getById(@PathVariable Integer id) {
- Book book = bookService.getById(id);
- Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
- String msg = book != null ? "" : "数据查询失败,请重试!";
- return new Result(code,book,msg);
- }
-
- @GetMapping
- public Result getAll() {
- List
bookList = bookService.getAll(); - Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
- String msg = bookList != null ? "" : "数据查询失败,请重试!";
- return new Result(code,bookList,msg);
- }
- }
- @GetMapping("/{id}")
- public Result getById(@PathVariable Integer id) {
-
- //手动添加一个错误信息
- if(id == 1){
- int i = 1/0;
- }
- Book book = bookService.getById(id);
- Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
- String msg = book != null ? "" : "数据查询失败,请重试!";
- return new Result(code,book,msg);
- }
前端接收到这个信息后和之前我们约定的格式不一致,这个问题该如何解决 ?在解决问题之前,我们先来看下异常的种类及出现异常的原因 :框架内部抛出的异常:因使用不合规导致数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)看完上面这些出现异常的位置,你会发现,在我们开发的任何一个位置都有可能出现异常,而且这些异常是不能避免的。所以我们就得将异常进行处理。
思考1. 各个层级均出现异常,异常处理代码书写在哪一层 ?所有的异常均抛出到表现层进行处理2. 异常的种类很多,表现层如何将所有的异常都处理到呢 ?异常分类3. 表现层处理异常,每个方法中单独书写,代码书写量巨大且意义不强,如何解决 ?AOP对于上面这些问题及解决方案, SpringMVC 已经为我们提供了一套解决方案 :异常处理器 :集中的、统一的处理项目中出现的异常。
- //@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
- @RestControllerAdvice
- public class ProjectExceptionAdvice {
- //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
- @ExceptionHandler(Exception.class)
- public Result doOtherException(Exception ex){
- System.out.println("嘿嘿,异常你哪里跑")
- }
- }
- @GetMapping("/{id}")
- public Result getById(@PathVariable Integer id) {
-
- //手动添加一个错误信息
- if(id == 1){
- int i = 1/0;
- }
- Book book = bookService.getById(id);
- Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
- String msg = book != null ? "" : "数据查询失败,请重试!";
- return new Result(code,book,msg);
- }
-
-
说明异常已经被拦截并执行了doException方法。


系统异常(SystemException)
项目运行过程中可预计但无法避免的异常

3.3.2 异常解决方案
思路 :1. 先通过自定义异常,完成 BusinessException 和 SystemException 的定义2. 将其他异常包装成自定义异常类型3. 在异常处理器类中对不同的异常进行处理
- package com.itheima.exception;
- //自定义异常处理器,用于封装异常信息,对异常进行分类
- public class SystemException extends RuntimeException{
- private Integer code;
-
- public Integer getCode() {
- return code;
- }
-
- public void setCode(Integer code) {
- this.code = code;
- }
-
- public SystemException(Integer code, String message) {
- super(message);
- this.code = code;
- }
-
- public SystemException(Integer code, String message, Throwable cause) {
- super(message, cause);
- this.code = code;
- }
-
- }
- package com.itheima.exception;
- //自定义异常处理器,用于封装异常信息,对异常进行分类
- public class BusinessException extends RuntimeException{
- private Integer code;
-
- public Integer getCode() {
- return code;
- }
-
- public void setCode(Integer code) {
- this.code = code;
- }
-
- public BusinessException(Integer code, String message) {
- super(message);
- this.code = code;
- }
-
- public BusinessException(Integer code, String message, Throwable cause) {
- super(message, cause);
- this.code = code;
- }
-
- }
- public Book getById(Integer id) {
- //模拟业务异常,包装成自定义异常
- if(id == 1){
- throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的 耐性!"); }
- //模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
- try{
- int i = 1/0;
- }catch (Exception e){
- throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重 试!",e);
- }
- return bookDao.getById(id);
- }
- package com.itheima.controller;
-
- public class Code {
- public static final Integer SAVE_OK = 20011;
- public static final Integer DELETE_OK = 20021;
- public static final Integer UPDATE_OK = 20031;
- public static final Integer GET_OK = 20041;
-
- public static final Integer SAVE_ERR = 20010;
- public static final Integer DELETE_ERR = 20020;
- public static final Integer UPDATE_ERR = 20030;
- public static final Integer GET_ERR = 20040;
-
- public static final Integer SYSTEM_ERR = 50001;
- public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
- public static final Integer SYSTEM_UNKNOW_ERR = 59999;
-
- public static final Integer BUSINESS_ERR = 60002;
-
-
-
- }
- package com.itheima.controller;
-
- import com.itheima.exception.BusinessException;
- import com.itheima.exception.SystemException;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- import org.springframework.web.bind.annotation.RestControllerAdvice;
-
- //@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
- @RestControllerAdvice
- public class ProjectExceptionAdvice {
- //@ExceptionHandler用于设置当前处理器类对应的异常类型
- @ExceptionHandler(SystemException.class)
- public Result doSystemException(SystemException ex){
- //记录日志
- //发送消息给运维
- //发送邮件给开发人员,ex对象发送给开发人员
- return new Result(ex.getCode(),null,ex.getMessage());
- }
-
- @ExceptionHandler(BusinessException.class)
- public Result doBusinessException(BusinessException ex){
- return new Result(ex.getCode(),null,ex.getMessage());
- }
-
- //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
- @ExceptionHandler(Exception.class)
- public Result doOtherException(Exception ex){
- //记录日志
- //发送消息给运维
- //发送邮件给开发人员,ex对象发送给开发人员
- return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
- }
- }

首先创建两个自定义异常处理器,继承RuntimeException,并且其方法(主要作用是对异常进行封装),当程序运行出错时,将异常throw/try...catch给响应的自定义处理器,然后在处理类ProjectException中对异常进行拦截操作。

(1)浏览器发送一个请求会先到Tomcat的web服务器
(2)Tomcat 服务器接收到请求以后,会去判断请求的是静态资源还是动态资源(3) 如果是静态资源,会直接到 Tomcat 的项目部署目录下去直接访问(4) 如果是动态资源,就需要交给项目的后台代码进行处理(5) 在找到具体的方法之前,我们可以去配置过滤器 ( 可以配置多个 ) ,按照顺序进行执行(6) 然后进入到到中央处理器 (SpringMVC 中的内容 ) , SpringMVC 会根据配置的规则进行拦截(7) 如果满足规则,则进行处理,找到其对应的 controller 类中的方法进行执行 , 完成后返回结果(8) 如果不满足规则,则不进行处理(9) 这个时候,如果我们需要在每个 Controller 方法执行的前后添加业务,具体该如何来实现 ?这个就是拦截器要做的事。拦截器( Interceptor )是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法的执行作用:在指定的方法调用前后执行预先设定的代码阻止原始方法的执行总结:拦截器就是用来做增强
拦截器和过滤器之间的区别是什么?归属不同: Filter 属于 Servlet 技术, Interceptor 属于 SpringMVC 技术拦截内容不同: Filter 对所有访问进行增强, Interceptor 仅针对 SpringMVC 的访问进行增强
- <dependencies>
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>3.1.0version>
- <scope>providedscope>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webmvcartifactId>
- <version>5.2.10.RELEASEversion>
- dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.9.0version>
- dependency>
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.tomcat.mavengroupId>
- <artifactId>tomcat7-maven-pluginartifactId>
- <version>2.1version>
- <configuration>
- <port>80port>
- <path>/path>
- configuration>
- plugin>
- <plugin>
- <groupId>org.apache.maven.pluginsgroupId>
- <artifactId>maven-compiler-pluginartifactId>
- <configuration>
- <source>8source>
- <target>8target>
- configuration>
- plugin>
- plugins>
- build>
- public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
- protected Class>[] getRootConfigClasses() {
- return new Class[0];
- }
-
- protected Class>[] getServletConfigClasses() {
- return new Class[]{SpringMvcConfig.class};
- }
-
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
-
- //乱码处理
- @Override
- protected Filter[] getServletFilters() {
- CharacterEncodingFilter filter = new CharacterEncodingFilter();
- filter.setEncoding("UTF-8");
- return new Filter[]{filter};
- }
- }
- @Configuration
- @ComponentScan({"com.itheima.controller"})
- @EnableWebMvc
- //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
- public class SpringMvcConfig {
-
- }
- public class Book {
- private String name;
- private double price;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public double getPrice() {
- return price;
- }
-
- public void setPrice(double price) {
- this.price = price;
- }
-
- @Override
- public String toString() {
- return "Book{" +
- "书名='" + name + '\'' +
- ", 价格=" + price +
- '}';
- }
- }
- @RestController
- @RequestMapping("/books")
- public class BookController {
-
- @PostMapping
- public String save(@RequestBody Book book){
- System.out.println("book save..." + book);
- return "{'module':'book save'}";
- }
-
- @DeleteMapping("/{id}")
- public String delete(@PathVariable Integer id){
- System.out.println("book delete..." + id);
- return "{'module':'book delete'}";
- }
-
- @PutMapping
- public String update(@RequestBody Book book){
- System.out.println("book update..."+book);
- return "{'module':'book update'}";
- }
-
- @GetMapping("/{id}")
- public String getById(@PathVariable Integer id){
- System.out.println("book getById..."+id);
- return "{'module':'book getById'}";
- }
-
- @GetMapping
- public String getAll(){
- System.out.println("book getAll...");
- return "{'module':'book getAll'}";
- }
- }
- @Component
- //定义拦截器类,实现HandlerInterceptor接口
- //注意当前类必须受Spring容器控制
- public class ProjectInterceptor implements HandlerInterceptor {
- @Override
- //原始方法调用前执行的内容
- //返回值类型可以拦截控制的执行,true放行,false终止
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- String contentType = request.getHeader("Content-Type");
- HandlerMethod hm = (HandlerMethod)handler;
- System.out.println("preHandle..."+contentType);
- return true;
- }
-
- @Override
- //原始方法调用后执行的内容
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle...");
- }
-
- @Override
- //原始方法调用完成后执行的内容
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("afterCompletion...");
- }
- }
- @Configuration
- public class SpringMvcSupport extends WebMvcConfigurationSupport {
- @Autowired
- private ProjectInterceptor projectInterceptor;
-
- @Override
- protected void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
- }
-
- @Override
- protected void addInterceptors(InterceptorRegistry registry) {
- //配置拦截器
- registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
- }
- }
- @Configuration
- @ComponentScan({"com.itheima.controller","com.itheima.config"})
- @EnableWebMvc
- public class SpringMvcConfig implements WebMvcConfigurer {
- }
如果发送http://localhost/books/100会发现拦截器没有被执行,原因是拦截器的
- @Configuration
- public class SpringMvcSupport extends WebMvcConfigurationSupport {
- @Autowired
- private ProjectInterceptor projectInterceptor;
-
- @Override
- protected void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
- }
-
- @Override
- protected void addInterceptors(InterceptorRegistry registry) {
- //配置拦截器
- registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
- }
- }
- @Configuration
- @ComponentScan({"com.itheima.controller"})
- @EnableWebMvc
- //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
- public class SpringMvcConfig implements WebMvcConfigurer {
- @Autowired
- private ProjectInterceptor projectInterceptor;
- @Autowired
- private ProjectInterceptor2 projectInterceptor2;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- //配置多拦截器
- registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
- registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
- }
- }
5.3.3 完成处理方法
- @Component
- public class ProjectInterceptor2 implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- // String contentType = request.getHeader("Content-Type");
- // HandlerMethod hm = (HandlerMethod)handler;
- System.out.println("preHandle...222");
- return false;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle...222");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("afterCompletion...222");
- }
- }
- @Configuration
- @ComponentScan({"com.itheima.controller"})
- @EnableWebMvc
- //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
- public class SpringMvcConfig implements WebMvcConfigurer {
- @Autowired
- private ProjectInterceptor projectInterceptor;
- @Autowired
- private ProjectInterceptor2 projectInterceptor2;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- //配置多拦截器
- registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
- registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
- }
- }