大西洲总督

tan90°

  • 主页
  • 随笔
所有文章 关于我

大西洲总督

tan90°

  • 主页
  • 随笔

spring笔记

2019-09-15

循环依赖

  • spring容器如何解决循环依赖
    • 通过单例缓存池解决循环依赖(三级缓存池)
      • org.springframework.context.support.AbstarctApplicationContext # getBean()
      • org.springframework.bean.factory.support.AbstarctBeanFactory # doGetBean()
        1. transformeBeanName 解析别名
        2. getSingleton 尝试去缓存池中获取对象(第一次创建bean时,缓存池中没有该对象)
        3. 若出现循环依赖,判断bean是否单例,不是单例则抛出异常
        4. 当前容器是否有父工厂,有父工厂则尝试由父工厂加载
        5. 合并bean定义
        6. 判断bean定义是否为抽象的
        7. 进行dependsOn依赖检测
        8. 调用getSingleton方法
          • beforeSingletonCreation 标志当前的bean正在被创建
        9. CeateBean 创建bean
          • resolveBeforeInstantation 在aop过程中寻找切面(Aspectj)
          • doCreateBean 真正调用创建bean的方法
      • org.springframework.bean.factory.support.AbstarctAutowireCapableBeanFactory # doCreateBean()
        1. createBeanInstance() 调用构造器,创建 “早期对象”(属性未赋值)
        2. 提前暴露早期对象,存入缓存池
    • 假如InsatcneA与InstanceB互相依赖
      • 创建A时先将A的早期对象存入缓存池
      • 发现A依赖B,则走创建B的流程,将B的早期对象存入缓存池
      • 发现B又依赖A,则再次走创建A的流程,直接从缓存池中获取A对象,完成B的创建
      • 进而完成A的创建
  • 什么样的循环依赖无法解决
    • 在构造器中依赖
    • 这种情况下创建实例A时,还未来得及将A的早期对象放入单例缓存池就调用了创建实例B的方法
  • 为什么多例模式无法解决循环依赖
    • 因为多例模式下,对象不会被存入单例缓存池,因此无法从单例缓存池获取对象

AOP

  • 为什么通过IOC容器获取到的组件是一个动态代理对象?
  • 什么时候生成的代理对象?
  • 代理对象存放在哪?

展开全文 >>

ElasticSearch

2019-09-05

说明

  • 基于lucene的搜索引擎,可以实现全文检索和及时搜索
  • 优势:
    • 基于RESTFUL web的接口
    • 分布式、高可扩展性
  • 逻辑结构:倒排索引表
    1. 将要搜索的文档内容分词,所有不重复的词组成分词列表。
    2. 将搜索的文档最终以Document方式存储起来。
    3. 每个词和docment都有关联。
    • 根据分词查询对应的文档,查询到多个文档时,根据一定的算法(如:相似性算法,仅计算匹配词条的数量)选择最优的一个

安装

  • ElasticSearch 服务
    • 下载 https://www.elastic.co/downloads/past-releases
    • 解压
    • 修改配置文件 /
  • ElasticSearch-head 可视化插件(基于node.js)
    • git clone git://github.com/mobz/elasticsearch-head.git
    • npm install
    • npm run start

集群

  • 集群说明
    1. 结点
      • ES集群由多个服务器组成,每个服务器即为一个Node结点(该服务只部署了一个ES进程)。
    2. 分片
      • 当文档量很大时,由于内存和硬盘的限制,同时也为了提高ES的处理能力、容错能力及高可用能力,将索引分成若干分片(每个分片都是一个lucene实例)
      • 每个分片可以放在不同的服务器,实现多个服务器共同对外提供索引及搜索服务
      • 当一个搜索请求过来,会分别从各各分片去查询,最后将查询到的数据合并返回给用户
    3. 副本
      • 为了提高ES的高可用同时也为了提高搜索的吞吐量,将分片复制一份或多份存储在其它的服务器,
        即使当前的服务器宕机,拥有副本的服务器照常可以提供服务。
    4. 主结点
      • 一个集群中会有一个或多个主结点,主结点的作用是集群管理,比如增加节点,移除节点等,主结点挂掉后ES会重新选一个主结点。
    5. 结点转发
      • 每个结点都知道其它结点的信息,因此可以对任意一个结点发起请求,接收到请求的结点会转发给其它结点查询数据。
  • 节点角色
    1. 主节点 master
      • 用于集群的管理及索引,比如新增结点、分片分配、索引的新增和删除等
    2. 数据节点 data
      • 保存了数据分片,负责索引和搜索操作
    3. 客户端节点 client
      • 仅作为请求客户端存在,client也作为负载均衡器,client节点不存数据,只是将请求均衡转发到其它结点

