mvc 异常处理源码解析(3)

news2024/11/19 19:41:35

目录

  • 准备
  • 源码跟踪
  • ExceptionHandlerExceptionResolver初始化
    • ExceptionHandlerExceptionResolver注入
    • ExceptionHandlerExceptionResolver中exceptionHandlerAdviceCache初始化
    • ExceptionHandlerMethodResolver中mappedMethods初始化
  • 结尾

准备

  1. 准备一个controller类, 里面抛出一个异常
@RestController
@RequestMapping("/hello")
public class HelloController {


    @GetMapping("/h")
    public String hello(HttpServletResponse response) throws ArithmeticException {

        try {
            int a = 1 / 0;
        } catch (Exception e) {
            throw e;
        }
        return "hello";
    }

}

  1. 配置一个全局异常处理类
/**
 * 异常处理器
 */
@RestControllerAdvice
public class BDExceptionHandler {

    /**
     * 参数异常
     * @param e 异常
     * @return BaseResult
     */
    @ExceptionHandler(ArithmeticException.class)
    public R doBaseExceptionHandler(ArithmeticException e) {
        return R.error(e.getMessage());
    }
}
  1. 接下来访问url, 跟踪源码

源码跟踪

进入到mvc的入口类DispatcherServlet的 doDispatch方法, 可以发现整体逻辑被try catch包围, 当第3步抛出异常之后就会被捕获, dispatchException对象则不为空,最后进入processDispatchResult方法进行处理

	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				//1.获取处理器链路
				//2.执行拦截器前置方法
				//3.调用controller方法, 返回结果集
				//4.执行拦截器后置方法
			}
			catch (Exception ex) {
			//
				dispatchException = ex;
			}
			catch (Throwable err) {
				dispatchException = new NestedServletException("Handler dispatch failed", err);
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Throwable err) {
			triggerAfterCompletion(processedRequest, response, mappedHandler,
					new NestedServletException("Handler processing failed", err));
		}
		finally {
			if (asyncManager.isConcurrentHandlingStarted()) {
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				// Clean up any resources used by a multipart request.
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

进入processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {

		boolean errorView = false;
		//判断异常是否为空, 如果不是空则处理
		if (exception != null) {
			//处理ModelAndViewDefiningException异常
			if (exception instanceof ModelAndViewDefiningException) {
				logger.debug("ModelAndViewDefiningException encountered", exception);
				mv = ((ModelAndViewDefiningException) exception).getModelAndView();
			}
			else {
				//处理其他所有的异常
				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
				mv = processHandlerException(request, response, handler, exception);
				errorView = (mv != null);
			}
		}
		//省略下面代码

进入mv = processHandlerException(request, response, handler, exception);

	protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
			@Nullable Object handler, Exception ex) throws Exception {

		// Success and error responses may use different content types
		request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);

		// Check registered HandlerExceptionResolvers...
		ModelAndView exMv = null;
		if (this.handlerExceptionResolvers != null) {
			//this.handlerExceptionResolvers里面默认有两个处理异常的类
			for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
				// 遍历,判断使用那个类来处理
				exMv = resolver.resolveException(request, response, handler, ex);
				if (exMv != null) {
					break;
				}
			}
		}
		if (exMv != null) {
			//省略代码
			return exMv;
		}

		throw ex;
	}

看一下上面for循环里面的this.handlerExceptionResolvers对象的结构 :
DefaultErrorAttributes : 没做任何处理, 只是将异常设置到request对象的属性当中;

HandlerExceptionResolverComposite : 里面有三个异常处理类, 分别的作用是 :

ExceptionHandlerExceptionResolver:基于 @ExceptionHandler 配置 HandlerMethod 的 HandlerExceptionResolver 实现类。例如通过 @ControllerAdvice 注解自定义异常处理器,加上@ExceptionHandler注解指定方法所需要处理的异常类型

