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

目录

一、前提

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

三、拦截器

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

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ambition…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值