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 {
    //处理器运行之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("前置运行----a1");
        //返回值为false将拦截原始处理器的运行
        //如果配置多拦截器,返回值为false将终止当前拦截器后面配置的拦截器的运行
        return true;
    }

    //处理器运行之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("后置运行----b1");
    }

    //所有拦截器的后置执行全部结束后,执行该操作
    @Override
    public 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 {
    @Override
    public 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)
    @ResponseBody
    public 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位之间,请重新输入! ");
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示

文章目录 问题描述解决方案 问题描述 如下如所示&#xff1a; 表一&#xff1a;wechat_dynamically_config表&#xff0c;重点字段&#xff1a;wechat_object 表二&#xff1a;wechat_object表&#xff0c;重点字段&#xff1a;wxid 需求&#xff1a;根据wechat_dynamically_…

你不知道的Postman的Mock接口测试,看这一篇就够了

前言 创建Mock服务 你可以从Postman已有的测试集(Collection)中创建Mock Server或者直接创建Mock Server&#xff08;我们这里选择从已有的测试集中创建Mock Server&#xff09; Mock server详细配置页面&#xff0c;在此页面中我们可以设置&#xff1a; Name the mock serv…

JOSEF约瑟 同步检查继电器 BT-1B/R200 额定电压100/100V, 直流电压220V

BT-1B/R型同步检查继电器型号&#xff1a; BT-1B型同步检查继电器&#xff1b; BT-1B/R200同步检查继电器; BT-1B/R160同步检查继电器; BT-1B/R130同步检查继电器; BT-1B/R120同步检查继电器; BT -1B/R90同步检查继电器; 用途 BT-1B/R型同步检查继电器用于两端供电系统…

小程序应用为亲子陪伴趣味赋能

导言&#xff1a; 在现代社会&#xff0c;随着工作压力的增加和生活节奏的加快&#xff0c;家长们往往面临着亲子陪伴不足的困扰。而小程序应用的普及&#xff0c;为家庭提供了更多的亲子活动选择和参与方式。虎克技术公司成功帮助客户通过开发小程序实现亲子陪伴的赋能&#x…

北斗卫星助力无人机在沙漠播种,促进沙漠治理

北斗卫星助力无人机在沙漠播种&#xff0c;促进沙漠治理 近年来&#xff0c;随着科技的不断发展&#xff0c;北斗卫星和无人机技术的结合被广泛应用于沙漠治理领域&#xff0c;为解决沙漠化问题提供了全新的思路和解决方案。 近日&#xff0c;黄河“几字弯”北岸的内蒙古自治…

016集——n等分cad多段线、弧、圆等——vba实现

cad命令行输入“div”选择图元后可n等分图元&#xff0c;若图中有大量图元需要n等分&#xff0c;这时可借助vba一键实现。 代码逻辑框架为&#xff1a;通过创建句柄函数来选择实体&#xff0c;通过sendcommand函数向命令行输入命令。 先来个小程序练练手&#xff1a;在屏幕上指…

qt练习案例

记录一下qt练习案例&#xff0c;方便学习qt知识点 基本部件 案例1 需求&#xff0c;做一个标签&#xff0c;显示"你好"知识点&#xff0c;QLabel画面 4. 参考&#xff0c;Qt 之 QLabel 案例2 需求&#xff0c;做一个标签&#xff0c;显示图片 知识点&#xff0c;…

R语言lavaan结构方程模型(SEM)

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;是分析系统内变量间的相互关系的利器&#xff0c;可通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、…

基于dashscope在线调用千问大模型

前言 dashscope是阿里云大模型服务平台——灵积提供的在线API组件。基于它&#xff0c;无需本地加载大模型&#xff0c;通过在线方式访问云端大模型来完成对话。 申请API key 老规矩&#xff1a;要想访问各家云端大模型&#xff0c;需要先申请API key。 对于阿里云&#x…

