View on GitHub

我的极简博客

记录学习与生活

  1. tomcat配置元素包括顶级元素,connector,container和其他嵌套组件。顶级元素包括server和service,container包括engine,host,context,wrapper
  2. tomcat是一个java程序,从java代码或startup.sh开始启动JVM运行BootStrap,初始化tomcat的类加载器并实例化catalina,catalina根据配置信息创建组件并管理server的生命周期
  3. server表示整个catalina servlet容器,管理子组件的生命周期,监听关闭命令。一个server可嵌套一或多个service。
  4. service组装一组connector和一个engine,用于处理传入请求,提供完整的web服务。
  5. executor是连接池,各组件可共享,其可嵌入在service中,且配置在connector之前以便识别绑定
  6. connector代表协议+端口,如http1.1,http2,ajp,用于收发tcp数据并统一处理成servletrequest/servletresponse(http,smtp等)
  7. engine接受并处理一或多个connector的请求映射到其下的各个虚拟主机
  8. host是虚拟主机,代表一个域名
  9. context代表一个web应用程序,基于一个war包运行,并绑定一个请求上下文路径(如根路径),也会创建一个servletContext即应用域对象
  10. wrapper是一个servlet的封装
  11. container中的每个组件都可以基于pipline-value或者说责任链模式对请求进行处理,该调用过程由connector的adapter触发,filterchain是在wrapper中被组装触发的
  12. servlet是单实例,但web服务器会多线程调用处理请求,因此servlet中的成员变量要注意并发访问,静态变量是类加载器内所有代码均可见,而spring中的单例组件仅在IoC容器内可见
  13. tomcat除了脚本启动外还能用java代码启动,spring boot内置tomcat就是用这种方式,spring boot项目打包成可执行jar包后能用java -jar运行,其解决了java默认无法加载嵌套jar的问题
  14. springmvc项目采用前端控制器模式,使用数个(绝大多数情况都是一个)dispatcherservlet处理转发全部请求,其启动时会创建并保存servlet webapplicationcontext,springboot项目则使用servletcontext动态注册dispatcherservlet
  15. applicationcontext有上下层结构,root webapplicatiocontext由servlet容器启动时注册的spring中的ContextLoaderListener创建,保存到servletcontext中,然后servlet webapplicationcontext又会持有root webapplicationcontext
  16. dispatcherservlet处理请求流程是先给servletrequest绑定servlet webapplicationcontext,执行dispatcherservlet的doDispatch方法,检查request是不是上传文件,接着解析local确定i18n,然后根据url去handlermapping中确定映射转发的handler和拦截器链,然后使用适配器包装该handler获得handlerAdapter,执行拦截器的前置处理,执行handler业务逻辑,执行拦截器后置处理,如果有返回modelandview则进行结果处理,看是展示error页面还是解析渲染视图,然后执行aftercompletion处理,最后清理资源结束。
  17. dispatcherservlet执行doDispatch的执行链路中抛出的异常都能被全局异常处理器捕获处理,在spring低版本中handlermapping未找到即404会返回tomcat默认的错误页面,6.1版本开始404也能像其他异常一样处理,除此之外还有filter错误,serlvet容器错误,response已提交等情况下异常无法被捕获处理
  18. servlet规范将路径划分成contextpath(app应用的路径),servletpath(servlet的路径)和pathinfo(剩下的路径),匹配规则就是先排除contextpath,然后依次进行精确匹配,路径匹配,拓展名匹配和缺省匹配,当有一个匹配上则停止
  19. 精确匹配的servlet其配置路径和请求url完全一致,以/开头,不含通配符
  20. 路径匹配遵循最长路径优先原则,以/开头,/*结尾,匹配特定目录下的所有资源
  21. 拓展名匹配用于匹配特定文件类型,*.后缀名,前面不能加/
  22. 缺省匹配就是当所有规则都无法匹配时由该缺省servlet处理
  23. /*属于路径匹配,除精确匹配外拦截所有请求,包括.html,.css,.jsp,/则不会
  24. url尾部斜杆在高版本会严格处理,低版本宽松处理,和不带尾部斜杠的url视同一样处理
  25. dispatcherServlet要映射handler需要从url中计算出lookupPath,由于解码状态不一致,servlet容器实现差异,解码可能导致路径改变等问题,dispatcherServlet应首选使用/缺省匹配
  26. dispatcherServlet默认使用ant风格的路径匹配模式,首先是精确匹配,然后是路径变量匹配,最后是通配符匹配,并且spring 6+不再使用antPathMatcher而改用pathPatternParser,不再支持隐式的后缀匹配,而且将路径拆分成一个个segment单独解码不会破坏路径结构了
  27. handlermapping返回的是handlerExecutionChain,包括handlerMethod和一系列Interceptor
  28. interceptor先执行prehandle方法,如果返回true则放行,如果返回false则中断请求,如果出现异常则中断执行链,倒序执行已经成功的interceptor的afterCompletion方法,异常交给全局处理器处理
  29. handlerMethod执行完毕后倒序执行拦截器链中interceptor的postHandler方法,可以修改返回的ModleAndView,但是像@ResponseBody方法,响应已经在handlerAdapter中被写入提交了,postHandle无法修改响应,如果出现异常则中断执行链,倒序执行所有interceptor的afterCompletion方法,异常交给全局处理器处理
  30. afterCompletion在整个请求处理完毕之后执行,主要用于资源清理,如果抛出异常其他afterCompletion照常执行,但是由于请求处理结束了,响应已经提交,因此异常不会被全局处理器处理,只会打印一行错误日志
  31. filter在servlet之外执行,只能看到servletRequest、servletResponse,主要负责处理协议,不关心业务逻辑
  32. interceptor在dispatcherServlet内handler之外执行,既能拿到servletRequest也能拿到handler,主要负责web业务切面
  33. AOP工作在方法调用层面,负责需要深入方法参数,返回值,异常类型等信息,不局限于web业务的切面
  34. dispatcherServlet持有handlerExceptionResolver链表来依次处理异常,默认内置ExceptionHandlerExceptionResolver处理@ExcepionHandler方法,主要用于自定义业务异常处理,ResponseStatusExceptionResolver处理@ResponseStatus 注解的异常类或 ResponseStatusException 对象,如用于response.sendError(Status),DefaultHandlerExceptionResolver处理处理 Spring MVC 框架内部抛出的标准异常如400,404,405等
  35. 文件上传是基于表单上传的,其MIME类型从application/x-www-form-urlencoded到multipart/form-data,直接传输二进制数据避免了对字符编码导致体积膨胀,其请求体被浏览器随机生成的boundary定界字符串分割为一个个part,每个part确定是表单数据还是二进制数据。断点续传和大文件上传问题一般使用tus协议或S3分片上传解决。
  36. dispatcherServlet收到请求后会先检查content-type确定是文件上传后就调用multipartResolver解析将原始的HttpServletRequest包装成MultipartHttpServletRequest,controller方法就可以使用MultipartFile操作文件数据了。
  37. 如果文件过大在进入controller之前就会抛出异常,需全局异常处理捕获,上传文件名后缀不可信,真实文件类型需检查Magic Number,文件名也建议转换成UUID存储避免路径遍历攻击
  38. springmvc使用messageConverter实现报文和java对象的相互转化,首先依靠content-type进行内容协商确定调用哪个converter,默认有ByteArrayHttpMessageConverter处理字节数组,StringHttpMessageConverter处理字符串,ResourceHttpMessageConverter处理静态资源,MappingJackson2HttpMessageConverter处理json