使用统一功能完善图书管理系统

目录

一、前提

二、实现强制登陆传统方式

三、拦截器

1、概念

2、拦截器

(1)定义拦截器

(2)注册拦截器

(3)运行

3、使用拦截器实现强制登陆

4、DispatcherServlet源码解析

四、适配器模式

1、适配器模式概念

2、适配器模式角色

3、适配器应用场景

五、统一数据格式返回

1、对后端响应结果进行统一

2、对于不同状态执行不同方法

3、统一功能实现

4、统一功能实现存在的问题

六、统一异常处理

七、图书管理系统部分重要代码

1、登陆功能

2、增加图书功能

3、显示图书列表功能

4、更新图书功能

5、删除图书功能


一、前提

设计一个图书管理系统,具有:登陆功能、显示图书列表功能、增加图书、更新图书、删除图书、批量删除图书、强制登陆。目前已经实现了前6个功能,借助myBatis,以及一些插件:分页展示、批量选择等,所涉及到的知识点前面文章已详细介绍,此处就不再详细展开了,文章后面会附上关键代码(后端响应和前端请求)。

二、实现强制登陆传统方式

除登陆页面外,在每个页面执行请求前,先根据session判断是否登陆,未登陆的返回状态码401,前端接收到401状态码后跳转到登陆页面,若已经登陆,则返回body即可,默认状态码为200。

该方式在前面博客,基于sevlet实现博客系统已实现,此处就不再编写代码了。

我们想一个问题:除登陆页面外,每次在其他页面实现请求时都要检查是否登陆,我们可否对于这些请求进行同一拦截,并进行session检验---拦截器。

三、拦截器

1、概念

是spring框架提供的功能,对于指定请求,可以在方法前后执行指定的预代码,对于请求方法前的预代码,返回结果为true是才会进入请求方法。

2、拦截器

对于强制登陆,我们希望在执行方法前就进行判断是否登陆,利用拦截器,若未登陆,结束响应。

(1)定义拦截器

实现Handlerlnterceptor接口,并重写所有方法。

①preHandle方法:目标方法执行前执行。返回true,执行目标方法;返回false,中断执行。

②postHandle方法:目标方法执行完成后执行。

③afterCompletion方法:视图渲染后执行,最后执行。

(2)注册拦截器

实现WebMvcConfigurer接口,重写addInterceptors方法。

(3)运行
3、使用拦截器实现强制登陆

(1)定义

(2)注册

(3)运行

当完成登录后就可以访问了。

4、DispatcherServlet源码解析

当tomcat服务器启动后,有一个核心类---DispatcherServlet,由他控制程序的执行顺序。

(1)该类的初始化--init方法

在其父类HttpServletBean中实现了init方法,主要用来加载 web.xml 中 DispatcherServlet 的 配置, 并调⽤⼦类的初始化。

(2)initServletBean()方法

在HttpServletBean类的init方法中,调用了其父类FrameworkServlet的initServletBean方法,主要是用来建立上下文(运行环境,WebApplicationContext容器),并加载SpringMvc配置文件中定义的bean到该容器中,最后将容器添加到ServletContext中。

(3)initStrategies()方法

在DispatcherServlet类中,调用了initDStrategies方法,该方法可以进行九大组件的初始化,如果没有配置相应的组件,就使用默认定义的组件。

(4)doDispatch()方法

DispatcherServlet类在接收到请求后,会调用doDispatch方法,进行调度,将请求转给Controller

执行步骤:①遍历所有的HandlerMapping,找到与请求对应的Handler;②遍历所有的HandlerAdapter(适配器),找到可以处理该Handler的HandlerAdapter。③执行拦截器的preHandle方法;④执行目标方法;⑤执行拦截器postHndle方法;⑥处理视图,处理完成后执行拦截器的afterCompletion方法。

四、适配器模式