【开源】SpringBoot框架开发陕西非物质文化遗产网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与过程2.3.1 系统设计2.3.2 查阅文献2.3.3 网站分析2.3.4 网站设计2.3.5 网站实现2.3.6 系统测试与效果分析 三、系统展示四、核心代码4.1 查询民间文学4.2 查询传统音乐4.3 增改传统舞…

有趣的CSS - 圆点交互按钮

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是一个有意思的圆点交互文字按钮效果。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页…

关于汽车E\E架构演进的思考(1)

目录 1.电子电气架构概述 2.下一代架构面临的挑战 2.1 如何实现功能融合 2.2 整车通信的限制 2.3 如何保证融合ECU的功能安全和信息安全 3.小结 最近这段时间&#xff0c;汽车电子电气架构迭代的风吹得很猛烈。其中就包括国际MCU大厂纷纷对自家新推出的高性能MCU打得广告…

QEMU调试——通过获取设备树(dtb文件)查询开发板的外设地址信息

1、适用场景 使用qemu时&#xff0c;想快速知道开发板的地址空间映射情况&#xff0c;特别是某些外设控制器的寄存器基地址 2、查询QEMU支持的开发板 qemu-system-riscv32.exe -M ? 3、获取开发板对应的dtb文件 1、qemu-system-riscv32.exe -M nuclei_evalsoc 2、dumpdtb nucl…

HelpLook VS GitBook:知识库优劣详解

在信息爆炸的时代&#xff0c;企业要保持竞争优势&#xff0c;就必须善于管理和利用内部的知识资产。企业知识库作为一种集中存储和共享知识的工具&#xff0c;正在成为现代企业不可或缺的一部分。 HelpLook和Gitbook是提供专业知识库的两个平台&#xff0c;也被大众熟知。它们…

@ResponseStatus

目录 概述&#xff1a; 用途&#xff1a; 参数&#xff1a; 注意事项&#xff1a; 自定义异常类&#xff1a; 底层原理&#xff1a; 概述&#xff1a; 在 Spring MVC 中&#xff0c;我们有很多方法来设置 HTTP 响应的状态码其中最直接的方法&#xff1a;使用 ResponseSt…

教程篇:Groq API+沉浸式翻译插件 体验最快AI翻译

1、进入https://console.groq.com/keys 申请一个API&#xff08;目前免费&#xff01;抓紧白嫖&#xff09; 2、安装Chrome插件&#xff1a;沉浸式翻译。 https://immersivetranslate.com/ 3、照着抄&#xff08;注意将apikey&#xff0c;换成自己申请的groq的api-key&…

中间件 | Redis - [基本信息]

INDEX 1 常规用法2 QPS3 pipeline 1 常规用法 分布式锁 最常见用法&#xff0c;需要注意分布式锁的redis需要单点 分布式事务 分布式事务中&#xff0c;核心的技术难点其实是分布式事务这个事本身作为数据的持久化 2PC&#xff0c;比如 seata 的 AT 模式下&#xff0c;将 un…

哈希图的应用

位图 位图的概念 首先我们根据一个面试题来进入位图的理解 1. 面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。 大家思考一下&#xff0c;如果按照我们以往的思维&#xff0c;用直接遍历的方法…

猫毛过敏又不想扔掉猫怎么办?如何养猫?热门宠物空气净化器分享

养了猫咪一年多&#xff0c;忽然发现自己患上了过敏性鼻炎和结膜炎&#xff0c;就是那种一靠近猫咪就会不断打喷嚏、流鼻涕、流眼泪的症状。有时候还会感到眼睛发痒&#xff0c;发红。有没有什么好的方法治疗过敏性鼻炎呢&#xff1f; 医生建议&#xff0c;从根本上解决问题需…

uniapp图片涂鸦插件(支持多种涂鸦方式,图片放大缩小)

工程地址https://gitee.com/geshijia/ct-graffiti ct-graffiti涂鸦组件使用说明 参考说明 参考链接&#xff1a;https://github.com/ylyuanlu/yl-graffiti 感谢作者的付出&#xff0c;给我提供了一些思路&#xff0c;并做了如下优化&#xff1a; 增加图片放大缩小移动功能添…