ResponseStatusExceptionResolver:基于 @ResponseStatus 提供错误响应的 HandlerExceptionResolver 实现类。例如在方法上面添加 @ResponseStatus 注解,指定该方法发生异常时,需要设置的 code 响应码和 reason 错误信息

DefaultHandlerExceptionResolver:默认 HandlerExceptionResolver 实现类,针对各种异常,设置错误响应码。例如 HTTP Method 不支持,则在这个实现类中往响应中设置错误码和错误信息

原文链接:https://blog.csdn.net/Running666/article/details/130786561

在这里插入图片描述
进入HandlerExceptionResolverComposite类的resolveException(); 遍历上面的三种异常处理类, 判断应该使用哪个处理

	public ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		if (this.resolvers != null) {
			//获取, 遍历
			for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) {
				ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
				if (mav != null) {
					return mav;
				}
			}
		}
		return null;
	}

由于只设置了第一种异常处理方式, 所以异常会由ExceptionHandlerExceptionResolver来处理, 进入handlerExceptionResolver.resolveException()

	public ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		if (shouldApplyTo(request, handler)) {
			prepareResponse(ex, response);
			//主要的异常处理逻辑
			ModelAndView result = doResolveException(request, response, handler, ex);
			if (result != null) {
				// Print debug message when warn logger is not enabled.
				if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
					logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result));
				}
				
				logException(ex, request);
			}
			return result;
		}
		else {
			return null;
		}
	}

进入doResolveException(request, response, handler, ex)方法;

	@Override
	@Nullable
	protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
			HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
			
		//根据controller类和异常来判断由哪个类来处理这个异常
		ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
		if (exceptionHandlerMethod == null) {
			return null;
		}
		//填充参数处理器
		if (this.argumentResolvers != null) {
			exceptionHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
		}
		//填充返回结果处理器
		if (this.returnValueHandlers != null) {
			exceptionHandlerMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
		}

		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		ModelAndViewContainer mavContainer = new ModelAndViewContainer();
		ArrayList<Throwable> exceptions = new ArrayList<>();
		try {
			//省略代码
			Object[] arguments = new Object[exceptions.size() + 1];
			exceptions.toArray(arguments);  // efficient arraycopy call in ArrayList
			arguments[arguments.length - 1] = handlerMethod;
			//反射调用异常处理类
			exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments);
		}
		catch (Throwable invocationEx) {
			// Any other than the original exception (or a cause) is unintended here,
			// probably an accident (e.g. failed assertion or the like).
			if (!exceptions.contains(invocationEx) && logger.isWarnEnabled()) {
				logger.warn("Failure in @ExceptionHandler " + exceptionHandlerMethod, invocationEx);
			}
			// Continue with default processing of the original exception...
			return null;
		}
		//省略
	}

主要逻辑就是看如何找到处理对应异常的方法, 进入getExceptionHandlerMethod(handlerMethod, exception);

进入到了ExceptionHandlerExceptionResolver类中, 在这个类里面有两个关键的属性,exceptionHandlerCache和exceptionHandlerAdviceCache, 两个都是map, exceptionHandlerAdviceCache的初始化下面再说,exceptionHandlerCache的初始化想知道的自己去查一下吧

	private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
			new ConcurrentHashMap<>(64);

	private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
			new LinkedHashMap<>();

exceptionHandlerCache里面存的就是在当前controller里面包含@ExceptionHandler注解的方法, key: controller类, value : 方法包装类

