SpringMVC使用(二)

news2025/8/11 14:06:56

1. 统一异常处理

SpringMVC提供了统一处理Controller层抛出的异常的方法

1.1 统一异常处理案例

RestController的统一异常处理

package com.lan.controller;

import com.lan.exception.BusinessException;
import com.lan.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

//注解@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //注解@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class) // 处理SystemException
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        // ...
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class) // 处理BusinessException
    public Result doBusinessException(BusinessException ex){
        // ...
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class) // 处理其它的Exception
    public Result doOtherException(Exception ex){
        // ...
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

1.2 常用注解

注解作用作用目标
@RestControllerAdvice为Controller类做增强,相当于@ControllerAdvice+@ResponseBody,@ExceptionHandler 方法默认带有 @ResponseBody 。

@ExceptionHandler设置指定类型异常的处理方案,Controller出现指定类型的异常后转入当前方法执行方法

2. 统一结果封装

通过@RestControllerAdvice增强Controller的同时,实现ResponseBodyAdvice接口可以统一封装RestController的返回结果。

案例如下:

package com.lan.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice<Object> {
	@Autowired
    private ObjectMapper objectMapper;

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 类型不是Result时使用增强
		if(returnType.getParameterType() != Result.class) { 
			return true;
		}
		return false;
	}

    // body为原返回对象
	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {
		try {
			return objectMapper.writeValueAsString(new Result(0, body));
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return body;
	}
}

3. 拦截器interceptor

SpringMVC中的拦截器(interceptor)是一种动态拦截控制层的机制,用来做控制层增强。

 3.1 拦截器Interceptor与过滤器Filter的区别

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

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

3.2 拦截器案例

Servlet配置类

package com.lan.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        // return new Class[SpringConfig.class];
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"}; // 表示SpringMVC要处理的所有路径
    }

    //乱码处理的过滤器Filter
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

拦截器

package com.lan.controller.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        System.out.println("preHandle..."+contentType);
        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...");
    }
}

拦截器配置类(注意:拦截器类要被SpringMVC容器扫描到):

package com.lan.config;

import com.itheima.controller.interceptor.ProjectInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 不需要SpringMVC处理的静态资源
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //配置拦截器和拦截的所有路径
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
        // 添加多个添加拦截器
        // registry.addInterceptor(xxx).addPathPatterns("/xxx","/xxx/*");
    }
}

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

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

相关文章

DolphinDB Kafka 插件介绍

1. DolphinDB Kafka 插件介绍 DolphinDB Kafka 插件支持把 DolphinDB 中生产的数据推送到 Kafka&#xff0c;也支持从 Kafka 订阅数据&#xff0c;并在 DolphinDB 中消费。用户可以在 DolphinDB 中实例化 Producer 对象&#xff0c;把 DolphinDB 中的数据同步到 Kafka 中指定的…

LeetCode | 218. 天际线问题

城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度&#xff0c;请返回由这些建筑物形成的天际线 。 每个建筑物的几何信息由数组 buildings 表示&#xff0c;其中三元组 buildings[i] [lefti, righti, heighti] 表示&#xff1a;…

Egg如何实现文件上传

文件上传是开发中不可避免的一项。那么在没有单独的资源服务器的时候&#xff0c;上传的文件可能要放在我们的项目文件夹服务器上&#xff0c;我们如何实现文件上传呢&#xff1f; 首先不用想&#xff0c;我们需要一个测试页面。html用来上传文件。如下&#xff1a; <!DOCT…

D. Minimal Height Tree(如何BFS遍历序列使树的高度最小)

Problem - 1437D - Codeforces Monocarp有一棵由n个顶点组成的树&#xff0c;它的根在顶点1。他决定研究BFS&#xff08;宽度优先搜索&#xff09;&#xff0c;所以他在他的树上运行BFS&#xff0c;从根开始。BFS可以用下面的伪代码来描述。 a [] # 顶点被处理的顺序 q Queu…

mdr1基因寡核苷酸/酸敏感靶多肽/聚乙二醇埃博霉素B偶联阿霉素的相关制备

小编这里整理了mdr1基因寡核苷酸/酸敏感靶多肽/聚乙二醇埃博霉素B偶联阿霉素的相关内容&#xff0c;一起来看&#xff01; 聚乙二醇埃博霉素B偶联阿霉素相关研究&#xff1a; 阿霉素与酰肼聚乙二醇羧基在磷酸的作用下反应制得阿霉素聚乙二醇羧基中间体,其中阿霉素与磷酸的摩尔比…

Android App手势冲突处理中上下左右滑动的处理以及侧滑边缘菜单的讲解及实战(附源码 可直接使用)

运行有问题或需要源码请 点赞关注收藏后评论区留言~~~ 一、上下滚动与左右滑动的冲突处理 Android控件繁多&#xff0c;允许滚动或滑动操作的视图也不少&#xff0c;如果开发者要自己接管手势处理&#xff0c;那么这个页面的滑动就存在冲突的情况&#xff0c;如果系统响应了A视…

贴花、射线、动画通知——足迹01

案例实现效果&#xff1a; 人物跑步留下脚印&#xff08;其他运动留下脚印也是同理&#xff09;。 重点&#xff1a; 贴花的创建、射线、动画通知。射线碰撞决定贴花生成位置&#xff0c;动画通知决定贴花生成时间。 一、贴花 1、贴花纹理图 在网络上找素材&#xff08…

JavaSE之动态代理

