Tomcat

说明

  • server.xml是tomcat的配置文件
    • tomcat默认的端口号是8080,可以通过配置把端口号改成80
    • 80端口是Web服务默认的端口号,这样在输入URL的时候就不需要显示地加上端口号了
  • tomcat容器中有几个默认的servlet,在启动的时候被加载

    • default servlet处理静态资源(css/js/image)等,默认是/
    • jsp servlet处理jsp文件,默认是*.jsp

      启动时的加载顺序

      Bootstrap:JVM运行基本类,以及标准扩展类(位于jre/lib/ext)
      System:tomcat启动类,位于/bin
      Common:tomcat使用及应用通用类,位于/lib
      webapp:应用类,位于 WEB-INF/lib和WEB-INF/classes
  • tomcat6 类的加载顺序

    • tomcat6类加载.jpg
    • tomcat6类加载顺序.jpg

      Tomcat8熵池阻塞启动变慢

      org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom
      Tomcat7/8使用该类产生安全随机类SecureRandom的实例作为会话ID,基于SHA1PRNG算法,该算法基于SHA-1算法实现伪随机数生成器
      在SHA1PRNG中,有一个种子产生器,它根据配置执行各种操作,在实现中,产生器会评估熵池的噪声数量,随机数是从熵池中进行创建的
      当熵池为空时,来自/dev/random的读操作将被阻塞,直到熵池收集到足够的环境噪声数据
      随机数产生器会收集来自设备驱动器和其它源的环境噪声数据,并放入熵池中,产生器会评估熵池中的噪声数据的数量
      当熵池为空时,这个噪声数据的收集是比较花时间的。这就意味着,Tomcat在生产环境中使用熵池时,会被阻塞较长的时间
  • 尝试解决

    • 在catalina.sh中加入这么一行:-Djava.security.egd=file:/dev/./urandom,通过配置JRE使用非阻塞的Entropy Source
    • 修改$JAVA_PATH/jre/lib/security/java.security文件的securerandom.source属性

      web.xml

      加载过程

  • 当启动一个WEB项目,容器首先会读取项目web.xml配置文件

  • 容器会首先读取web.xml的两个节点:
  • 容器创建一个ServletContext(application),这个WEB项目的所有部分将共享这个上下文
  • 容器以的那么作为键,value作为值,存入ServletContext
  • 容器创建中的类实例,根据配置的class类路径来创建监听
    • 在监听中会有contextInitialized(ServletContextEvent args)初始化方法,启动Web应用时,系统调用Listener的该方法获得:ServletContextapplication=ServletContextEvent.getServletContext();
    • context-param的值就是application.getInitParameter(“context-param的键”);
    • 得到这个context-param的值之后,你就可以做一些操作了
    • 此时web项目还没有完全启动完成,这个动作比所有的servlet都要早
  • 接着,容器会读取,根据指定的类路径来实例化过滤器
  • 总的来说,web.xml的加载顺序是:->->->

    • 若filter需要用到bean,则将spring(org.springframework.web.context.ContextLoaderListener)放入listener中

      标签

    • 使用distributable元素来告诉servlet/JSP容器,Web容器中部署的应用程序适合在分布式环境下运行
    • 使用上下文初始化参数,
    • 参数名在整个Web应用中必须是唯一的,作为选择,可用子元素来描述参数
    • 在Web应用的整个生命周期中上下文初始化参数都存在,任意地Servlet和jsp都可以随时访问
    • 关于Spring配置文件
      • 配置Spring,必须需要,而可有可无
      • 如果不配置,默认路径为/WEB-INF/applicationContext.xml
      • 如果配置,则为contextConfigLocation,为路径名
    • 多个WEB项目
      • 部署在同一容器中的多个WEB项目,要配置不同的webAppRootKey
      • 该值的默认值为webapp.root
    • 获取的值
      • JSP:${initParam.param_name}
      • Servlet:
        • getServletContext().getInitParamter(“param_name”);
        • getServletConfig().getServletContext().getInitParameter()
    • 用于设置容器的session参数
      • 用于指定http session的失效时间
      • 默认时间设置在/conf/web.xml
      • 以分钟为单位,该元素值必须为整数
      • 零或负数,则表示会话将永远不会超时
    • 为web应用定义监听器,用来监听各种事件
      • 两个比较重要的Web应用事件:应用的启动和停止、Session的创建和失效
      • 如果要监听应用的启动和停止事件,必须实现ServletContextListener接口
      • 如果要监听Session的创建和失效事件,必须实现HttpSessionListener接口
    • 所有的监听器按照相同的方式定义,功能取决于各自实现的接口
      • ServletContextListener:用于监听Web应用的启动和关闭
      • ServletContextAttributeListener:用于监听ServletContext范围(application)内属性的改变
      • ServletRequestListener:用于监听用户的请求
      • ServletRequestAttributeListener:用于监听ServletRequest范围(request)内属性的改变
      • HttpSessionListener:用于监听用户session的开始和结束
      • HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变
    • 使用@WebListener修饰Listener实现类或进行配置
    • org.springframework.web.context.ContextLoaderListener
      • 作用为启动Web容器时,监听servletContext对象的变化
      • 获取servletContext对象的,来自动装配ApplicationContext的配置信息(即加载applicationContext.xml文件)
    • 主要用于对用户请求request进行预处理,也可以对Response进行后处理,是个典型的处理链
    • 使用Filter的完整流程
      • Filter对用户请求进行预处理
      • 将请求HttpServletRequest交给Servlet进行处理并生成响应
      • 最后Filter再对服务器响应HttpServletResponse进行后处理
    • Filter与Servlet具有完全相同的生命周期,可通过配置初始化参数
      • 使用FilterConfig的getInitParameter()
    • Filter其实是一个Servlet链,常见的应用场合
      • 认证、日志和审核、图片转换、数据压缩、密码、令牌
      • 触发资源访问事件、XSLT、媒体类型
    • Filter可负责拦截多个请求或响应,一个请求也可被多个Filter拦截
    • Filter必须实现javax.servlet.Filter接口
      • void init(FilterConfig config):用于完成Filter的初始化。FilteConfig用于访问Filter的配置信息
      • void destroy():用于Filter销毁前,完成某些资源的回收
      • void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能的核心方法,该方法就是对每个请求及响应增加额外的处理。它们的分界线为是否调用了chain.doFilter(request,response),执行该方法之前,即对用户请求request进行预处理,执行该方法之后,即对服务器响应response进行后处理
    • 使用@修饰Filter类或进行配置
      • 用来定义过滤器的名称,该名称在整个程序中都必须唯一
      • 元素指定过滤器类的完全限定的名称,即Filter的实现类
      • 为Filter配置参数,与具有相同的元素描述符
      • 元素用来声明Web应用中的过滤器映射,过滤器被映射到一个servlet或一个URL 模式
    • 过滤是按照部署描述符的出现的顺序执行的
    • 使用@WebServlet注解Servlet类或
      • :为Servlet指定一个文本描述
      • :为Servlet提供一个简短的名字被某些工具显示
      • :为Servlet指定一个图标,在图形管理工具中表示该Servlet
      • 用来定义servlet的名称,该名称在整个应用中必须是惟一的
      • 用来指定servlet的完全限定的名称
      • 用来指定应用中JSP文件的完整路径。这个完整路径必须由/开始
      • :Web容器载入内存的顺序
      • :指定相对于Servlet的URL的路径,该路径相对于web应用程序上下文的根路径
    • 加载Servlet的过程
      • 容器的Context对象对请求路径(URL)做出处理
      • 去掉URL的上下文路径,按路径映射规则和Servlet映射路径()做匹配
      • 如果匹配成功,则调用这个Servlet处理请求
    • 配置Spring MVC,指定处理请求的Servlet,DispatcherServlet的配置
      • 用户可以配置多个DispatcherServlet来分别处理不同的url请求,每个DispatcherServlet上下文都对应一个自己的子Spring容器,它们都拥有相同的父Spring容器(业务层、持久bean所在的容器)
      • ContextLoaderListener和DispatcherServlet初始化上下文关系和区别
        • 20180107223756504.png
    • :指定首页文件名称
    • :错误码
    • :错误页面