exceptionHandlerAdviceCache里面存的就是标注了@ControllerAdvice注解的类,里面带有@ExceptionHandler注解的方法, key:
@RestControllerAdvice注解标注的类, value: 方法包装类

	@Nullable
	protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
			@Nullable HandlerMethod handlerMethod, Exception exception) {

		Class<?> handlerType = null;
		//从exceptionHandlerCache获取异常对应的处理方法, 由于没有配置, 肯定获取不到
		if (handlerMethod != null) {
			handlerType = handlerMethod.getBeanType();
			ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);
			if (resolver == null) {
				resolver = new ExceptionHandlerMethodResolver(handlerType);
				this.exceptionHandlerCache.put(handlerType, resolver);
			}
			Method method = resolver.resolveMethod(exception);
			if (method != null) {
				return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
			}
			if (Proxy.isProxyClass(handlerType)) {
				handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
			}
		}
		//遍历全局的异常处理类, 看是否可以获取到对应的处理方法
		for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
			ControllerAdviceBean advice = entry.getKey();
			if (advice.isApplicableToBeanType(handlerType)) {
				ExceptionHandlerMethodResolver resolver = entry.getValue();
				Method method = resolver.resolveMethod(exception);
				if (method != null) {
					return new ServletInvocableHandlerMethod(advice.resolveBean(), method);
				}
			}
		}

		return null;
	}

进入Method method = resolver.resolveMethod(exception);, 最终进入到resolveMethodByExceptionType()方法, 在ExceptionHandlerMethodResolver类中

ExceptionHandlerMethodResolver中有两个关键属性mappedMethods,和exceptionLookupCache, 两个也都是map, 两个都是根据异常获取对应的异常处理方法, mappedMethods在程序启动时候初始化, exceptionLookupCache相当于一个缓存,为了提高查询速度

	@Nullable
	public Method resolveMethodByExceptionType(Class<? extends Throwable> exceptionType) {
		//从缓存中获取处理方法, 如果获取不到,返回null(第一次执行此方法肯定获取不到)
		Method method = this.exceptionLookupCache.get(exceptionType);
		if (method == null) {
			//如果获取不到, 则去mappedMethods获取
			method = getMappedMethod(exceptionType);
			//将获取的结果缓存到exceptionLookupCache中
			this.exceptionLookupCache.put(exceptionType, method);
		}
		return (method != NO_MATCHING_EXCEPTION_HANDLER_METHOD ? method : null);
	}

进入getMappedMethod(exceptionType);

	private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
		List<Class<? extends Throwable>> matches = new ArrayList<>();
		//遍历所有可以处理的异常, 判断与抛出的异常是否匹配
		for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
			if (mappedException.isAssignableFrom(exceptionType)) {
				matches.add(mappedException);
			}
		}
		if (!matches.isEmpty()) {
			//如果有多个方法可以匹配来处理异常,则进行排序
			if (matches.size() > 1) {
				matches.sort(new ExceptionDepthComparator(exceptionType));
			}
			//获取第一个方法来处理异常,返回方法
			return this.mappedMethods.get(matches.get(0));
		}
		else {
			return NO_MATCHING_EXCEPTION_HANDLER_METHOD;
		}
	}

到此为止, 已经获取到对应的处理异常的方法了, 在上面的doResolveHandlerMethodException方法中, 最后通过反射调用该方法, 处理异常

接下来讨论一下ExceptionHandlerExceptionResolver类里面的exceptionHandlerCache和exceptionHandlerAdviceCache初始化和
ExceptionHandlerMethodResolver类中的mappedMethods初始化

ExceptionHandlerExceptionResolver初始化

ExceptionHandlerExceptionResolver实现了InitializingBean接口, 猜测初始化肯定在afterPropertiesSet()方法中, 我们至于要查找ExceptionHandlerExceptionResolver是如何注入到springboot容器中的, 及afterPropertiesSet()方法逻辑即可
在这里插入图片描述

ExceptionHandlerExceptionResolver注入

实际上,ExceptionHandlerExceptionResolver并不会成为bean交给Spring容器管理。但是在WebMvcConfigurationSupport初始化过程中,会手动调用afterPropertiesSet()进行默认初始化

还记得上面HandlerExceptionResolverComposite类里面有三个异常处理类吗? 看一下他们是如何注入的