上面在执行doDispatch()方法时,使用到了适配器,使得在执行不同的请求时,例如:Controller、Servlet等,这些类的调用过程类实现了适配器的接口,使得适配器对于不同请求也能做出响应。

1、适配器模式概念

用于将一个类的接口转换为客户端目标的接口。

2、适配器模式角色

(1)target:目标接口,客回端希望的接口;

(2)Adaptee:适配者,与目标接口不兼容;适配器

(3)Adapter:适配器类,通过继承或向下转型将适配者转为目标接口;

(4)client:需要使用适配器的对象。

3、适配器应用场景

可以用来补救设计上的缺陷,设计之初若解决接口不兼容的问题,就可以不使用适配器模式了。

五、统一数据格式返回

为了使代码更规范,可以使响应可以具有统一的返回格式,也提高了前端与后端人员的沟通效率。方便前端人员解析响应。

针对上述图书管理系统,进行统一数据格式返回,返回有3种状态:①未登录,401(拦截器已实现);②已登陆,但出现异常;③已登录且成功响应。

1、对后端响应结果进行统一
2、对于不同状态执行不同方法
3、统一功能实现

实现ResponseBodyAdvice接口,加上@ControllerAdvice注解,重写supports和beforeBodyWrite方法。

supports():判断是否要执行beforeBodyWrite方法,true时执行,false时不执行

beforeBodyWrite():对后端的响应结果进行从处理。

没有进行统一功能时返回的结果:

进行统一功能返回的结果:

4、统一功能实现存在的问题

(1)结果重复包装

试想一下,若我们返回的结果本来就是统一结果的类型,是否会对结果再次包装???

访问url:发现结果重复包装

做出修改:

(2)响应内容是字符串时无法进行包装

①结果是Integer类型

②结果是boolean类型

③结果是String类型

发现报错了,500是后端代码出错。查看日志:

读源码发现:当返回的数据是⾮字符串时, 使⽤的 MappingJackson2HttpMessageConverter 写⼊返回对象;当返回的数据是字符串时, StringHttpMessageConverter 会先被遍历到,这时会认为 StringHttpMessageConverter可以使⽤。由于 StringHttpMessageConverter 重写了addDefaultHe-aders方法,所以会执⾏⼦类的⽅法,然⽽⼦类 StringHttpMessageConverter 的addDefaultH-eaders⽅法定义接收参数为String, 统一结果处理后,此时UnifiedResult类型, 所以出现类型不匹配"UnifiedResult cannot be cast to java.lang.String"的异常

解决方法:将结果修改为json类型

(3)对于异常结果无法返回正确代码状态

以上出现空指针异常,服务器状态码已经为500了,失败状态,结果里的200也应该为-1,代表失败,但是返回的还是200,是因为没有对异常进行处理,使得结果调用的都是success方法,对异常处理,出现异常调用fail方法。

六、统一异常处理

@ControllerAdvice+@ResponseBody+@ExceptionHandler+异常捕获

访问url:

上面异常继承关系:NullPointerException---->RuntimeException---->Exception

注:若没有NullPointerException异常声明,则会报运行异常RuntimeException;若没有NullPointerException和RuntimeException异常声明,则会报异常Exception。

七、图书管理系统部分重要代码

1、登陆功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

2、增加图书功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

3、显示图书列表功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

4、更新图书功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

5、删除图书功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

6、批量删除功能

(1)前端请求+处理后端响应:

(2)后端处理请求:

注:

若需要全部源码,可以进入:葛雅宁 (ge-yaning) - Gitee.com

点击java学习下的myBookSystem

相关推荐
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
hanbarger4 小时前
mybatis框架——缓存,分页
java·spring·mybatis
龙少95436 小时前
【深入理解@EnableCaching】
java·后端·spring
啦啦右一12 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
荆州克莱15 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei16 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
火烧屁屁啦16 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
岁岁岁平安16 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
北辰浮光16 小时前
[spring]XML配置文件标签
xml·spring
ZSYP-S17 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring