【SSM】SSM框架整合入门(二)

前后台协议联调

环境准备

参考SSM框架整合入门(一),同时在WebApp下添加静态资源。
因为添加了静态资源,SpringMVC会拦截,所有需要在SpringConfig的配置类中将静态资源进行放行。
新建SpringMvcSupport

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

在SpringMvcConfig中扫描SpringMvcSupport

@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}

列表功能

需求:页面加载完后发送异步请求到后台获取列表数据进行展示。
1.找到页面的钩子函数,created()
2. created()方法中调用了this.getAll()方法
3.在getAll()方法中使用axios发送异步请求从后台获取数据
4.访问的路径为http://localhost/ssm/books
5.返回数据

getAll() {
//发送ajax请求
axios.get("/books").then((res)=>{
this.dataList = res.data.data;
});
}

在这里插入图片描述

添加功能

需求:完成图片的新增功能模块
1.找到页面上的新建按钮,按钮上绑定了@click="handleCreate()"方法
2.在method中找到handleCreate方法,方法中打开新增面板
3.新增面板中找到确定按钮,按钮上绑定了@click="handleAdd()"方法
4.在method中找到handleAdd方法
5.在方法中发送请求和数据,响应成功后将新增面板关闭并重新查询数据

handleCreate打开新增面板

 				//弹出添加窗口
                handleCreate() {
                    this.dialogFormVisible = true;
                    this.resetForm();
                },

handleAdd方法发送异步请求并携带数据

handleAdd () {
//发送ajax请求
//this.formData是表单中的数据,最后是一个json数据
axios.post("/books",this.formData).then((res)=>{
	this.dialogFormVisible = false;
	this.getAll();
});
}

添加功能状态处理

基础的新增功能已经完成,但是还有一些问题需要解决下:

需求:新增成功是关闭面板,重新查询数据,那么新增失败以后该如何处理?
1.在handlerAdd方法中根据后台返回的数据来进行不同的处理
2.如果后台返回的是成功,则提示成功信息,并关闭面板
3.如果后台返回的是失败,则提示错误信息

//添加
                handleAdd () {
                    axios.post("/ssm/books",this.formData).then((resp)=>{
                        if (resp.data.code == 20011){
                            this.dialogFormVisible = false;
                            this.$message.success("添加成功")
                        }else if (resp.data.code == 20010){
                            this.$message.error("添加失败")
                        }else {
                            this.$message.error(resp.data.msg);
                        }
                    }).finally(()=>{
                        this.getAll();
                    });
                }

修改功能

需求:完成图书信息的修改功能
1.找到页面中的编辑按钮,该按钮绑定了@click=“handleUpdate(scope.row)”
2.在method的handleUpdate方法中发送异步请求根据ID查询图书信息
3.根据后台返回的结果,判断是否查询成功
如果查询成功打开修改面板回显数据,如果失败提示错误信息
4.修改完成后找到修改面板的确定按钮,该按钮绑定了@click=“handleEdit()”
5.在method的handleEdit方法中发送异步请求提交修改数据
6.根据后台返回的结果,判断是否修改成功
如果成功提示错误信息,关闭修改面板,重新查询数据,如果失败提示错误信息

修改handleUpdate方法

//弹出编辑窗口
                handleUpdate(row) {
                    axios.get("/ssm/books/"+row.id).then((res)=>{
                        if (res.data.code==20041){
                            this.formData = res.data.data;
                            this.dialogFormVisible4Edit = true;
                        }else {
                            this.$message.error(res.data.msg);
                        }
                    });
                },

修改handleEdit方法

 //编辑
                handleEdit() {
                    axios.put("/ssm/books",this.formData).then((res)=>{
                        if (res.data.code == 20031){
                            this.dialogFormVisible4Edit = false;
                            this.$message.success("修改成功")
                        }else if(res.data.code == 20030){
                            this.$message.error("修改失败");
                        }else {
                            this.$message.error(res.data.msg);
                        }
                    }).finally(()=>{
                        this.getAll();
                    })
                },

删除功能