在WebMvcConfigurationSupport类里面的handlerExceptionResolver()方法:

	@Bean
	public HandlerExceptionResolver handlerExceptionResolver(
			@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
		List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
		configureHandlerExceptionResolvers(exceptionResolvers);
		//如果是空, 在下面的if里面将三个异常处理类添加到集合中
		if (exceptionResolvers.isEmpty()) {
			addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);
		}
		extendHandlerExceptionResolvers(exceptionResolvers);
		HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
		composite.setOrder(0);
		//赋值属性, 最后返回
		composite.setExceptionResolvers(exceptionResolvers);
		return composite;
	}

进入到addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);

	protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers,
			ContentNegotiationManager mvcContentNegotiationManager) {
		//创建ExceptionHandlerExceptionResolver 对象
		ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();
		exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager);
		exceptionHandlerResolver.setMessageConverters(getMessageConverters());
		exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers());
		exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());
		if (jackson2Present) {
			exceptionHandlerResolver.setResponseBodyAdvice(
					Collections.singletonList(new JsonViewResponseBodyAdvice()));
		}
		if (this.applicationContext != null) {
			exceptionHandlerResolver.setApplicationContext(this.applicationContext);
		}
		//手动调用afterPropertiesSet()给属性初始化
		exceptionHandlerResolver.afterPropertiesSet();
		//添加第一个
		exceptionResolvers.add(exceptionHandlerResolver);

		ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver();
		responseStatusResolver.setMessageSource(this.applicationContext);
		//添加第二个
		exceptionResolvers.add(responseStatusResolver);
		//添加第三个
		exceptionResolvers.add(new DefaultHandlerExceptionResolver());
	}

所以我们只需要看WebMvcConfigurationSupport是如何注入的就可以了, 实际上他是通过WebMvcAutoConfiguration类来间接注入的
在这里插入图片描述
而WebMvcAutoConfiguration类的注入是通过自动装配来注册的
在这里插入图片描述

ExceptionHandlerExceptionResolver中exceptionHandlerAdviceCache初始化

	@Override
	public void afterPropertiesSet() {
		// Do this first, it may add ResponseBodyAdvice beans
		initExceptionHandlerAdviceCache();

		if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		if (this.returnValueHandlers == null) {
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}

进入initExceptionHandlerAdviceCache()方法

	private void initExceptionHandlerAdviceCache() {
		if (getApplicationContext() == null) {
			return;
		}
		//获取带有ControllerAdvice注解的类
		List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
		for (ControllerAdviceBean adviceBean : adviceBeans) {
			Class<?> beanType = adviceBean.getBeanType();
			if (beanType == null) {
				throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
			}
			//构建value对象, 存入到exceptionHandlerAdviceCache中
			//ExceptionHandlerMethodResolver中mappedMethods初始化逻辑也在其中
			ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
			if (resolver.hasExceptionMappings()) {
				this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
			}
			if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
				this.responseBodyAdvice.add(adviceBean);
			}
		}
	}

ExceptionHandlerMethodResolver中mappedMethods初始化

mappedMethods的初始化逻辑很简单, 在上面的initExceptionHandlerAdviceCache()方法中我们已经找到了带有ControllerAdvice的所有类, 将类的类型作为参数创建了ExceptionHandlerMethodResolver对象, mappedMethods的初始化就在构造方法中

进入ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType) 方法

	public ExceptionHandlerMethodResolver(Class<?> handlerType) {
		//获取到handlerType类中所有的带有ExceptionHandler注解的方法,
		for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
			//解析ExceptionHandler注解中的属性, 因为可以配置多个异常类型, 所有返回的是集合, 进行遍历
			for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
				//将异常类型作为key, 方法作为value, 存入到mappedMethods中
				addExceptionMapping(exceptionType, method);
			}
		}
	}

	private List<Class<? extends Throwable>> detectExceptionMappings(Method method) {
		List<Class<? extends Throwable>> result = new ArrayList<>();
		//获取method上的ExceptionHandler注解的所有的异常类型,存入到result中, 返回
		detectAnnotationExceptionMappings(method, result);
		if (result.isEmpty()) {
			for (Class<?> paramType : method.getParameterTypes()) {
				if (Throwable.class.isAssignableFrom(paramType)) {
					result.add((Class<? extends Throwable>) paramType);
				}
			}
		}
		if (result.isEmpty()) {
			throw new IllegalStateException("No exception types mapped to " + method);
		}
		return result;
	}


	private void addExceptionMapping(Class<? extends Throwable> exceptionType, Method method) {
		Method oldMethod = this.mappedMethods.put(exceptionType, method);
		if (oldMethod != null && !oldMethod.equals(method)) {
			throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" +
					exceptionType + "]: {" + oldMethod + ", " + method + "}");
		}
	}