使用

  1. 索引管理

    • 每个索引包含term(分词)和document(文档)
    • 对索引进行CRUD操作(通过发送HTTP请求实现)
      • 创建索引
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        put http://el的ip:端口/索引名称

        {
        "settings":{
        "index":{
        "number_of_shards":1,#分片的数量
        "number_of_replicas":0#副本数量
        }
        }
        }
  2. 文档管理

    • 对文档进行CRUD操作(通过发送HTTP请求实现)
      • 添加文档
        • PUT /{index}/{type}/{id} { “field”: “value”, … } 如果不指定id,ES会自动生成。
      • 查询文档
        • GET /{index}/{type}/{id}
      • 修改文档
        • ES更新文档的顺序是 先检索到文档、将原来的文档标记为删除、创建新文档、删除旧文档,创建新文档就会重建索引
        • 通过请求Url有两种方法:
          1. 完全替换 POST:/{index}/{type}/{id} 根据id删除
          2. 局部更新 POST: /{index}/{type}/{id}/_update 搜索匹配删除,将搜索出来的记录删除
      • 删除文档
        1. DELETE /{index}/{type}/{id}
        2. POST /{index}/{type}/_delete_by_query
  3. 映射管理
    • 每个document中包含一个或多个field
    • 对映射进行CRUD操作(通过发送HTTP请求实现)
      • 创建映射
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        put http://localhost:9200/索引库名称/类型名称/_mapping

        {
        "properties": {
        "name": {
        "type": "text",
        "analyzer":"ik_max_word",
        "search_analyzer":"ik_smart"
        },
        "description": {
        "type": "text",
        "analyzer":"ik_max_word",
        "search_analyzer":"ik_smart"
        },
        "studymodel": {
        "type": "keyword"
        },
        "price": {
        "type": "float"
        },
        "timestamp": {
        "type": "date",
        "format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd||epoch_millis"
        }
        }
        }
  • 注意!:

    • 6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。
    • 创建索引库相当于关系数据库中的数据库还是表?
      • 如果相当于数据库就表示一个索引库可以创建很多不同类型的文档,这在ES中也是允许的
      • 如果相当于表就表示一个索引库只能存储相同类型的文档,ES官方建议 在一个索引库中只存储相同类型的文档
  • 映射(field)

    • document中除了可以保存字符串类性的field,还能保存数值、日期等类型
    • 常用映射数据类型
      1. 字符串:
        • text 会分词
        • keyword 不分词,keyword字段为关键字字段,通常按照整体搜索,因此创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等
      2. 数值
        byte、short、integer、long、float、double、half_float、scaled_float
        与一般的数值基本类型类似
        (优化) 尽量选择范围小的类型,提高搜索效率 (优化) 对于浮点数尽量用比例因子scaled_float(),把浮点变为整型再存储,好处是整型比浮点型更易压缩,节省磁盘空间,没有适合的比例因子时再选择范围最小的
        • half_float < float < double
      3. 日期
      4. 布尔
      5. 二进制
      6. 等级 range(用于范围过虑)

分词器

  • 什么是分词器?
    • 添加文档时会进行分词,索引中存放的就是一个一个的词(term),当搜索时就是用关键字匹配词(term),最终找到词关联的文档。
    • 因此对一段内容创建索引,首先就要对该内容进行分词,分词通过分词器实现
    • ElasticSearch默认使用的分词器- analyze 是将单个的字作为分词条件,针对中文分词时不适用
    • 中文分词使用IK作为分词器,需要下载IK,解压后复制到ElasticSearch安装目录的plugins下的ik目录下
  • 分词模式:

    • ik_max_word:会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为 中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等
    • ik_smart:会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为 中华人民共和国、人民大会堂

      *(优化) 建议创建索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性

  • 自定义词库:让分词器支持一些专有词语(扩展默认字典)

    • iK分词器自带一个main.dic的文件,此文件为词库文件
    • 在目录中新建一个my.dic文件,作为扩展词库
    • 在配置文件中添加扩展词库配置,引入my.dic

过滤器

  • 过虑是针对搜索的结果进行过虑,过虑器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过虑器性能比查询要高,且方便缓存
  • (优化) 推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用

展开全文 >>

FastDFS

2019-09-05

分布式文件管理系统

  • 作用:
    • 通过网络将单机上的文件系统组成一个网络文件系统。
    • 可以快速扩容存储,提高文件访问速度。
    • 主要应用在大型互联网项目中,实现图片存储、音视频存储等服务。
  • 服务端
    • 主:元信息(文件名称、大小、分块信息等)
    • 从:文件分块
  • 客户端
    • 查询: 从主服务器获取文件元信息,通过元信息操作从服务器,进而获取文件
    • 修改:更新主服务器的元信息,由服务端自动实现对文件的分块存储
      通用分布式文件管理系统:
    • NFS、GFS、HDFSC
      分布式文件服务提供商(Object Storage Service) OSS:
    • 阿里云、七牛云

