SpringMVC-异步调用,拦截器与异常处理

1.异步调用

1.发送异步请求

<a href="javascript:void(0);" id="testAjax">访问controller</a>
<script type="text/javascript" src="js/jquery-3.7.1.js"></script>
<script type="text/javascript">$(function(){$("#testAjax").click(function(){ //为id="testAjax"的组件绑定点击事件$.ajax({ //发送异步调用type:"POST", //请求方式: POST请求url:"ajaxController", //请求参数(也就是请求内容)data:'ajax message', //请求参数(也就是请求内容)dataType:"text", //响应正文类型contentType:"application/text", //请求正文的MIME类型});});
});
</script>

接收异步请求参数

名称: @RequestBody

类型: 形参注解

位置:处理器类中的方法形参前方

作用:将异步提交数据组织成标准请求参数格式,并赋值给形参

范例

@RequestMapping("/ajaxController")
public String ajaxController(@RequestBody String message){System.out.println(message);return "page.jsp";
}  

注解添加到Pojo参数前方时,封装的异步提交数据按照Pojo的属性格式进行关系映射

注解添加到集合参数前方时,封装的异步提交数据按照集合的存储结构进行关系映射

@RequestMapping("/ajaxPojoToController")
//如果处理参数是POJO,且页面发送的请求数据格式与POJO中的属性对应,@RequestBody注解可以自动映射对应请求数据到POJO中
//注意:POJO中的属性如果请求数据中没有,属性值为null,POJO中没有的属性如果请求数据中有,不进行映射
public String  ajaxPojoToController(@RequestBody User user){System.out.println("controller pojo :"+user);return "page.jsp";
}@RequestMapping("/ajaxListToController")
//如果处理参数是List集合且封装了POJO,且页面发送的数据是JSON格式的对象数组,数据将自动映射到集合参数中
public String  ajaxListToController(@RequestBody List<User> userList){System.out.println("controller list :"+userList);return "page.jsp";
}

2.异步请求接受响应数据

方法返回值为Pojo时,自动封装数据成json对象数据

@RequestMapping("/ajaxReturnJson")
@ResponseBody
public User ajaxReturnJson(){System.out.println("controller return json pojo...");User user = new User();user.setName("Jockme");user.setAge(40);return user;
}  
@RequestMapping("/ajaxReturnJsonList")
@ResponseBody
//基于jackon技术,使用@ResponseBody注解可以将返回的保存POJO对象的集合转成json数组格式数据
public List ajaxReturnJsonList(){System.out.println("controller return json list...");User user1 = new User();user1.setName("Tom");user1.setAge(3);User user2 = new User();user2.setName("Jerry");user2.setAge(5);ArrayList al = new ArrayList();al.add(user1);al.add(user2);return al;
}

3.跨域访问

跨域访问介绍

当通过域名A下的操作访问域名B下的资源时,称为跨域访问

跨域访问时,会出现无法访问的现象

跨域环境搭建

为当前主机添加备用域名

        修改windows安装目录中的host文件

        格式:ip 域名

动态刷新DNS

        命令:ipconfig /displaydns

        命令:ipconfig /flushdns

跨域访问支持

名称: @CrossOrigin

类型: 方法注解 、 类注解

位置:处理器类中的方法上方 或 类上方

作用:设置当前处理器方法/处理器类中所有方法支持跨域访问

@RequestMapping("/cross")
@ResponseBody
//使用@CrossOrigin开启跨域访问
//标注在处理器方法上方表示该方法支持跨域访问
//标注在处理器类上方表示该处理器类中的所有处理器方法均支持跨域访问
@CrossOrigin
public User cross(HttpServletRequest request){System.out.println("controller cross..."+request.getRequestURL());User user = new User();user.setName("ljb");user.setAge(21);return user;
}

2.拦截器

1.拦截器概述

请求处理过程解析

拦截器( Interceptor)是一种动态拦截方法调用的机制

作用:

在指定的方法调用前后执行预先设定后的的代码

阻止原始方法的执行

核心原理: AOP思想

拦截器链:多个拦截器按照一定的顺序,对原始被调用功能进行增强

拦截器VS过滤器

归属不同: Filter属于Servlet技术, Interceptor属于SpringMVC技术

拦截内容不同: Filter对所有访问进行增强, Interceptor仅针对SpringMVC的访问进行增强

2.自定义拦截器的开发

package com.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class InterceptorController {@RequestMapping("/handleRun")public String handleRun(){System.out.println("业务处理器运行---------main");return "page.jsp";}
}

实现HandlerInterceptor接口

package com.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;//自定义拦截器需要实现HandleInterceptor接口
public class MyInterceptor implements HandlerInterceptor {//处理器运行之前执行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前置运行----a1");//返回值为false将拦截原始处理器的运行//如果配置多拦截器,返回值为false将终止当前拦截器后面配置的拦截器的运行return true;}//处理器运行之后执行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置运行----b1");}//所有拦截器的后置执行全部结束后,执行该操作@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("完成运行----c1");}//三个方法的运行顺序为    preHandle -> postHandle -> afterCompletion//如果preHandle返回值为false,三个方法仅运行preHandle
}
 <context:component-scan base-package="com"/><mvc:interceptors><mvc:interceptor><mvc:mapping path="/handleRun"/><bean class="com.interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors><mvc:annotation-driven/>

 注意:配置顺序为先配置执行位置,后配置执行类

3.拦截器配置与方法参数 

前置处理方法

原始方法之前运行

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

参数:

request:请求对象

response:响应对象

handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装

返回值:

返回值为false,被拦截的处理器将不执行

后置处理方法

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

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

参数:

modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整

完成处理方法

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

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

参数:

ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理

拦截器配置项

<mvc:interceptors><!--开启具体的拦截器的使用,可以配置多个--><mvc:interceptor><!--设置拦截器的拦截路径,支持*通配--><!--/**         表示拦截所有映射--><!--/*          表示拦截所有/开头的映射--><!--/user/*     表示拦截所有/user/开头的映射--><!--/user/add*  表示拦截所有/user/开头,且具体映射名称以add开头的映射--><!--/user/*All  表示拦截所有/user/开头,且具体映射名称以All结尾的映射--><mvc:mapping path="/*"/><mvc:mapping path="/**"/><mvc:mapping path="/handleRun*"/><!--设置拦截排除的路径,配置/**或/*,达到快速配置的目的--><mvc:exclude-mapping path="/b*"/><!--指定具体的拦截器类--><bean class="MyInterceptor"/></mvc:interceptor>
</mvc:interceptors>

4.多拦截器配置

当配置多个拦截器时,形成拦截器链

拦截器链的运行顺序参照配置的先后顺序

当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行

当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

附:责任链模式 

责任链模式是一种行为模式

特征:

沿着一条预先设定的任务链顺序执行,每个节点具有独立的工作任务

优势:

独立性:只关注当前节点的任务,对其他任务直接放行到下一节点

隔离性:具备链式传递特征,无需知晓整体链路结构,只需等待请求到达后进行处理即可

灵活性:可以任意修改链路结构动态新增或删减整体链路责任

解耦:将动态任务与原始任务解耦

弊端:

链路过长时,处理效率低下

可能存在节点上的循环引用现象,造成死循环,导致系统崩溃

3.异常处理

1.异常处理器

HandlerExceptionResolver接口(异常处理器)

@Component
public class ExceptionResolver implements HandlerExceptionResolver {public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {System.out.println("my exception is running...");ModelAndView modelAndView = new ModelAndView();//定义异常现象出现后,反馈给用户查看的信息modelAndView.addObject("msg","出错啦! ");//定义异常现象出现后,反馈给用户查看的页面modelAndView.setViewName("error.jsp");return modelAndView;}
}

根据异常的种类不同,进行分门别类的管理,返回不同的信息

public class ExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {System.out.println("my exception is running ...."+ex);ModelAndView modelAndView = new ModelAndView();if( ex instanceof NullPointerException){modelAndView.addObject("msg","空指针异常");}else if ( ex instanceof  ArithmeticException){modelAndView.addObject("msg","算数运算异常");}else{modelAndView.addObject("msg","未知的异常");}modelAndView.setViewName("error.jsp");return modelAndView;}
}

2.注解开发异常处理器

使用注解实现异常分类管理

名称: @ControllerAdvice

类型: 类注解

位置:异常处理器类上方

作用:设置当前类为异常处理器类

名称: @ExceptionHandler

类型: 方法注解

位置:异常处理器类中针对指定异常进行处理的方法上方

作用:设置指定异常的处理方式

@Component
@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(Exception.class)@ResponseBodypublic String doNullException(Exception ex){return "空指针异常";}}

3.异常处理解决方案 

 

4.自定义异常

package com.exception;//自定义异常继承RuntimeException,覆盖父类所有的构造方法
public class BusinessException extends RuntimeException {public BusinessException() {}public BusinessException(String message) {super(message);}public BusinessException(String message, Throwable cause) {super(message, cause);}public BusinessException(Throwable cause) {super(cause);}public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

异常触发方式

if(user.getName().trim().length()<4) {throw new BusinessException("用户名长度必须在2-4位之间,请重新输入! ");
}

通过自定义异常将所有的异常现象进行分类管理,以统一的格式对外呈现异常消息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/727089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言学习--练习2

目录 1.排序数组 2.多数元素 3.存在重复元素 4.最大间距 5.按奇偶排序数组 6.最小时间差 1.排序数组 /*** Note: The returned array must be malloced, assume caller calls free().*/ int cmp(const void*a,const void*b){return *(int*)a-*(int*)b; } int* sortArray(i…

C语言抽象代码(其五)

水博客 今天突发奇想&#xff0c;可不可以用中文写代码。 然后我发现可以用#define完成。 我们看代码 非常好理解就是用前面代替后面。比如&#xff1a; 主函数 代替 int main 非常简单

二叉搜索树题目:二叉搜索树迭代器

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉搜索树迭代器 出处&#xff1a;173. 二叉搜索树迭代器 难度 4 级 题目…

计讯物联智慧工业园区系统平台全面提升园区智能化水平

工业园区聚集着各种生产要素&#xff0c;是纺织、机械、家具等诸多产业集中的区域&#xff0c;更是资源消耗和污染物排放的集中地。根据某些工业园区环境调研&#xff0c;园区入驻企业从生产原料到生产制造过程大多带有有毒有害、易燃易爆的特性&#xff0c;再加上装置大型化、…

SpringBoot 热部署。

SpringBoot 热部署。 文章目录 SpringBoot 热部署。 pom.xml。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional…

LeetCode-第137题-只出现一次的数||

1.题目描述 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 2.样例描述 3.思路描述 先把数组排序&am…

M2TS转MP4怎么转?超快的方法~

M2TS格式的优点主要体现在对高清视频的完美支持&#xff0c;能够提供极致的视觉体验。然而&#xff0c;由于其相对较大的文件大小&#xff0c;有时可能不太适合网络传输。此外&#xff0c;部分不支持M2TS的播放设备可能导致一定的兼容性问题。 想要播放m2ts视频&#xff0c;可…

【kubernetes】关于k8s集群如何将pod调度到指定node节点?

目录 一、k8s的watch机制 二、scheduler的调度策略 Predicate&#xff08;预选策略&#xff09; 常见算法&#xff1a; priorities&#xff08;优选策略&#xff09;常见的算法有&#xff1a; 三、k8s的标签管理之增删改查 四、k8s的将pod调度到指定node的方法 方案一&am…

DFS回溯-经典全排列问题(力扣)

前言 对于全排列问题&#xff0c;常用的做法是设置一个vis数组来确定位置i上的数字是否被访问&#xff0c;因为是全排列问题&#xff0c;所以不同的顺序也是不一样的排列&#xff0c;因此每次都是从起点开始询问**(注意起点到底是0还是1)** 46全排列(最简单的模板) class So…

某资产管理系统打点过程中的免杀经历

上周&#xff0c;被扔过来单位内部的一个链接&#xff0c;让渗透一下&#xff0c;本以为三下五除二很快就能测完&#xff0c;没想到在对抗杀软时费了一番功夫&#xff0c;再加上杂七杂八的事儿&#xff0c;经过了一个星期才测完(&#xff03;&#xffe3;&#xff5e;&#xff…

C#知识点-21(初识数据库)

数据库与内存、文件的比较 内存&#xff1a; 优点&#xff1a;存取速度快 缺点&#xff1a;-容量小 -断电后&#xff0c;数据不会保存 文件&#xff1a; 优点&#xff1a;数据可以持久化保存 缺点&#xff1a;-读取速度慢…

mprpc分布式RPC网络通信框架

mprpc 项目介绍 该项目是一个基于muduo、Protobuf和Zookeeper实现的轻量级分布式RPC网络通信框架。 可以把任何单体架构系统的本地方法调用&#xff0c;重构成基于TCP网络通信的RPC远程方法调用&#xff0c;实现同一台机器的不同进程之间的服务调用&#xff0c;或者不同机器…

下载无水印抖音视频

在抖音看到某些视频想下载&#xff0c;却出现无法保存在本地【显示"作品暂时无法保存,链接已复制"】。或者下载的视频有水印。 而某些微信小程序下载可能需要付费或者有水印。其实我们可以直接使用电脑浏览器直接下载。 举个例子: 这是来自王道官方账号的一条视频链…

基于springboot的某大学外卖系统的实现(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能实现 1 后台登录 2管理员界面 3员工信息管理 4客户信息管理 三、库表设计 四、论文 前言 如今&#xff0c;信息化不断的高速发展&#xff0c;社会也跟着不断进步&#xff0c;现今的社会&#xff0c;各种工作都离不开信息化技…

Python基础二

一、变量 在编程中&#xff0c;变量是用来存储数据值的名称。在 Python 中&#xff0c;变量是动态类型的&#xff0c;这意味着你可以将任何类型的数据分配给一个变量&#xff0c;而不需要提前声明变量的类型。 1、全局变量 在函数外部定义的变量是全局变量&#xff0c;可以在程…

boost 编译

参考博客&#xff1a;vs2019 boost 入坑指南 boost下载 官方网站&#xff1a;https://www.boost.org/ 下面以boost_1_73_0为例&#xff1a; boost编译 解压boost_1_73_0.zip运行bootstrap.bat&#xff08;此时目录下会生成b2.exe&#xff09;编译boost b2 install --build…

【vue2项目总结】——动态渲染

文章目录 主页渲染封装接口页面调用传到子组件 搜索列表渲染根据关键字搜索分类id搜索 主页渲染 封装接口 封装准备接口 api/home.js import request from /utils/request// 获取首页数据 export const getHomeData () > {return request.get(/page/detail, {params: {p…

springboot3.x集成SpringDoc Swagger3

近期将springboox2.x升级到了3.x&#xff0c;索性将swagger2也同步升级到swagger3&#xff0c;具体过程如下。 一、添加maven依赖 <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>…

用户角色的重要性:确保财务数据安全的最佳方式

在企业的财务管理业务中&#xff0c;一个人几乎不可能完成所有的财务记账任务&#xff0c;例如设定预算、发票审批等等&#xff0c;至少不能有效地执行。最为明智的方式&#xff0c;是将这些任务分派给特定的人员&#xff0c;比如部门经理、财务经理或者销售、市场人员等等。 但…

C++读取NC数据的结果与真实数值不一致的解决方法

本文介绍基于C 语言的netCDF库读取.nc格式的栅格文件时&#xff0c;代码读取到的数据与栅格文件的实际数据不一致的解决方法。 最近&#xff0c;由于需要读取ERA5气象数据&#xff0c;因此使用C 语言中的netCDF库读取.nc格式文件。其中&#xff0c;偶然发现在Visual Studio的代…