classpath

  • classpath是web项目的类路径,可以理解为classes下面
  • classpath和classpath*的区别

    • 同名资源存在时,classpath只从第一个符合条件的classpath中加载资源
    • classpath*会从所有的classpath中加载符合条件的资源
    • classpath*需要遍历所有的classpath

      application-context.xml

      说明

  • application-context.xml是全局的,应用于多个servlet,配合ContextLoaderListener

  • application-context.xml一般采用非spring mvc架构,用来加载Application Context
  • 如果直接采用SpringMVC,只需要把所有相关配置都放到spring-mvc.xml中就好

    spring-mvc.xml

    说明

  • WEB项目启动时,读取web.xml配置文件,首先解析的是applicationContext.xml文件,其次才是spring-mvc.xml文件

  • 主要工作
    • 启动注解、扫描controller包注解、静态资源映射、视图解析、文件上传、返回json配置

      自动扫描

      1. <!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 -->
      2. <!-- 加载controller的时候,不加载service,因为此时事物并未生效,若此时加载了service,那么事物无法对service进行拦截 -->
      3. <context:component-scan base-package="org.jeecgframework.web.*,com.jeecg.*,org.jeecgframework.jwt.*">
      4. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
      5. </context:component-scan>

      默认的视图解析器

<bean id="defaultViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="3">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="contentType" value="text/html" />
        <property name="prefix" value="/webpage/" />
        <property name="suffix" value=".jsp" />
</bean>

上传文件

<bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="UTF-8">
        <property name="maxUploadSize">
            <value>104857600</value>
        </property>
        <property name="maxInMemorySize">
            <value>4096</value>
        </property>
</bean>