专用分布式文件管理系统 – FastDFS

  • 使用场景:多用于存储小文件,存储不分块,减少文件拆分、合并造成的额外开销
  • 角色:

    • Tracker server

      • 可以将tracker称为追踪服务器或调度服务器。
      • 负责负载均衡和调度,通过Tracker server在文件上传时可以根据一些策略找到Storage server提供文件上传服务。
      • 存在多个Tracker server组件集群时,各个服务实例平等对外提供服务,客户端采用轮询的方式调用集群中的服务实例。
      • 客户端请求Tracker服务时,不是由tracker直接操作storage完成文件的上传。
      • 而是由tracker告诉客户端一个可用的storage服务的ip和端口,由客户端自己请求storage服务,完成对文件的操作
      • 客户端操作storage服务完成文件上传后,storage向客户端响应file_id,该file_id用于以后访问该文件(文件id即路径(组名/虚拟磁盘路径/数据两级目录/文件名))
    • Storage server

      • 作用是文件存储,客户端上传的文件最终存储在Storage服务器上,Storage server没有实现自己的文件系统,而是使用操作系统的文件系统来管理文件。
      • storage集群由一个或多个组构成,一个组由一台或多台存储服务器组成,集群存储总容量为集群中所有组的存储容量之和。
      • 组内的Storage server之间是平等关系,不同组的Storage server之间不会相互通信,
      • 同组内的Storage server之间会相互连接进行文件同步,从而保证同组内每个storage上的文件完全一致的。
      • 一个组的存储容量为该组内的存储服务器容量最小的那个,因此组内存储服务器的软硬件配置最好一致。
        • 用分组存储方式的好处是灵活、可控性较强。
        • 上传文件时,可以由客户端直接指定上传到的组也可以由tracker进行调度选择。
        • 一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向扩容)。
        • 当系统容量不足时,可以增加组来扩充存储容量(横向扩容)
      • Storage server会连接集群中所有的Tracker server,定时报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。
  • 文件上传流程
    文件上传流程
  • 文件下载流程
    文件下载流程

安装

  • Tracker安装
    • 施工中…
  • Storage安装
    • 施工中…
  • FastDFS-Nginx-module:
    • 在storage server上安装nginx的目的是对外通过http访问storage server上的文件。
    • 使用nginx的模块FastDFS-nginx-module的作用是通过http方式访问storage中的文件,当storage本机没有要找的文件时向源storage主机代理请求文件

展开全文 >>


title:Filter&Listener