需求:完成页面的删除功能。
1.找到页面的删除按钮,按钮上绑定了@click=“handleDelete(scope.row)”
2.method的handleDelete方法弹出提示框
3.用户点击取消,提示操作已经被取消。
4.用户点击确定,发送异步请求并携带需要删除数据的主键ID
5.根据后台返回结果做不同的操作
如果返回成功,提示成功信息,并重新查询数据
如果返回失败,提示错误信息,并重新查询数据

修改handleDelete方法

                // 删除
                handleDelete(row) {
                    this.$confirm("此操作将永久删除当前数据,是否继续?","提示",{type: 'info'}).then(()=>{
                        axios.delete("/ssm/books/"+row.id).then((res)=>{
                            if (res.data.code == 20021){
                                this.$message.success("删除成功");
                            }else{
                                this.$message.error("删除失败")
                            }
                        }).finally(()=>{
                            this.getAll();
                        });
                    }).catch(()=>{
                        this.$message.info("取消删除操作");
                    })
                }

拦截器

拦截器概念

拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。
作用:

  • 在指定的方法调用前后执行预先设定的代码
  • 阻止原始方法的执行

总结:拦截器就是用来做增强的。
介绍完拦截器,大家会发现拦截器和过滤器在作用和执行顺序上很相似。
所以这个时候,就有一个问题需要思考:拦截器和过滤器之间的区别是什么?

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅对SpringMVC的访问进行增强。

拦截器入门案例

环境准备:使用SSM框架整合入门(一)中的项目
拦截器开发,开发的步骤如下:

  1. 创建拦截器类

在controller包下创建interceptor包,在interceptor包下创建拦截器类,让类实现HandlerInterceptor接口,重写接口中的三个方法。

//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
@Component
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        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...");
    }
}
  1. 配置拦截器类
@Configuration //设置静态资源访问过滤,当前类需要被设置为配置类,并被扫描加载
public class SpringMVCSupport extends WebMvcConfigurationSupport {

    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问/pages/??时候,从/pages目录下查询内容
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books");
    }
}
  1. 在SpringMVC配置类中添加包扫描
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
  1. 运行测试测试

向http://localhost:8080/ssm2/books发送GET请求
控制台打印结果如下:

  1. 修改拦截器拦截规则

通过修改拦截器拦截规则,下次访问http://localhost:8080/ssm2/books/100,拦截器也会被执行。

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }

拦截器参数

前置处理方法
原始方法之前运行preHandle

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        return true;
    }

request:请求对象
response:响应对象
handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装
使用request对象可以获取请求数据中的内容,如获取请求头的Content-Type

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	String contentType = request.getHeader("Content-Type");
	System.out.println("preHandle..."+contentType);
	return true;
}

使用handler参数,可以获取方法的相关信息

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	HandlerMethod hm = (HandlerMethod)handler;
	String methodName = hm.getMethod().getName();//可以获取方法的名称
	System.out.println("preHandle..."+methodName);
	return true;
}

后置处理方法
原始方法运行后运行,如果原始方法被拦截,则不执行

public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,
ModelAndView modelAndView) throws Exception {
	System.out.println("postHandle");
}

前三个参数和上面的是一致的。
modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整
因为咱们现在都是返回json数据,所以该参数的使用率不高。

完成处理方法
拦截器最后执行的方法,无论原始方法是否执行

public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
	System.out.println("afterCompletion");
}

前三个参数与上面的是一致的。
ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理
因为我们现在已经有全局异常处理器类,所以该参数的使用率也不高。

这三个方法中,最常用的是preHandle,在这个方法中可以通过返回值来决定是否要进行放行,我们
可以把业务逻辑放在该方法中,如果满足业务则返回true放行,不满足则返回false拦截。

拦截器链配置

配置多个拦截器

  • 步骤1:创建拦截器类
  • 步骤2:配置拦截器类
  • 步骤3:运行程序,观察顺序

拦截器执行的顺序是和配置顺序有关。就和前面所提到的运维人员进入机房的案例,先进后出。
当配置多个拦截器时,形成拦截器链
拦截器链的运行顺序参照拦截器添加顺序为准
当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

preHandle:与配置顺序相同,必定运行
postHandle:与配置顺序相反,可能不运行
afterCompletion:与配置顺序相反,可能不运行。
这个顺序不太好记,最终只需要把握住一个原则即可:以最终的运行结果为准

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值