结尾

上面已经说了到逻辑代码发生异常之后, 我们自定义的异常处理类如何加载处理这些异常(同时包括系统启动时的一些系统异常), 但是如果抛出一种没有处理类的异常会怎么样呢? 下篇文章在讨论一下

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

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

相关文章

Revit SDK 介绍:CreateAirHandler 创建户式风管机

前言 这个例子介绍如何通过 API 创建一个户式风管机族的内容&#xff0c;包含几何和接头。 内容 效果 核心逻辑 必须打开机械设备的族模板创建几何实体来表示风管机创建风机的接头 创建几何实体来表示风管机 例子中创建了多个拉伸&#xff0c;下面仅截取一段代码&#xff…

OpenGL-入门-BMP像素图glReadPixels(1)实现读取屏幕中间的颜色和获取屏幕上鼠标点击位置的颜色

glReadPixels函数用于从帧缓冲区中读取像素数据。它可以用来获取屏幕上特定位置的像素颜色值或者获取一块区域内的像素数据。下面是该函数的基本语法&#xff1a; void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *da…

LeetCode——字母异位词分组(中等)

题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&quo…

java八股文面试[多线程]——Synchronized优化手段:锁膨胀、锁消除、锁粗化和自适应自旋锁

1.锁膨胀 &#xff08;就是锁升级&#xff09; 我们先来回顾一下锁膨胀对 synchronized 性能的影响&#xff0c;所谓的锁膨胀是指 synchronized 从无锁升级到偏向锁&#xff0c;再到轻量级锁&#xff0c;最后到重量级锁的过程&#xff0c;它叫锁膨胀也叫锁升级。 JDK 1.6 之前…

springdoc-openapi-ui 整合 knife,多模块分组,脚手架

pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…

2023年京东箱包行业数据分析(京东数据运营)

当前&#xff0c;旅游业全面复苏&#xff0c;这一现象也带动了周边产业的火爆。在全国游客的出行热带动下&#xff0c;箱包产业迎来消费热潮。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年7月&#xff0c;京东箱包大盘整体的销量为266万&#xff0c;同比增长…

知识图谱笔记:TransH

1 TransE存在的问题 一对多 假设有一个关系 "是父亲"&#xff0c;其中一个父亲&#xff08;头实体&#xff09;可能有多个孩子&#xff08;尾实体&#xff09; 父亲 A -> 孩子 1父亲 A -> 孩子 2在 TransE 中&#xff0c;这两个关系会被建模为&#xff1a; A是…

【pytorch】tensorboard + transforms的使用

一、tensorboard的使用 1. 加载一张图片转化为tensor类型&#xff0c;并通过tenboard可视化 from PIL import Image from torch.utils.tensorboard import SummaryWriter from torchvision import transformsimg_path "dataset/train/ants_image/0013035.jpg"img …

ESXi 6.7添加螃蟹2.5g网卡支持

安装了ESXi 6.7&#xff0c;结果机器两块网卡只能识别一块&#xff0c;然后想着不能让另一块浪费啊&#xff0c;开始折腾&#xff0c;看着网上都是找的驱动然后封装进iso&#xff0c;可是我已经装完了&#xff0c;怎么办&#xff0c;然后找到了下面解决方法 1.找驱动 下载RTL81…

DEAP库文档教程四——操作与算法