Filter:过滤器

  • 什么说Filter:
    • web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
    • 过滤器的作用:
      • 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤…
  • Filter使用方法:

    • 步骤:
      1. 定义一个类,实现接口Filter
      2. 复写方法
      3. 配置拦截路径
        1. web.xml
        2. 注解
    • 代码:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      //访问所有资源之前,都会执行该过滤器
      @WebFilter("/*")
      public class FilterDemo1 implements Filter {
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {

      }

      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
      System.out.println("filterDemo1被执行了....");

      //放行
      filterChain.doFilter(servletRequest,servletResponse);

      }

      @Override
      public void destroy() {

      }
      }
  • 过滤器配置:

    • 基础配置(通过web.xml实现)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <filter>
      <filter-name>demo1</filter-name>
      <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
      </filter>
      <filter-mapping>
      <filter-name>demo1</filter-name>
      <!-- 拦截路径 -->
      <url-pattern>/*</url-pattern>
      </filter-mapping>
    • 拦截路径配置:

      1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
      2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
      3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
      4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
    • 拦截方式配置:资源被访问的方式
      • 注解配置:
        • 设置dispatcherTypes属性
          1. REQUEST:默认值。浏览器直接请求资源
          2. FORWARD:转发访问资源
          3. INCLUDE:包含访问资源
          4. ERROR:错误跳转资源
          5. ASYNC:异步访问资源
      • web.xml配置
        • 设置标签即可
  • 过滤器执行流程

    1. 执行过滤器
    2. 执行放行后的资源
    3. 回来执行过滤器放行代码下边的代码
  • 过滤器生命周期方法

    1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
    2. doFilter:每一次请求被拦截资源时,会执行。执行多次
    3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
  • 过滤器链(配置多个过滤器)

    • 执行顺序:如果有两个过滤器:过滤器1和过滤器2

      1. 过滤器1
      2. 过滤器2
      3. 资源执行
      4. 过滤器2
      5. 过滤器1
      6. 类似括号
    • 过滤器先后顺序:

      1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
        • 如: AFilter 和 BFilter,AFilter就先执行了。
      2. web.xml配置: 谁定义在上边,谁先执行

Listener:监听器

  • 什么是Listener:

    • web的三大组件之一(Servlet、Filter、Listener)
    • 事件监听机制
      • 事件 :一件事情
      • 事件源 :事件发生的地方
      • 监听器 :一个对象
      • 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
  • ServletContextListener:

    • 作用:监听ServletContext对象的创建和销毁
    • 方法:

      1
      2
      3
      4
      // ServletContext对象被销毁之前会调用该方法
      * void contextDestroyed(ServletContextEvent sce)
      // ServletContext对象创建后会调用该方法
      * void contextInitialized(ServletContextEvent sce)
    • 使用步骤:

      1. 定义一个类,实现ServletContextListener接口
      2. 复写方法
      3. 配置

        1. web.xml

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          <!-- 配置监听器,指定Listener类 -->
          <listener>
          <listener-class>com.test.listener.ContextLoaderListener</listener-class>
          </listener>

          <!-- 指定初始化参数 -->
          <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
          </context-param>
        2. 注解:

          • @WebListener

展开全文 >>

MVC:开发模式

  • 什么是MVC:
    1. M:Model,模型 → JavaBean
      • 完成具体的业务操作,如:查询数据库,封装对象
    2. V:View,视图。JSP
      • 展示数据
    3. C:Controller,控制器 → Servlet
      • 获取用户的输入
      • 调用模型
      • 将数据交给视图进行展示
  • MVC作用:
    1. 降低组件耦合性低,方便维护,可以利于分工协作
    2. 提高代码重用性
      MVC开发模式

三层架构:软件设计架构

  • 界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互
  • 业务逻辑层:处理业务逻辑的。
  • 数据访问层:操作数据存储文件。
    三层架构

展开全文 >>

jsp

2019-08-11

jsp

  • 什么是jsp:Java Server Pages: java服务器端页面
    • 个特殊的页面,其中既可以指定定义html标签,又可以定义java代码,出现的初衷是用于简化书写
  • jsp原理
    • 在程序运行过程中,由web容器在work目录下生成一个对应的xx_jsp.java类,该类继承了HttpJspBase
    • HttpJspBase继承HttpServlet,因此JSP本质上就是一个Servlet
  • jsp的脚本:JSP定义Java代码的方式
    1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
    2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
    3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
  • jsp指令
    • 作用:用于配置JSP页面,导入资源文件
    • 格式:
      <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %>
    • 分类:
      1. page : 配置JSP页面
        • contentType:等同于response.setContentType()
          1. 设置响应体的mime类型以及字符集
          2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
        • import:导包
        • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
        • isErrorPage:标识当前也是是否是错误页面。
          • true:是,可以使用内置对象exception
          • false:否。默认值。不可以使用内置对象exception
      2. include :页面嵌套。导入页面的资源文件
        • <%@include file=”top.jsp”%>
      3. taglib :导入资源
        • <%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core" %>
          • prefix:前缀,可以自定义
  • jsp注释:
    1. html注释: <!-- -->: 只能注释html代码片段
    2. jsp注释:推荐使用
      <%– –%>:可以注释所有
  • JSP的内置对象:
    • 在jsp页面中不需要获取和创建,可以直接使用的对象
    • jsp的9个内置对象:
      1. pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象
      2. request HttpServletRequest 一次请求访问的多个资源(转发)
      3. session HttpSession 一次会话的多个请求间
      4. application ServletContext 所有用户间共享数据
      5. response HttpServletResponse 响应对象
      6. page Object 当前页面(Servlet)的对象 this
      7. out JspWriter 输出对象,数据输出到页面上
        • response.getWriter()和out.write()的区别:
        • 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
        • response.getWriter()数据输出永远在out.write()之前
      8. config ServletConfig Servlet的配置对象
      9. exception Throwable 异常对象

EL表达式

  • 什么是EL表达式:
    • Expression Language 表达式语言
  • EL表达式作用:
    • 替换和简化jsp页面中java代码的编写
  • EL表达式语法:
    • ${表达式}
    • 注意事项:jsp默认支持el表达式。如果要忽略el表达式
      1. 设置jsp中page指令中:isELIgnored=”true” 忽略当前jsp页面中所有的el表达式
      2. \${表达式} :忽略当前这个el表达式
  • EL表达式语法:
    1. 运算:
      1. 算数运算符: + - * /(div) %(mod)
      2. 比较运算符: > < >= <= == !=
      3. 逻辑运算符: &&(and) ||(or) !(not)
      4. 空运算符: empty
        • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
        • ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
        • ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
    2. 获取值
      1. el表达式只能从域对象中获取值
      2. 语法:
        1. ${域名称.键名}:从指定域中获取指定键的值
          • 域名称:
            1. pageScope –> pageContext
            2. requestScope –> request
            3. sessionScope –> session
            4. applicationScope –> application(ServletContext)
          • 举例:在request域中存储了name=张三
          • 获取:${requestScope.name}
        2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
        3. 获取对象、List集合、Map集合的值
          1. 对象:${域名称.键名.属性名}
            • 本质上会去调用对象的getter方法
          2. List集合:${域名称.键名[索引]}
          3. Map集合:
            • ${域名称.键名.key名称}
            • ${域名称.键名[“key名称”]}
    3. 隐式对象:
      • el表达式中有11个隐式对象
      • pageContext:
        • 获取jsp其他八个内置对象
          • ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

  • 什么是JSTL:
    • JavaServer Pages Tag Library JSP标准标签库
    • 由Apache组织提供的开源的免费的jsp标签
  • JSTL的作用:
    • 把jsp页面上的java代码替换成标签
    • 简化jsp页面
  • JSTL使用步骤:
    1. 导入jstl相关jar包
    2. 引入标签库:taglib指令: <%@ taglib %>
    3. 使用标签
  • 常用的JSTL标签

    1. if:相当于java代码的if语句
      1. 属性:
        • test 必须属性,接受boolean表达式
          • 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
          • 一般情况下,test属性值会结合el表达式一起使用
        1. 注意:
          • c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
    2. choose:相当于java代码的switch语句
      1. 使用choose标签声明 相当于switch声明
      2. 使用when标签做判断 相当于case
      3. 使用otherwise标签做其他情况的声明 相当于default
    3. foreach:相当于java代码的for语句

      1. 完成重复的操作

        1
        2
        3
        <c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
        ${i} <h3>${s.index}<h3> <h4> ${s.count} </h4><br>
        </c:forEach>
        • begin:开始值
        • end:结束值
        • var:临时变量
        • step:步长
        • varStatus:循环状态对象
          • index:容器中元素的索引,从0开始
          • count:循环次数,从1开始
      2. 遍历容器

        1
        2
        3
        <c:forEach items="${list}" var="str" varStatus="s">
        ${s.index} ${s.count} ${str}<br>
        </c:forEach>
        • items:容器对象
        • var:容器中元素的临时变量
        • varStatus:循环状态对象
          • index:容器中元素的索引,从0开始
          • count:循环次数,从1开始

展开全文 >>

Cookie&Session

2019-08-04

会话技术

  • 什么是会话:
    • 一次会话中包含多次请求和响应。
    • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  • 会话的作用:
    • 在一次会话的范围内的多次请求间,共享数据
  • 会话实现方式:
    1. 客户端会话技术:Cookie
    2. 服务器端会话技术:Session

Cookie

  • 什么是Cookie:
    • 客户端会话技术,将数据保存到客户端
  • Cookie使用方法:

    1
    2
    3
    4
    5
    6
    // 1.创建Cookie对象,绑定数据
    new Cookie(String name, String value)
    // 2.发送Cookie对象
    response.addCookie(Cookie cookie)
    // 3.获取Cookie,拿到数据
    Cookie[] request.getCookies()
  • Cookie实现原理

    • 基于响应头set-cookie和请求头cookie实现
      cookie原理
  • cookie的细节
    1. 一次可不可以发送多个cookie?
      • 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
    2. cookie在浏览器中保存多长时间?
      1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
      2. 持久化存储:
        • setMaxAge(int seconds)
          1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
          2. 负数:默认值
          3. 零:删除cookie信息
    3. cookie能不能存中文?
      • 在tomcat 8 之前 cookie中不能直接存储中文数据。
        • 需要将中文数据转码—一般采用URL编码(%E3)
      • 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
    4. cookie共享问题?
      1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
        • 默认情况下cookie不能共享
        • setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
          • 如果要共享,则可以将path设置为”/“
      2. 不同的tomcat服务器间cookie共享问题?
        • setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
          • setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享
  • Cookie的特点和作用
    • 特点
      1. cookie存储数据在客户端浏览器
      2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
    • 作用:
      1. cookie一般用于存出少量的不太敏感的数据
      2. 在不登录的情况下,完成服务器对客户端的身份识别

Session

  • 什么是Session:
    • 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
  • Seesion使用方法:

    1
    2
    3
    4
    5
    6
    // 1.获取HttpSession对象:
    HttpSession session = request.getSession();
    // 2.使用HttpSession对象:
    Object getAttribute(String name)
    void setAttribute(String name, Object value)
    void removeAttribute(String name)
  • Session实现原理

    • Session的实现是依赖于Cookie的。
      Session实现原理
  • Session细节:

    1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
      • 默认情况下。不是。
      • 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
        Cookie c = new Cookie(“JSESSIONID”,session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
    2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
      • 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
        • session的钝化:
          • 在服务器正常关闭之前,将session对象序列化到硬盘上
          • 由tomcat实现,在tomcat的work目录中生成一个.ser文件
        • session的活化:
          • 在服务器启动后,读取session文件反序列化为内存中的session对象即可。
          • 由tomcat实现,将work目录中的.ser文件加载进内存
    3. session什么时候被销毁?
      1. 服务器关闭时被销毁
      2. session对象调用invalidate() 。
      3. session默认失效时间 30分钟,选择性配置修改,修改tomcat的web.xml文件
        1
        2
        3
        <session-config>
        <session-timeout>30</session-timeout>
        </session-config>
  • session的特点

    • session的特点
      1. session用于存储一次会话的多次请求的数据,存在服务器端
      2. session可以存储任意类型,任意大小的数据
    • session与Cookie的区别:
      1. session存储数据在服务器端,Cookie在客户端
      2. session没有数据大小限制,Cookie有
      3. session数据安全,Cookie相对于不安全

展开全文 >>

HttpServlet

2019-07-28

HTTP:

  • 什么是HTTP?
    • Hyper Text Transfer Protocol 超文本传输协议
  • 什么是传输协议?
    • 定义了,客户端和服务器端通信时,发送数据的格式
  • HTTP的特点:
    1. 基于TCP/IP的高级协议
    2. 默认端口号:80
    3. 基于请求/响应模型的:一次请求对应一次响应
    4. 无状态的:每次请求之间相互独立,不能交互数据
  • HTTP版本特性:

    • 1.0:每一次请求响应都会建立新的连接
    • 1.1:复用连接
  • HTTP请求消息数据格式

    • 字符串格式:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      POST /login.html	HTTP/1.1
      Host: localhost
      User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
      Accept-Encoding: gzip, deflate
      Referer: http://localhost/login.html
      Connection: keep-alive
      Upgrade-Insecure-Requests: 1

      username=zhangsan
    1. 请求行

      1
      2
      # 请求方式 请求url 请求协议/版本
      GET /login.html HTTP/1.1
    2. 请求头:客户端浏览器告诉服务器一些信息

      • 数据格式:(key : value)请求头名称: 请求头值
      • 常见的请求头:
        1. User-Agent:浏览器告诉服务器,浏览器版本信息
          • 作用:在服务器端获取该头的信息,解决浏览器的兼容性问题
        2. Referer:http://localhost/login.html
          • 作用:告诉服务器,当前请求来源
            1. 防盗链
            2. 统计工作
    3. 请求空行
      • 用于分割POST请求的请求头,和请求体
    4. 请求体(正文):
      • 封装POST请求消息的请求参数
  • HTTP响应消息数据格式

    • 数据格式:

      1. 响应行
        • 组成:协议/版本 响应状态码 状态码描述
        • 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
          1. 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
          2. 2xx:成功。代表:200
          3. 3xx:重定向。代表:302(重定向),304(访问缓存)
          4. 4xx:客户端错误。
            • 代表:
              • 404(请求路径没有对应的资源)
              • 405:请求方式没有对应的doXxx方法
          5. 5xx:服务器端错误。代表:500(服务器内部出现异常)
      2. 响应头:
        • 格式:头名称: 值
        • 常见的响应头:
          1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
          2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
            • 值:
              • in-line:默认值,在当前页面内打开
              • attachment;filename=xxx:以附件形式打开响应体。文件下载
      3. 响应空行
      4. 响应体:传输的数据
    • 响应字符串格式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      HTTP/1.1 200 OK
      Content-Type: text/html;charset=UTF-8
      Content-Length: 101
      Date: Wed, 06 Jun 2018 07:08:42 GMT

      <html>
      <head>
      <title>$Title$</title>
      </head>
      <body>
      hello , response
      </body>
      </html>
  • HTTP常用两种请求方法:

    • GET:
      1. 请求参数在请求行中,在url后。
      2. 请求的url长度有限制的
      3. 不太安全
    • POST:
      1. 请求参数在请求体中
      2. 请求的url长度没有限制的
      3. 相对安全

Request:

  1. request对象和response对象原理

    1. request和response对象是由服务器(web容器)创建
    2. request对象用于获取请求消息,response对象用于设置响应消息
  2. request对象继承体系结构:

    1
    2
    3
    4
    5
    ServletRequest		-- 接口
    | 继承
    HttpServletRequest -- 接口
    | 实现
    org.apache.catalina.connector.RequestFacade 类(tomcat)
  3. request主要功能:

    • 获取请求行数据 :GET /demo/testService?name=zhangsan HTTP/1.1

      1. 获取请求方式 :GET
        • String getMethod()
      2. 获取虚拟目录:/demo
        • String getContextPath()
      3. 获取Servlet路径: /demo1
        • String getServletPath()
      4. 获取get方式请求参数:name=zhangsan
        • String getQueryString()
      5. 获取请求URI:/demo/testService
        • String getRequestURI(): /demo/testService
        • StringBuffer getRequestURL(): http://localhost/demo/testService
      6. 获取协议及版本:HTTP/1.1
        • String getProtocol()
      7. 获取客户机的IP地址:
        • String getRemoteAddr()
    • 获取请求头数据

      • String getHeader(String name):通过请求头的名称获取请求头的值
      • Enumeration getHeaderNames():获取所有的请求头名称
    • 获取请求体数据:

      • 只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
      1. 获取流对象
        • BufferedReader getReader():获取字符输入流,只能操作字符数据
        • ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
      2. 再从流对象中拿数据
  4. request其他功能:

    • 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

      1. String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
      2. String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
      3. Enumeration getParameterNames():获取所有请求的参数名称
      4. Map<String,String[]> getParameterMap():获取所有参数的map集合
      • 中文乱码问题:
        • get方式:tomcat 8 已经将get方式乱码问题解决了
        • post方式:会乱码
          • 解决:在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”);
    • 请求转发:一种在服务器内部的资源跳转方式

      1. 步骤:
        1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
        2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
      2. 特点:
        1. 浏览器地址栏路径不发生变化
        2. 只能转发到当前服务器内部资源中。
        3. 转发是一次请求
    • 共享数据:

      • 域对象:一个有作用范围的对象,可以在范围内共享数据
      • request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
        1. void setAttribute(String name,Object obj):存储数据
        2. Object getAttitude(String name):通过键获取值
        3. void removeAttribute(String name):通过键移除键值对
    • 获取ServletContext:
      • ServletContext getServletContext()

Response对象

  • 功能:设置响应消息

    1. 设置响应行
      1. 格式:HTTP/1.1 200 ok
      2. 设置状态码:setStatus(int sc)
    2. 设置响应头:setHeader(String name, String value)

    3. 设置响应体:

      • 使用步骤:

        1. 获取输出流

          • 字符输出流:PrintWriter getWriter()

          • 字节输出流:ServletOutputStream getOutputStream()

        2. 使用输出流,将数据输出到客户端浏览器
  • 重定向:资源跳转的方式

    • 实现方法:

      1. 通过设置响应状态和响应头实现

        1
        2
        3
        4
        //1. 设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/day15/responseDemo2");
      2. 通过response对象封装的方法实现

        1
        2
        //简单的重定向方法
        response.sendRedirect("/day15/responseDemo2");
    • forward 和 redirect 区别

      • 重定向的特点:redirect
        1. 地址栏发生变化
        2. 重定向可以访问其他站点(服务器)的资源
        3. 重定向是两次请求。不能使用request对象来共享数据
      • 转发的特点:forward
        1. 转发地址栏路径不变
        2. 转发只能访问当前服务器下的资源
        3. 转发是一次请求,可以使用request对象来共享数据
  • 路径写法:

    1. 相对路径:通过相对路径不可以确定唯一资源
      • 不以/开头,以.开头路径
      • 如:./index.html
      • ./可省略,直接写成 index.html也表示相对路径
      • 使用规则:找到当前资源和目标资源之间的相对位置关系
        • ./:当前目录
        • ../:后退一级目录
    2. 绝对路径:通过绝对路径可以确定唯一资源
      • 如:http://localhost/demo/responseDemo2
      • 前面的协议名称、ip、端口号等可省略,变成 /demo/responseDemo2
      • 以/开头的路径
      • 使用规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
        • 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
          • 虚拟目录动态获取:request.getContextPath()
        • 给服务器使用:不需要加虚拟目录
          • 转发路径
  • 服务器输出数据到浏览器

    1. 服务器输出字符数据到浏览器

      • 步骤:
        1. 获取字符输出流
        2. 输出数据
      • 乱码问题:
        1. PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
        2. 设置该流的默认编码
        3. 告诉浏览器响应体使用的编码
          1
          2
          //简单的形式,设置编码,是在获取流之前设置
          response.setContentType("text/html;charset=utf-8");
    2. 服务器输出字节数据到浏览器

      • 步骤:
        1. 获取字节输出流
        2. 输出数据

ServletContext对象:

  • 概念:代表整个web应用,可以和程序的容器(服务器)来通信
  • 获取ServletContext对象:
    1. 通过request对象获取
      request.getServletContext();
    2. 通过HttpServlet获取
      this.getServletContext();
  • ServletContext对象功能:

    1. 获取MIME类型:

      • MIME类型:在互联网通信过程中定义的一种文件数据类型
        • 格式: 大类型/小类型 text/html image/jpeg
      • 方法:
        1
        String getMimeType(String file)
    2. 域对象:共享数据

      • ServletContext对象范围:所有用户所有请求的数据
      • 方法:
        1
        2
        3
        setAttribute(String name,Object value)
        getAttribute(String name)
        removeAttribute(String name)
    3. 获取文件的真实(服务器)路径

      • 方法:String getRealPath(String path)
        1
        2
        3
        4
        5
        6
        7
        8
        9
        //web目录下资源访问
        String b = context.getRealPath("/b.txt");
        System.out.println(b);
        //WEB-INF目录下的资源访问
        String c = context.getRealPath("/WEB-INF/c.txt");
        System.out.println(c);
        //src目录下的资源访问
        String a = context.getRealPath("/WEB-INF/classes/a.txt");
        System.out.println(a);

展开全文 >>

Servlet

2019-07-21

什么是Servlet

  • 运行在服务器端的小程序
  • Servlet是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。

如何使用Servlet

  1. 创建JavaEE项目
  2. 定义一个类,实现Servlet接口,复写接口方法
    • public class ServletDemo implements Servlet
  3. 实现接口中的抽象方法
  4. 配置Servlet
    在web.xml中配置:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!--配置Servlet -->
    <servlet>
    <servlet-name>demo</servlet-name>
    <servlet-class>com.test.servlet.ServletDemo</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>demo</servlet-name>
    <url-pattern>/demo</url-pattern>
    </servlet-mapping>

Servlet执行流程

  1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径(URI)
  2. 查找web.xml文件,是否有对应的标签体内容。
  3. 如果有,则在找到对应的全限定类名
  4. tomcat将字节码文件加载进内存(Class.forName()),并且创建其对象(class.newInstance())
  5. 调用其方法(service())
  • Servlet中的生命周期方法:
    1. init: Servlet对象被创建时执行,只执行一次
      • Servlet什么时候被创建?
        • 默认情况下,第一次被访问时,Servlet被创建
        • 可以配置执行Servlet的创建时机,在标签下配置
          1. 第一次被访问时创建:的值为负数
          2. 在服务器启动时创建:的值为0或正整数
      • Servlet的init方法只执行一次,说明一个Servlet在内存中只存在一个对象,是单例的
        • 多个用户同时访问时,可能存在线程安全问题。
        • 因此尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改
    2. service:提供服务时执行,执行多次
      • 每次访问Servlet时,Service方法都会被调用一次。
    3. destory:Servlet对象被销毁时执行,只执行一次
      • 服务器关闭时,Servlet被销毁
      • 只有服务器正常关闭时,才会执行destroy方法
      • destroy方法在Servlet被销毁之前执行,一般用于释放资源

Servlet3.0:

  • 支持注解配置,可以不需要配置web.xml
  • 使用步骤:

    1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
    2. 定义一个类,实现Servlet接口
    3. 复写方法
    4. 在类上使用@WebServlet注解,进行配置
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      @WebServlet("资源路径")
      @Target({ElementType.TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      public @interface WebServlet {
      // 相当于<Servlet-name>
      String name() default "";

      // 代表urlPatterns()属性配置
      String[] value() default {};

      // 相当于<url-pattern>
      String[] urlPatterns() default {};

      // 相当于<load-on-startup>
      int loadOnStartup() default -1;

      WebInitParam[] initParams() default {};

      boolean asyncSupported() default false;

      String smallIcon() default "";

      String largeIcon() default "";

      String description() default "";

      String displayName() default "";
      }
  • 相关配置

    1. 一个Servlet可以定义多个访问路径(urlpartten) : @WebServlet({“/d4”,”/dd4”,”/ddd4”})
    2. 路径定义规则:
      • /xxx:路径匹配
      • /xxx/xxx:多层路径,目录结构
      • *.do:扩展名匹配

Servlet的体系结构

  1. Servlet – 接口
  2. GenericServlet – 抽象类
    • GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
    • 定义Servlet类时,可以继承GenericServlet,实现service()方法即可
  3. HttpServlet – 抽象类
    • HttpServlet:对http协议的一种封装,简化操作
    • 定义类继承HttpServlet
    • 复写doGet/doPost方法

展开全文 >>

Linux定时任务删除指定时间前的文件

2019-07-14

新建一个文件

1
touch /xxx/xxx/clearfiles

赋予文件权限

1
chomd 755 /xxx/xxx/clearfiles

编辑文件,在新建的clearfiles中按需求添加删除命令

1
2
3
#!/bin/sh
find /mnt/www/Application/Runtime/Logs -mtimes +10 -name *.* -exec rm -rf {} \;
find /tmp -type f -mmin 120 -name *.log -exec rm -rf {} \;
  • 说明:
    • find 后面紧跟的是要查找的目录,. 表示当前目录
      • -type f: 指定查找对象为文件
    • -name *.log: 指定查找对象名称以.log结尾
      • -mtime +10: 查找10天以前的老文件
      • -mmin +120: 查找120分钟(两小时)以前的老文件
      • -exec rm -rf {} /; :对查找到的文件执行删除命令
  • 注意:
    • -exec rm -rf {} /; 中{}之间不能有空格
    • {}与/之间必须带空格
    • /是转译符,这里与;配对使用
    • 新建的clearfiles这里不能是.sh后缀结尾,否则执行会报错

将clearfiles加入定时任务

  • 执行命令,打开crontab配置文件

    1
    crontab -e
  • 在配置文件中添加配置,保存

    1
    2
    # 每分钟执行一次
    */1 * * * * /usr/local/bin/clear_log
  • 完成配置后重启crond服务

    1
    service crond restart
  • 说明

    • 用户通过crontabl -e命令建立的Crontab文件存于/var/spool/cron中,其文件名与用户名一致
    • 它的格式共分为六段,前五段为时间设定段,第六段为所要执行的命令段
    • 格式如下:f1 f2 f3 f4 f5 command/program
    • f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的命令或程序。
    • 当 f1 为 时表示每分钟都要执行 program,f2 为 时表示每小时都要执行程序,以此类推
    • 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,以此类推
    • 当 f1 为 /n 时表示每 n 分钟个时间间隔执行一次,f2 为 /n 表示每 n 小时个时间间隔执行一次,以此类推
    • 当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,以此类推