目录动态代理动态代理的好处Proxy重写invoke方法实例最后动态代理 动态代理需要确定要代理的对象&#xff0c;所以需要先new一个要代理的对象 动态代理的好处 可以在不改变方法源码的情况下&#xff0c;实现对方法功能的增强。 简化了代码。 提高了软件系统的可扩展性。 P…

【TensorRT】神经网络中的量化

文章目录一、TensorRT 为什么需要量化二、基础内容三、神经网络的量化过程一、TensorRT 为什么需要量化 量化是什么&#xff1a;量化在数字信号处理领域&#xff0c;是指将信号的连续取值&#xff08;或者大量可能的离散取值&#xff09;近似为有限多个&#xff08;或较少的&a…

七彩动态|棱镜七彩获“北京国家金融科技认证中心”颁发的「金融开源技术服务商能力评估证书」

11月13日&#xff0c;由北京金融科技产业联盟举办的第二届会员大会第四次会议在北京召开。 聚焦开源应用与安全&#xff0c;棱镜七彩通过北京国家金融科技认证中心“金融业开源评估”—金融开源技术服务商能力评估&#xff0c;并获得由北京国家金融科技认证中心颁发的“金融开…

对梯度回传的理解

参考 对梯度回传的理解 - 云社区 - 腾讯云 神经网络的每一层可以看做是使用一个函数对变量的一次计算。在微分中链式法则用于计算复合函数的导数。反向传播时一种计算链式法则的算法&#xff0c;使用高效的特定运算顺序。 设x是实数&#xff0c;f和g是从实数映射到实数的函数。…

分享一个单片机GUI库,简洁,使用

1-介绍一下 先来几张图&#xff1a; 看着是不是还不错。这个是一个国外的爱好者开发的&#xff0c;笔者有次逛网站&#xff0c;搜GUI看到的没感觉还不错&#xff0c;今天特意给大家分享一下。 这个GUI是一个用于嵌入式系统的免费开源图形库。平台独立的&#xff0c;也就是说可…

OVN 流表基础 -- 基于 kubeOVN (二)

文章目录功能流表加 Pod加子网跨子网 pod 互访访问外部网络DHCP静态路由策略路由安全组DNATLBFullNAT LBService 扩展Src-ip LB功能流表 基于此模型配置功能&#xff0c;来查看流表变化&#xff0c;探讨功能实现方式。 加 Pod 流表添加&#xff1a; Datapath: "ovn-cl…

《Eolink 征文活动- -RESTful接口全解测试-全方位了解Eolink》

目录 Eolink平台首页 Eolink平台下载地址 一、自带环境示例【GET】|【POST】 示例项目&#xff1a; 完成Get请求示例&#xff1a; 完整POST请求示例&#xff1a; 二、自建接口测试【PUT】|【DELETE】 RESTful协议/方法 创建PUT&DELETE的API接口&#xff1a; PUT协…

【linux】虚拟化

linux虚拟化 文章目录linux虚拟化实验环境安装虚拟化服务安装虚拟机遇到报错效果虚拟机管理命令移植虚拟机虚拟机快照由快照创建虚拟机实验环境 1号虚拟机配置局域网镜像仓库&#xff0c;httpd服务2号虚拟机保证可以使用dnf搜索到1号的镜像仓库 安装虚拟化服务 查看是否支持v…

代码随想录刷题|动态规划理论基础 LeetCode 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

目录 动态规划理论基础 509. 斐波那契数 思路 斐波那契数 递归思路 动态规划 动态规划(优化数组) 70. 爬楼梯 思路 爬楼梯 动态规划(优化数组) 动态规划(变量替代数组) 746. 使用最小花费爬楼梯 思路 使用最小花费爬楼梯 动态规划(使用数组) 动态规划(使用变量) 动态规划理论基…

顺风车用户最爱“送花”城市Top30 出炉,来看有没有你的家乡?

11月18日&#xff0c;嘀嗒小红花迎来“一周岁生日”&#xff0c;嘀嗒出行也于当日正式发布《嘀嗒小红花一周年出行人文报告》。《报告》显示&#xff0c;自2021年11月18日&#xff0c;嘀嗒出行“送你一朵小红花”产品功能上线至今&#xff0c;嘀嗒顺风车乘客已向车主送出239万朵…

商品720vr全景环物制作便捷推送到全世界

720vr全景的应用范围也得到了扩大和普及。VR全景作为新一代信息技术&#xff0c;相较于传统的图文视频等展现方式而言&#xff0c;VR全景不仅能够帮助用户随时随地身临其境的进行沉浸式体验&#xff0c;也可以帮助商家有效降低宣传推广成本。 720VR全景制作拍摄VR全景需要用到相…

德国药品数据库查询系统(含网址)

德国曾经有被誉为世界’医药基地’的称号。在2020年时德国药品出口额有近千亿美元&#xff0c;占世界药品出口总额的近七分之一&#xff0c;连续18年为居世界第一位&#xff0c;不仅仅是销量&#xff0c;德国生物医药行业在心脏、血液循环、糖尿病、癌症等疾病的研究、预防、基…

用Python计算点估计预测评价指标(误差指标RMSE、MSE、MAE、MAPE) ,画图展示

机器学习的回归问题常用RMSE&#xff0c;MSE, MAE,MAPE等评价指标&#xff0c;还有拟合优度R2。由于每次预测出来的预测值再去和原始数据进行误差评价指标的计算很麻烦&#xff0c;所以这里就直接给出他们五个指标的计算函数。把每次预测出来的值和真实值输入这个函数就可以得到…