本节将将在初始化的基础上&#xff0c;进一步说明操作与算法。 1、Using the Toolbox toolbox(base.Toolbox())是包含所有进化操作的工具箱&#xff0c;从目标初始化到适应度计算。它允许在每个算法中实现简单的构造。toolbox基本上由两种方法组成&#xff0c;register()和un…

工服穿戴检测联动门禁开关算法

工服穿戴检测联动门禁开关算法通过yolov8深度学习框架模型&#xff0c;工服穿戴检测联动门禁开关算法能够准确识别和检测作业人员是否按照规定进行工服着装&#xff0c;只有当人员合规着装时&#xff0c;算法会发送开关量信号给门禁设备&#xff0c;使门禁自动打开。YOLO的结构…

msvcp71.dll丢失怎样修复和msvcr71.dll丢失的解决方法介绍

今天&#xff0c;我将为大家分享一个关于电脑msvcp71.dll丢失的问题及其解决方法。希望这些方法能够帮助到正面临同样问题的朋友们。 首先&#xff0c;让我们来了解一下msvcp71.dll丢失的原因。msvcp71.dll是Microsoft Visual C 2008 Redistributable Package的一个组件&#…

内网隧道代理技术(十九)之 CS工具自带上线不出网机器

CS工具自带上线不出网机器 如图A区域存在一台中转机器,这台机器可以出网,这种是最常见的情况。我们在渗透测试的过程中经常是拿下一台边缘机器,其有多块网卡,边缘机器可以访问内网机器,内网机器都不出网。这种情况下拿这个边缘机器做中转,就可以使用CS工具自带上线不出网…

leetcode55.跳跃游戏 【贪心】

题目&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例…

DEAP库文档教程二-----创建类型

本节将展示如何通过creator创建类型以及如何使用toolbox进行初始化。 1、Fitness 已经提供的Fitness类是一个抽象类&#xff0c;它需要weight来使得它成为一个函数。一个最小化的适应度是通过负权重构建的&#xff0c;而一个最大化适应度则需要正权重。 creator.create(&quo…

渗透测试漏洞原理之---【失效的访问控制】

文章目录 1、失效的访问控制1.1、OWASP Top 101.1.1、A5:2017-Broken Access Control1.1.2、A01:2021 – Broken Access Control 1.2、失效的访问控制类别1.2.1、水平越权1.2.2、垂直越权 1.3、攻防案例1.3.1、Pikachu靶场 Over Permision1.3.2、DVWA越权利用失效的访问控制漏洞…

QT listWidget 中实现元素的自由拖拽

QListWIdget中拖拽元素移动 setMovement(QListView::Movement::Free);setDragEnabled(true); setDragDropMode(DragDropMode::DragDrop); setDefaultDropAction(Qt::DropAction::MoveAction);

稳定性建设框架 | 京东物流技术团队

一、为什么要做稳定性建设 1、从熵增定律引出稳定性建设的必要性 物理学上&#xff0c;用“熵”来描述一个体系的混乱程度。卡尔弗里德曼提出熵增定律&#xff0c;他认为在一个封闭的系统内&#xff0c;如果没有外力的作用&#xff0c;一切物质都会从有序状态向无序状态发展。…

CSRF与XSS结合利用

文章目录 修改cms网站后台管理员密码成功登录总结 修改cms网站后台管理员密码 CSRF和XSS结合的JS代码&#xff1a; <script> xmlhttp new XMLHttpRequest(); xmlhttp.open("post","http://10.4.7.130/cms/admin/user.action.php",false); xmlhttp…

2023第二届中国绿色钢铁国际峰会 演讲嘉宾预告:Meranti Steel

2023第二届中国绿色钢铁国际峰会将于9月21日-22日在上海举办&#xff0c;本次会议线上线下同步举行&#xff0c;会场提供中英同声传译。 钢铁是当今世界上最常用的金属&#xff0c;普遍应用于世界各国基础设施建设与机械、汽车、飞机、船舶、家电等产品的生产制造中。但是&…