展开全文 >>

123Next »
© 2019 大西洲总督
Hexo Theme Yilia by Litten
  • 所有文章
  • 关于我

tag:

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • spring笔记

    2019-09-15

  • ElasticSearch

    2019-09-05

  • FastDFS

    2019-09-05

  • 2019-08-25

  • 2019-08-18

  • jsp

    2019-08-11

  • Cookie&Session

    2019-08-04

  • HttpServlet

    2019-07-28

  • Servlet

    2019-07-21

  • Linux定时任务删除指定时间前的文件

    2019-07-14

  • RabbitMQ

    2019-07-07

  • 集合

    2019-06-30

  • 分布式事务

    2019-06-23

  • Java多线程

    2019-06-16

  • java类

    2019-06-09

  • vim使用技巧

    2019-06-02

  • dubbo

    2019-05-26

  • Junit单元测试

    2019-05-19

  • 反射与注解

    2019-05-12

  • 《程序是怎样跑起来的》读书笔记

    2019-05-04

  • 《计算机是怎样跑起来的》读书笔记

    2019-05-03

  • maven笔记

    2019-04-28

  • RPC框架

    2019-04-21

  • java打包

    2019-04-14

  • 设计模式

    2019-04-07

  • xml笔记

    2019-04-07

  • Web services笔记

    2019-03-30

  • 通过Hexo搭建个人博客

    2019-03-27

  • 开端

    2019-03-26

  • Hello World

    2019-03-25

Just want to do something interesting.