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

news2024/11/18 21:29:04

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位之间,请重新输入! ");
}

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

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

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

相关文章

基于 Win Server 2008 复现 IPC$ 漏洞

写在前面 本篇博客演示了使用 winXP&#xff08;配合部分 win10 的命令&#xff09;对 win server 2008 的 IPC$ 漏洞进行内网渗透&#xff0c;原本的实验是要求使用 win server 2003&#xff0c;使用 win server 2003 可以规避掉很多下面存在的问题&#xff0c;建议大家使用 …

Bytebase 签约合思,覆盖多云数据库变更发布,数据访问控制,安全治理的全生命周期,确保符合合规审计要求

在数字化快速发展时代&#xff0c;有效的规范数据库管理对企业安全运营至关重要。近日&#xff0c;数据库 DevOps 团队协同管理工具 Bytebase 签约费控领域领军企业合思&#xff0c;旨在全面优化数据库操作管理&#xff0c;收口全体员工的变更和查询操作&#xff0c;以提高整体…

Linux环境下使用interrupt方式操作UART

目录 概述 1 Linux环境下UART设备 2 轮询方式操作UART功能实现 2.1 打开串口函数&#xff1a;usr_serial_open 2.2 关闭串口函数&#xff1a; usr_serial_close 2.3 发送数据函数&#xff1a; usr_serial_sendbytes 2.4 接收数据函数&#xff1a; usr_serial_readinterr…

YOLOv8改进 | 主干篇 | 轻量级的低照度图像增强网络IAT改进YOLOv8暗光检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是轻量级的变换器模型&#xff1a;Illumination Adaptive Transformer (IAT)&#xff0c;用于图像增强和曝光校正。其基本原理是通过分解图像信号处理器&#xff08;ISP&#xff09;管道到局部和全局图像组件&#xff0c;从而恢复在低光…

在高并发、高性能、高可用 三高项目中如何设计适合实际业务场景的分布式id(一)

分布式ID组件&#xff1a;黄金链路上的关键基石 在现代分布式系统中&#xff0c;分布式ID组件无疑扮演着至关重要的角色。作为整个系统的黄金链路上的关键组件&#xff0c;它的稳定性和可靠性直接关乎到整个系统的正常运作。一旦分布式ID组件出现问题&#xff0c;黄金链路上的…

微前端之使用无界创建一个微前端项目

wujie 使用手册 使用简介 主应用配置 安装 wujie依赖main.js配置 是否开启预加载 生命周期函数 – lifecycle.js配置 子应用配置 跨域设置运行模式 生命周期改造 在主应用中&#xff0c;使用wujie&#xff0c;将子应用引入到主应用中去 wujie 使用手册 wujie 是一个基于 Web…

加密 / MD5算法 /盐值

目录 加密的介绍 MD5算法 盐值 加密的介绍 加密介绍&#xff1a;在MySQL数据库中, 我们常常需要对密码, 身份证号, 手机号等敏感信息进行加密, 以保证数据的安全性。 如果使用明文存储, 当黑客入侵了数据库时, 就可以轻松获取到用户的相关信息, 从而对用户或者企业造成信息…

11. C语言标准函数库

C语言制定了一组使用方式通用的函数&#xff0c;称为C语言标准函数库&#xff0c;用于实现编程常用功能&#xff0c;标准函数库由编译器系统提供&#xff0c;并按功能分类存储在不同源代码文件中&#xff0c;调用标准库内函数时需要首先使用 #include 连接对应的源代码文件。 【…

MATLAB | MATLAB版玫瑰祝伟大女性节日快乐!!

妇女节到了&#xff0c;这里祝全体伟大的女性&#xff0c;节日快乐&#xff0c;事业有成&#xff0c;万事胜意。 作为MATLAB爱好者&#xff0c;这里还是老传统画朵花叭&#xff0c;不过感觉大部分样式的花都画过了&#xff0c;这里将一段很古老的2012年的html玫瑰花代码转成MA…

Git 内幕探索:从底层文件系统到历史编辑的全面指南

微信搜索“好朋友乐平”关注公众号。 1. Git 底层文件对象 #mermaid-svg-uTkvyr26fNmajZ3n {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uTkvyr26fNmajZ3n .error-icon{fill:#552222;}#mermaid-svg-uTkvyr26fNmaj…

K8S之实现业务的金丝雀发布

如何实现金丝雀发布 金丝雀发布简介优缺点在k8s中实现金丝雀发布 金丝雀发布简介 金丝雀发布的由来&#xff1a;17 世纪&#xff0c;英国矿井工人发现&#xff0c;金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯&#xff0c;金丝雀也会停止歌唱&#xff1b;当瓦斯…

前端工程化【01】:核心思想、发展历程和面临挑战

前端工程化是指将前端开发中的工具、流程和方法进行规范化和自动化&#xff0c;以提高前端开发效率、提升代码质量和项目可维护性的一种开发方式。通过前端工程化&#xff0c;可以将前端开发过程中的重复工作自动化&#xff0c;减少开发者的重复劳动&#xff0c;提高开发效率。…

✅ Windows11 系统 I 卡独显 A770 安装 深度学习 Pytorch 环境

&#x1f4cb; 文献参考 这里非常感谢知乎上的 ‘丢丢’ 的[**Windows系统下英特尔独显Pytorch的历程**] 为我提供了一开始的 I 卡安装想法&#xff01;但是文中并未介绍如何进行额外的环境变量操作问题&#xff0c;导致很多软件直接安装至系统盘&#xff0c;占用系统盘空间&am…

Go编译报错 link: running gcc failed: exit status 1(已解决)

背景 在对一个开源的Go程序二次开发 重新编译时 &#xff0c; 报错截图如下 报错文字如下&#xff1a;关键信息 link: running gcc failed: exit status 1 $ go build -o orchestrator-didi -i go/cmd/orchestrator/main.go go build: -i flag is deprecated # command-li…

18-Java迭代器模式 ( Iterator Pattern )

Java迭代器模式 摘要实现范例 迭代器模式&#xff08;Iterator Pattern&#xff09;用于顺序访问集合对象的元素&#xff0c;不需要知道集合对象的底层表示 迭代器模式是 Java 和 .Net 编程环境中非常常用的设计模式 迭代器模式属于行为型模式 摘要 1. 意图 提供一种方法…

【MySQL】lower_case_table_names作用及使用

知识点&#xff1a; lower_case_table_names 是mysql设置大小写是否敏感的一个参数。 场景&#xff1a;在使用dataease时&#xff0c;连接外部数据库&#xff0c;启动报错&#xff01;后查看官方文档&#xff0c;特别要求改数据库配置文件&#xff1a;lower_case_table_names …

Service Mesh:如何为您的微服务架构带来可靠性和灵活性

在云原生架构中&#xff0c;Service Mesh 技术成为了微服务架构中不可或缺的一环。本文灸哥将和你一起探讨 Service Mesh 技术的原理、功能和实践&#xff0c;帮助架构师和开发人员更好地理解和应用这一关键技术。 1、Service Mesh 技术概述 Service Mesh 又称为服务网格&…

FPGA 按键控制串口发送

按键消抖 消抖时间一般为10ms&#xff0c;我使用的板子是ACX720&#xff0c;晶振为50MHZ&#xff0c;20ns为一周期。 状态机 模块设计 设计文件 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2023/01/11 12:18:36 // Design Name: // Module Name…

JavaEE进阶(14)Linux基本使用和程序部署(博客系统部署)

接上次博客&#xff1a;JavaEE进阶&#xff08;13&#xff09;案例综合练习——博客系统-CSDN博客 目录 程序配置文件修改和打包 构建项目并打包 分平台配置 数据准备 上传jar包到云服务器并运行 开放端口号 验证程序 如何查看日志得到报错信息 常见问题 关于Linux基…

【自然语言处理】NLP入门(五):1、正则表达式与Python中的实现(5):字符串常用方法:对齐方式、大小写转换详解

文章目录 一、前言二、正则表达式与Python中的实现1.字符串构造2. 字符串截取3. 字符串格式化输出4.字符转义符5. 字符串常用函数函数与方法之比较 6. 字符串常用方法1. 对齐方式center()ljust()rjust() 2. 大小写转换lower()upper()capitalize()title()swapcase() 一、前言 本…