JavaWeb知识汇总

  • 一、Servlet
  • 二、HTTP
    • 1. HTTP协议简介
    • 2.HTTPS
  • 三、Request
  • 四、Response
  • 五、ServletContext
  • 六、ServletConfig(了解)
  • 七、Cookie和Session
    • 1.会话技术
    • 2.Cookie
    • 3.Session
  • 八、JSP
  • 九、 EL &JSTL
    • 1. EL表达式
    • 2. JSTL
  • 十、Filter
  • 十一、Listener
  • 十二、 MVC和三层架构
  • 十三、Ajax
  • 十四、JSON
    • 1.jackson
    • 2.Jsonlib

使用PC浏览,体验更加!!!!

一、Servlet

  • 概念:servlet是一个在Web服务器中运行的小型Java程序。主要功能在于交互
    式地浏览和修改数据,⽣成动态Web内容。

    A servlet is a small Java program that runs within a Web server

    • Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
    • 未来我们可以自定义一个类,实现Servlet接口,复写方法。
  • 快速入门

    1. 创建JavaEE项目

    2. 定义一个类,实现Servlet接口
      public class ServletDemo1 implements Servlet

    3. 实现接口中的抽象方法

    4. 配置Servlet
      在web.xml中配置:

           <!--配置Servlet --><servlet><servlet-name>demo1</servlet-name><!--全类名--><servlet-class>cn.itcast.web.servlet.ServletDemo1</servlet-class></servlet><servlet-mapping><servlet-name>demo1</servlet-name><!--资源路径--><url-pattern>/demo1</url-pattern></servlet-mapping>
      
  • 执行原理:

    1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径。
    2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
    3. 如果有,则在找到对应的<servlet-class>全类名。
    4. tomcat会将对应的Servlet字节码文件加载进内存,并且创建其对象。
    5. 调用其方法。
    
  • Servlet生命周期

    1. 当客户端⾸次发送第⼀次请求后,由容器(web服务器(tomcat))去解析请求。
    2.  根据请求找到对应的servlet,判断该类的对象是否存在。
    3. 不存在则创建servlet实例,调取init()⽅法 进⾏初始化操作。
    4. 初始化完成后调取service()⽅法,由service()判断客户端的请求⽅式。
    5. 如果是get,则执⾏doGet()。
    6. 如果是post则执⾏doPost()。
    7. 处理⽅法完成后,作出相应结果给客户端.单次请求处理完毕。
    8. 当服务器关闭时调取destroy()⽅法进⾏销毁
    

    对于同一个Servlet,当⽤户发送第2~n次请求时,不再执⾏init(),⽽直接执⾏service()⽅法,调取doGet()/doPost()⽅法。

  • Servlet中的生命周期方法

    1. 被创建:执行init()方法,只执行一次Servlet什么时候被创建?默认情况下,第一次被访问时,Servlet被创建。通过web.xml文件,可以配置Servlet的创建时机。在<servlet>标签下配置1. 第一次被访问时,创建<load-on-startup>的值为负数。2. 在服务器启动时,创建<load-on-startup>的值为0或正整数,正数情况下,数值越⼩,加载该Servlet的优先级越⾼。Servlet的init()方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的多个用户同时访问时,可能存在线程安全问题。解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值2. 提供服务:执行service()方法,执行多次每次访问Servlet时,service()方法都会被调用一次。3. 被销毁:执行destroy()方法,只执行一次Servlet被销毁时执行。服务器关闭时,Servlet被销毁只有服务器正常关闭时,才会执行destroy()方法。destroy()方法在Servlet被销毁之前执行,一般用于释放资源*  Servlet3.0:好处:支持注解配置。可以不需要web.xml了。步骤:1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml2. 定义一个类,实现Servlet接口3. 复写方法4. 在类上使用@WebServlet注解,进行配置* @WebServlet("资源路径")示例:@WebServlet(urlPatterns = {"/test"},initParams ={@WebInitParam(name = "code",value = "utf-8")         },loadOnStartup = 1)public class TestServlet extends HttpServlet {}
    

关于@WebServlet的注解类如下:

 @Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface WebServlet {String name() default "";//相当于<Servlet-name>String[] value() default {};//代表urlPatterns()属性配置String[] urlPatterns() default {};//相当于<url-pattern>int loadOnStartup() default -1;//相当于<load-on-startup>WebInitParam[] initParams() default {};boolean asyncSupported() default false;String smallIcon() default "";String largeIcon() default "";String description() default "";String displayName() default "";}
  • Servlet体系结构

     Servlet -- 接口|GenericServlet -- 抽象类|HttpServlet  -- 抽象类* GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象* 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可* HttpServlet:对service()方法做了详细的实现,不再需要我们写代码判断用户的请求方式,对http协议的一种封装,简化操作1. 定义类继承HttpServlet2. 复写doGet/doPost方法
    
  • Servlet相关配置
    1. urlpartten:Servlet访问路径(资源路径)1. 一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})2. 路径定义规则:1. /xxx:路径匹配2. /xxx/xxx:多层路径,目录结构3. *.do:扩展名匹配ps: /user/.do、/.do、test*.do都是非法的,启动时候会报错
    

二、HTTP

1. HTTP协议简介

  • 概念:超⽂本传输协议(英⽂:HyperText Transfer Protocol,缩写:HTTP)是⼀种⽤于分布式、协作式和超媒体信息系统的应⽤层协议。HTTP是万维⽹的数据通信的基础。定义了客户端和服务器端通信时,交互报文的格式

  • 特点:
    1. 基于TCP/IP的高级协议
    2. 默认端口号:80
    3. 基于请求/响应模型的:一次请求对应一次响应
    4. 在HTTP/1.0中默认使⽤短连接。也就是说,客户端和服务器每进⾏⼀次HTTP操作,就建⽴⼀次连接,任务结束就中断连接。
    5. 无状态协议:HTTP协议自身不对请求和响应之间的通信状态进行保存。每次请求之间相互独立,不能交互数据。
    6. HTTP/1.1起,默认使⽤⻓连接,⽤以保持连接特性。使⽤⻓连接的HTTP协议,会在响应头加⼊这⾏
    代码:

    Connection:keep-alive

    在使⽤⻓连接的情况下,当⼀个⽹⻚打开完成后,客户端和服务器之间⽤于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使⽤这⼀条已经建⽴的连接。Keep-Alive不会永久保持连接,它有⼀个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现⻓连接需要客户端和服务端都⽀持⻓连接。

  • 请求消息(报文)格式: 客户端发送给服务器端的数据

    1. 请求行请求方式                请求url                                       请求协议/版本GET                http://localhost:8080/thumbupTest/index.jsp            HTTP/1.1请求方式:HTTP协议有7中请求方式,常用的有2种GET:1. 请求参数在请求行中,在url后。2. 请求的url长度有限制的3. 不太安全POST:1. 请求参数在请求体中2. 请求的url长度没有限制的3. 相对安全
    2. 请求头:客户端浏览器告诉服务器一些信息请求头名称: 请求头值常见的请求头:1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息* 可以在服务器端获取该头的信息,解决浏览器的兼容性问题2. Referer:http://localhost/login.html告诉服务器,我(当前请求)从哪里来?作用:1. 防盗链:通过条件判断指定从某条URL跳转过来到当前页面才正常显示2. 统计工作:可以统计从某个URL跳转到当前页面的用户数
    3. 请求空行空行,就是用于分割POST请求的请求头,和请求体的。
    4. 请求体(正文):封装POST请求消息的请求参数的格式: username=zhangsan * 字符串格式(请求头):POST /login.html    HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-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.2Accept-Encoding: gzip, deflateReferer: http://localhost/login.htmlConnection: keep-aliveUpgrade-Insecure-Requests: 1
    
  • 响应消息(报文)格式: 服务器端发送给客户端的数据

    数据格式:
    1. 响应行1. 组成:协议/版本     响应状态码      状态码描述示例: HTTP/1.1      200             OK2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。1. 状态码都是3位数字 2. 分类:1. 1xx:服务器接收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码2. 2xx:成功。代表:2003. 3xx:重定向。代表:302(重定向),304(访问缓存)4. 4xx:客户端错误。* 代表:* 404(请求路径没有对应的资源) * 405:请求方式没有对应的doXxx方法5. 5xx:服务器端错误。代表:500(服务器内部出现异常)
    2. 响应头:1. 格式:头名称: 值2. 常见的响应头:1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据* 值:* in-line:默认值,在当前页面内打开* attachment;filename=xxx:以附件形式打开响应体。文件下载需设置此响应头
    3. 响应空行
    4. 响应体:传输的数据
    5.
    * 响应字符串格式HTTP/1.1 200 OKContent-Type: text/html;charset=UTF-8Content-Length: 101Date: Wed, 06 Jun 2018 07:08:42 GMT<html><head><title>$Title$</title></head><body>hello , response</body></html>
  • 常见状态码

    状态码 状态码描述 含义
    100 Continue 只有⼀部分请求被服务器接收,但只要没被服务器拒绝,客户端就会延续这个请求
    101 Switching Protocols 服务器交换机协议
    200 OK 请求被确认
    201 Created 请求时完整的,新的资源被创建
    202 Accepted 请求被接受,但未处理完
    300 Multiple Choices ⼀个超链接表,⽤户可以选择⼀个超链接并访问,最⼤⽀持5个超链接
    301 Moved Permanently 被请求的⻚⾯已经移动到了新的URL下
    302 Found 被请求的⻚⾯暂时性地移动到了新的URL下
    303 See Other 被请求的⻚⾯可以在⼀个不同的URL下找到
    400 Bad Request 服务器⽆法识别请求
    403 Forbidden 禁⽌访问所请求的⻚⾯
    404 Not Found 服务器⽆法找到所请求的⻚⾯
    405 Method Not Allowed 请求中所指定的⽅法不被允许
    500 Internal Server Error 请求不完整,服务器遇⻅了出乎意料的状况
    501 Not Implemented 请求不完整,服务器不提供所需要的功能
    502 Bad Gateway 请求不完整,服务器从上游服务器接受了⼀个⽆效的响应
    503 Service Unavailable 请求不完整,服务器暂时重启或关闭
    504 Gateway Timeout ⽹关超时
    505 HTTP Version Not Supported 服务器不⽀持所指定的HTTP版本

2.HTTPS

HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),
是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。
HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。
这个系统提供了身份验证与加密通讯方法。
它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。
  • 详情请看 HTTPS

三、Request

  • Request对象和Response对象的原理

    1.客户端发送请求后,Tomcat服务器会根据请求URL中的资源路径(Servlet访问路径),创建对应的Servlet对象。
    2. Tomcat服务器,会创建request和response对象,并将请求消息(请求报文)数据封装到request对象中。
    3. Tomcat将request和response两个对象传递给service()方法,并且调用service()方法。
    4. 后续,程序员可以通过request对象获取请求消息数据,通过response对象设置响应消息(响应报文)数据。
    5. 服务器给浏览器作出响应之前会从response对象中获取程序员设置的响应消息数据。

  • Request对象继承体系结构

    ServletRequest       --  接口| 继承
    HttpServletRequest  -- 接口|  实现
    org.apache.catalina.connector.RequestFacade 类(tomcat)public class RequestFacade implements HttpServletRequest
    
  • Request功能

    1. 获取请求消息(报文)数据1. 获取请求行数据* GET        http://localhost:8080/day14/demo1?name=zhangsan           HTTP/1.1* 方法:1. 获取请求方式 :GET* String getMethod()  2. (*)获取虚拟目录:/day14* String getContextPath()3. 获取Servlet路径: /demo1* String getServletPath()4. 获取get方式请求参数:name=zhangsan* String getQueryString()5. (*)获取请求URI:/day14/demo1* String getRequestURI():      /day14/demo1* StringBuffer getRequestURL()  :http://localhost/day14/demo1* URL:统一资源定位符 : http://localhost/day14/demo1        例如:中华人民共和国* URI:统一资源标识符 : /day14/demo1                    例如:共和国6. 获取协议及版本:HTTP/1.1* String getProtocol()7. 获取客户机的IP地址:* String getRemoteAddr()  // 0:0:0:0:0:0:0:12. 获取请求头数据* 方法:* (*)String getHeader(String name):通过请求头的名称获取请求头的值* Enumeration<String> getHeaderNames():获取所有的请求头名称3. 获取请求体(正文)数据:* 请求体:只有POST请求方式,才有请求体,在请求体(正文)中封装了POST请求的请求参数* 步骤:1. 获取流对象*  BufferedReader getReader():获取字符输入流,只能操作字符数据*  ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据2. 再从流对象中拿数据
    2. 其他功能:1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数1. String getParameter(String name):根据参数名称获取参数值    username=zs&password=1232. String[] getParameterValues(String name):根据参数名称获取参数值的数组  hobby=xx&hobby=game3. Enumeration<String> getParameterNames():获取所有请求的参数名称4. Map<String,String[]> getParameterMap():获取所有参数的map集合* 中文乱码问题:* get方式:tomcat 8 已经将get方式乱码问题解决了* Tomcat 8以前:⽅式1: //针对于get提交时中⽂乱码String s=new String(请求参数.getBytes("ISO-8859-1"),"UTF-8");示例: String s=new String(request.getParameter("key").getBytes("ISO-8859-1"),"GBK");⽅式2:修改tomcat中配置⽂件://使⽤于get提交在Tomcat⽬录结构\conf\server.xml中设置字符集  URLEncoding<Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />* post方式:会乱码* 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");2. 请求转发:一种在服务器内部的资源跳转方式1. 步骤:1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response) 2. 特点:1. 浏览器地址栏路径不发生变化2. 只能转发到当前服务器内部资源中。3. 转发是一次请求,可以使用request对象来共享数据3. 共享数据:* 域对象:一个有作用范围的对象,可以在范围内共享数据* request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据* 方法:1. void setAttribute(String name,Object obj):存储数据2. Object getAttitude(String name):通过键获取值3. void removeAttribute(String name):通过键移除键值对4. 获取ServletContext:* ServletContext getServletContext()
    
  • GET和POST的区别

    1、GET请求:请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数⽤&连接。URL的编码格式采⽤的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。POST请求:请求的数据放在请求消息(报文)的请求体(正文)中。因此,GET请求的数据会暴露在地址栏中,⽽POST请求则不会。
    2、传输数据的大小在HTTP规范中,没有对URL的⻓度和传输的数据⼤⼩进⾏限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的⻓度有限制。因此,在使⽤GET请求时,传输数据会受到URL⻓度的限制。对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据⼤⼩进⾏限制,Apache、IIS都有各⾃的配置。
    3、安全性POST的安全性比GET的相对较⾼。
    

四、Response

  • 功能: 设置响应消息

    1. 设置响应行1. 格式:HTTP/1.1 200 ok2. 设置状态码:setStatus(int sc)
    2. 设置响应头:setHeader(String name, String value) 添加响应头:void addHeader(String name, String value)     //两者作用一致
    3. 设置响应体:* 使用步骤:1. 获取输出流* 字符输出流:PrintWriter getWriter()* 字节输出流:ServletOutputStream getOutputStream()2. 使用输出流,将数据输出到客户端浏览器
    
  • 案例

    1. 完成重定向* 重定向:资源跳转的方式* 代码实现://1. 设置状态码为302response.setStatus(302);//2.设置响应头locationresponse.setHeader("location","/day15/responseDemo2");//简单的重定向方法response.sendRedirect("/day15/responseDemo2");* forward 和  redirect 区别* 重定向的特点:redirect1. 地址栏发生变化2. 重定向可以访问其他站点(服务器)的资源3. 重定向是两次请求。不能使用request对象来共享数据* 转发的特点:forward1. 转发地址栏路径不变2. 转发只能访问当前服务器下的资源3. 转发是一次请求,可以使用request对象来共享数据2. 服务器输出字符数据到浏览器* 步骤:1. 获取字符输出流2. 输出数据* 注意:* 乱码问题:1. PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-12. 设置该流的默认编码     response.setHeader("content-type","text/htm;charset=utf-8")告诉浏览器响应体所使用的编码//简单的形式,设置编码,是在获取流之前设置response.setContentType("text/html;charset=utf-8");3. 服务器输出字节数据到浏览器* 步骤:1. 获取字节输出流  ServletOutputStream getOutputStream()2. 输出数据
    
  • 路径写法

    1. 路径分类1. 相对路径:通过相对路径不可以确定唯一资源* 如:./index.html    或者 servletDemo1* 不以/开头、以.开头路径* 规则:找到当前资源和目标资源之间的相对位置关系* ./:当前目录* ../:后退一级目录2. 绝对路径:通过绝对路径可以确定唯一资源* 如:http://localhost/day15/responseDemo2       /day15/responseDemo2* 以/开头的路径* 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出* 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)* 建议虚拟目录动态获取:request.getContextPath()*如 <a> , <form> 标签重定向到某个页面* 给服务器使用:不需要加虚拟目录,使用相对路径即可* 转发路径
    

五、ServletContext

  1. 概念:ServletContext是javax.servlet包内定义的接口,Web容器会为每个Web程序构造一个实现该接口的对象实例,代表整个web应用,Servlet可以和web容器(服务器)进行交互
  2. 获取:
    1. 通过request对象获取
      request.getServletContext();
    2. 通过HttpServlet获取
      this.getServletContext();
  3. 功能:
    1. 获取MIME类型:

      • MIME类型:在互联网通信过程中定义的一种文件数据类型

        • 格式: 大类型/小类型 text/html image/jpeg
      • 获取:String getMimeType(String file)

    2. 域对象:共享数据
      1. void setAttribute(String name,Object value)

      2. Object getAttribute(String name)

      3. void removeAttribute(String name)

        // ServletContext对象范围:所有用户所有请求的数据

    3. 获取文件的真实(服务器)路径
      1. 方法:String getRealPath(String path)
        String b = context.getRealPath("/b.txt");//web目录下资源访问
        System.out.println(b);

        String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
        System.out.println(c );

        String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
        System.out.println(a);

六、ServletConfig(了解)

  • 概述

    ServletConfig是用来获得Servlet相关的配置的对象

  • 获取

    通过当前Servlet实例来获取
    ServletConfig config = this.getServletConfig();

  • 功能
    1. 获取ServletContext对象
      * ServletContext getServletContext();
    2. 获取当前Servlet的初始化参数
      * String getInitParameter(String name)
    3. 获取当前Servlet的所有初始化参数的名称
      * Enumeration getInitParameterNames()
    4. 获取当前Servlet实例的名称
      * String getServletName()
  • Servlet初始化参数
  1. 针对某个Servlet的初始化参数

    实现⽅式:
    (1) web.xml中先定义初始化参数<servlet><servlet-name></servlet-name><servlet-class></servlet-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></servlet>
    (2) 注解方式实现 initParams@WebServlet(urlPatterns = {"/test"},initParams ={@WebInitParam(name = "code",value = "utf-8")         })public class TestServlet extends HttpServlet {}*获取:
    String encode = this.getServletConfig().getInitParameter("encoding");
    

    2.对于当前web程序中所有的Servlet都有效的初始化参数

    (1)定义<context-param><param-name>forAll</param-name><param-value>utf-8</param-value></context-param>
    (2)获取
    this.getServletConfig().getServletContext().getInitParameter("forAll");
    

七、Cookie和Session

1.会话技术

  1. 会话:会话跟踪是Web程序中常⽤的技术,⽤来跟踪⽤户的整个会话。保持对⽤户会话期间的数据管理。常⽤的会话跟踪技术是Cookie与Session。一次会话中包含多次请求和响应。

    一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

  2. 功能:在一次会话的范围内的多次请求间,共享数据
  3. 方式:
    1. 客户端会话技术:Cookie
    2. 服务器端会话技术:Session

2.Cookie

  • 概念
    Cookie是客户端(⼀般指浏览器)请求服务器后,服务器发给客户端的⼀个辨认标识,保存在客户端,当客户端再次向服务器发送请求时,会携带着这个辨认标识,服务器就可以通过这个标识来识别客户端的身份或状态等。

  • Cookie的设置和获取

    • 使用步骤:
      1. 创建Cookie对象,绑定数据
      * new Cookie(String name, String value)
      2. 发送Cookie对象
      * response.addCookie(Cookie cookie)
      3. 获取Cookie,拿到数据
      * Cookie[] request.getCookies()
      *
      * 示例:
      * Cookie[] cs = request.getCookies();
      * // 通过遍历获取各个cookie的值
      for (Cookie c : cs) {
      String name = c.getName(); //获取cookie的名称
      String value = c.getValue();//获取cookie的值
      }
  • 实现原理

  • 基于响应头set-cookie和请求头cookie实现。
  1. 客户端请求服务器中发送cookie的Servlet,服务器设置set-cookie: msg = hello头发送到客户端浏览器。
  2. 浏览器将msg = hello保存到本地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可以共享。
  5. Cookie的特点和作用
    * 特点
    1. cookie存储数据在客户端浏览器
    2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制,不同浏览器对于cookie的数量限制不同。
    * 作用:
    1. cookie一般用于存出少量的不太敏感的数据
    2. 在不登录的情况下,完成服务器对客户端的身份识别

3.Session

  1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession

  2. 快速入门:

    1. 获取HttpSession对象:
      HttpSession session = request.getSession();
    2. 使用HttpSession对象:
      Object getAttribute(String name)
      void setAttribute(String name, Object value)
      void removeAttribute(String name)
  3. 原理

    • Session的实现是依赖于Cookie的。
    • 第一次获取Session,没有Cookie,服务器会在内存中创建一个新的Session对象,假设其对应的Id属性值为 ID = 742938a4289。
    • 服务器会自动设置响应头set-cookie:JSESSIONID= 742938a4289响应消息给浏览器。
    • 浏览器解析set-cookie响应头,将JSESSIONID=742938a4289存入Cookie请求头。
    • 后续服务器再次创建Session对象时会根据请求头Cookie中的JSESSIONID先在内存中寻找对应的session实例,然后返回其引用。
  4. 细节:
    ​ 1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
    ​ * 默认情况下。不是。
    ​ * 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让 cookie持久化保存。
    ​ Cookie c = new Cookie(“JSESSIONID”,session.getId());
    ​ c.setMaxAge(60*60); //单位:秒
    ​ response.addCookie(c );

     2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?* 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作* session的钝化:* 在服务器正常关闭之前,将session对象序列化到硬盘上* session的活化:* 在服务器启动后,将session文件转化为内存中的session对象即可。
    
  5. session什么时候被销毁?
    1. 本地服务器正常关闭后不会被销毁,idea上配置的tomcat服务器关闭后会被销毁
    2. session对象调用invalidate() 。
    3. session默认失效时间 30分钟
    * Session的超时时间为maxInactiveInterval属性,可以通过对应的 getMaxInactiveInterval()获取,通过 setMaxInactiveInterval(longinterval)修改
    * 还可以在config目录下的web.xml中选择性配置修改

       <session-config><session-timeout>30</session-timeout></session-config>
    

    4.浏览器中含有JSESSIONID的cookie被销毁时,服务器会重新创建一个新的session对象,原有的session对象会在失效时间过后被销毁。

  6. session的特点

    1. session用于存储一次会话的多次请求的数据,存在服务器端。
    2. 为了获得更⾼的存取速度,服务器⼀般把Session放在内存⾥。
    3. session可以存储任意类型,任意大小的数据

    什么时候创建Session?
    1.Session在⽤户第⼀次访问page指令中的session属性值不为false的JSP页面时被创建。
    2.若servelt是第浏览器客户端访问的第一个WEB应用的资源,则只有调用了request.getSession()或request.getSession(true)才会创建session对象。

    其中request.getSession(boolean),
    boolean为false时,若没有和当前JSP页面关联的session对象则返回null,若有,则返回true。
    Boolean为true时,一定返回一个session对象,若没有和当前JSP页面关联的session对象,则服务器创建一个新的session对象,若有,直接返回。
    request.getSession()等同于request.getSession(true)。

  • session与Cookie的区别:
    1. session存储数据在服务器端,Cookie在客户端。
    2. session没有数据大小限制,Cookie有,一般为4KB。
    3. session数据安全,Cookie相对于不安全。
    4. Session是由应⽤服务器维持的⼀个服务器端的存储空间,⽤户在连接服务器时,会由服务器⽣成⼀个唯⼀的SessionID,⽤该SessionID 为标识符来存取服务器端的Session存储空间。⽽SessionID这⼀数据则是保存到客户端,⽤Cookie保存的,⽤户提交⻚⾯时,会将这⼀SessionID提交到服务器端,来存取Session数据。这⼀过程,是不⽤开发⼈员⼲预的。所以⼀旦客户端禁⽤Cookie,那么Session也会失效。

八、JSP

1. 概念:
* Java Server Pages: java服务器端页面
* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
* 用于简化书写!!!

2. 原理
* JSP本质上就是一个Servlet,当浏览器访问http://localhost:8080/day9_1/index.jsp。服务器发现后缀为.jsp,它会根据路径找到index.jsp⽂件,会将index.jsp翻译成index_jsp.java⽂件,对这个java⽂件进⾏编译,产⽣⼀个index_jsp.class⽂件,将class⽂件加载运⾏。将JSP翻译成java⽂件,它是将JSP中的所有的HTML代码通过流进⾏输出,也就是说最终翻译成class,被虚拟机加载,它本质是servlet,它就会往回响应,响应回去就是把JSP中的HTML代码以流的⽅式写回浏览器。所以在JSP中展示出了HTML代码。

3. JSP指令

  • 作用:用于配置JSP页面,导入资源文件

    • 格式:
      <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %>
  • 分类:
    1. page :

    • contentType: 配置JSP页面的 contentType属性:等同于response.setContentType()
    1. 设置响应体的mime类型以及字符集
    2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
    • import:导包
    • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
    • isErrorPage:标识当前也是是否是错误页面。
      • true:是,可以使用内置对象exception <% String message = exception.getMessage(); %>
      • false:否。默认值。不可以使用内置对象exception

page 指令相关属性:

  1. include : JSP可以通过include指令来包含其他⽂件。被包含的⽂件可以是JSP⽂件、HTML⽂件或⽂本⽂件。包含的⽂件就好像是该JSP⽂件的⼀部分,会被同时编译执⾏。
    <%@ include file=“⽂件相对 url 地址” %>

  2. taglib : 导入资源(引入jsp标签库)

    • <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

      • prefix:前缀,自定义的
  3. 注释:

 1. html注释:<!-- -->:只能注释html代码片段2. jsp注释:推荐使用<%-- --%>:可以注释所有

4. JSP的脚本: JSP定义Java代码的方式
1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。

5. JSP的内置对象:
* 在jsp页面中不需要获取和创建,可以直接使用的对象
* jsp一共有9个内置对象。

变量名 真实类型 作用
pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象
request HttpServletRequest 一次请求访问的多个资源(转发)间共享数据。
session HttpSession 一次会话的多个请求间共享数据
application ServletContext 所有用户间共享数据
response HttpServletResponse response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。只在JSP⻚⾯内有效。
page Object 当前页面(Servlet)的对象,类似于this
out JspWriter 输出对象,数据输出到页面上
config ServletConfig 主要作⽤是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() ⽅法可以获取⼀个config对象。当⼀个Servlet 初始化时,容器把某些信息通过config对象传递给这个Servlet。 开发者可以在web.xml ⽂件中为应⽤程序环境中的Servlet程序和JSP⻚⾯提供初始化参数。
exception Throwable exception 对象的作⽤是显示异常信息,只有在包含 isErrorPage=“true” 的⻚⾯中才可以被使⽤,通常用于打印错误信息输出到日志文件,exception.getMessage()
  • out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
    * response.getWriter()和out.write()的区别:
    * 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
    * response.getWriter()数据输出永远在out.write()之前。

九、 EL &JSTL

1. EL表达式

  1. 概念:Expression Language 表达式语言
  2. 作用:替换和简化jsp页面中java代码的编写
  3. 语法:${表达式}
  4. 注意:
    • jsp默认支持el表达式的。如果要忽略el表达式

      1. 设置jsp中page指令中:isELIgnored=“true” 忽略当前jsp页面中所有的el表达式
      2. ${表达式} :忽略当前这个el表达式
  5. 使用:
    1. 运算:

      • 运算符:

        1. 算数运算符: + - * /(div) %(mod)
          ${30 + 40}
          ${20 div 5}
        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个隐式对象
      * pageScope
      * requestScope
      * sessionScope
      * applicationScope
      * pageContext:
      * 获取jsp其他八个内置对象
      * ${pageContext.request.contextPath}:动态获取虚拟目录

2. JSTL

(1) 什么是JSTL
JSP标准标签库(JSTL)是⼀个JSP标签集合,它封装了JSP应⽤的通⽤核⼼功能。
JSTL⽀持通⽤的、结构化的任务,⽐如迭代,条件判断,XML⽂档操作,国际化标签,SQL标签。 除了这些,它还提供了⼀个框架来使⽤集成JSTL的⾃定义标签。
根据JSTL标签所提供的功能,可以将其分为5个类别。核⼼标签 格式化标签 sql标签 xml标签 jstl函数(后⾯详细解释)
(2) JSTL的作⽤和语法格式
作⽤:用于简化和替换jsp页面上的java代码
语法格式:

  1. 下载 jakarta-taglibs-standard-1.1.2.zip 包并解压,将 jakarta-taglibs-standard-1.1.2/lib/ 下的两
    个 jar ⽂件:standard.jar 和 jstl.jar ⽂件拷⻉到 /WEB-INF/lib/ 下。

  2. 在JSP⻚⾯中引⼊<%@ taglib prefix=”⻚⾯使⽤的名称” uri=”功能范围的路径”%>

  3. 常用的JSTL标签

    • 核⼼标签
      核⼼标签是最常⽤的 JSTL标签。引⽤核⼼标签库的语法如下:
      <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

      1. if:相当于java代码的if语句

        1. 属性:

          • test 必须属性,接受boolean表达式

            • 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
            • 一般情况下,test属性值会结合el表达式一起使用
        2. 注意:
          • c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
      2. choose:相当于java代码的switch语句

        1. 使用choose标签声明 相当于switch声明
        2. 使用when标签做判断 相当于case
        3. 使用otherwise标签做其他情况的声明 相当于default
      3. foreach:相当于java代码的for语句

代码案例:

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html>
<head><title>if标签</title>
</head>
<body><%--c:if标签1. 属性:* test 必须属性,接受boolean表达式* 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容* 一般情况下,test属性值会结合el表达式一起使用2. 注意:c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签--%><c:if test="true"><h1>我是真...</h1></c:if><br><%//判断request域中的一个list集合是否为空,如果不为null则显示遍历集合List list = new ArrayList();list.add("aaaa");request.setAttribute("list",list);request.setAttribute("number",4);%><c:if test="${not empty list}">遍历集合...</c:if><br><c:if test="${number % 2 != 0}">${number}为奇数</c:if><c:if test="${number % 2 == 0}">${number}为偶数</c:if></body>
</html>


代码案例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html>
<head><title>choose标签</title>
</head>
<body><%--完成数字编号对应星期几案例1.域中存储一数字2.使用choose标签取出数字         相当于switch声明3.使用when标签做数字判断         相当于case4.otherwise标签做其他情况的声明  相当于default--%><%request.setAttribute("number",51);%><c:choose><c:when test="${number == 1}">星期一</c:when><c:when test="${number == 2}">星期二</c:when><c:when test="${number == 3}">星期三</c:when><c:when test="${number == 4}">星期四</c:when><c:when test="${number == 5}">星期五</c:when><c:when test="${number == 6}">星期六</c:when><c:when test="${number == 7}">星期天</c:when><c:otherwise>数字输入有误</c:otherwise></c:choose></body>
</html>


代码案例:

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html>
<head><title>foreach标签</title>
</head>
<body><%--foreach:相当于java代码的for语句1. 完成重复的操作for(int i = 0; i < 10; i ++){}* 属性:begin:开始值end:结束值var:临时变量step:步长varStatus:循环状态对象index:容器中元素的索引,从0开始count:循环次数,从1开始2. 遍历容器List<User> list;for(User user : list){}* 属性:items:容器对象var:容器中元素的临时变量varStatus:循环状态对象index:容器中元素的索引,从0开始count:循环次数,从1开始--%><c:forEach begin="1" end="10" var="i" step="2" varStatus="s">${i} <h3>${s.index}<h3> <h4> ${s.count} </h4><br></c:forEach><hr><%List list = new ArrayList();list.add("aaa");list.add("bbb");list.add("ccc");request.setAttribute("list",list);%><c:forEach items="${list}" var="str" varStatus="s">${s.index} ${s.count} ${str}<br></c:forEach></body>
</html>
  1. 格式化标签
    1、fmt:formatDate 作⽤:将⽇期类型格式化为指定模式的字符串
    属性
    value:将要被格式化的数据
    pattern:格式化的模式,与SimpleDateFormat的参数设置⼀样
    var:格式化后的字符串所要存放的变量,若不指定var,则会将格式化的结果直接显示在⻚⾯
    scope:变量存放的域属性空间,默认page
    type:其取值为date、time、both,表示给出的value是⽇期、时间、还是两者都包含,默认是date

代码案例:


<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head><title>Title</title>
</head>
<body><%pageContext.setAttribute("mytime",new Date());%>date=<fmt:formatDate value="${mytime}" pattern="yyyy-MM-dd"></fmt:formatDate>
</body>
</html>

十、Filter

  1. 概念:

    • 生活中的过滤器:净水器,空气净化器,土匪、
    • web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
    • 过滤器的作用:
      • 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤…
  2. 快速入门:

    1. 步骤:

      1. 定义一个类,实现接口Filter
      2. 复写方法
      3. 配置拦截路径
        1. web.xml
        2. 注解
    2. 代码:
     @WebFilter("/*")//访问所有资源之前,都会执行该过滤器public class FilterDemo1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {    }       @Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("filterDemo1被执行了....");//放行filterChain.doFilter(servletRequest,servletResponse);}@Overridepublic void destroy() {}}
    
  3. 过滤器细节:

    1. web.xml配置

      demo1
      cn.itcast.web.filter.FilterDemo1

      demo1

      /*

    2. 过滤器执行流程

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

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

      • 拦截路径配置:

        1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
        2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
        3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
        4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
      • 拦截方式配置:资源被访问的方式
        • 注解配置:

          • 设置dispatcherTypes属性

            1. REQUEST:默认值。浏览器直接请求资源
            2. FORWARD:转发访问资源
            3. INCLUDE:包含访问资源
            4. ERROR:错误跳转资源
            5. ASYNC:异步访问资源

        //浏览器直接请求index.jsp资源时,该过滤器会被执行
        //@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
        //只有转发访问index.jsp时,该过滤器才会被执行
        //@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
        //浏览器直接请求index.jsp或者转发访问index.jsp。该过滤器才会被执行
        //@WebFilter(value="/*",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})

        1. web.xml配置

          设置<dispatcher></dispatcher>标签即可
          如: <filter-mapping><filter-name>demo1</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher></filter-mapping>
          
    5. 过滤器链(配置多个过滤器)

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

        1. 过滤器1
        2. 过滤器2
        3. 资源执行
        4. 过滤器2
        5. 过滤器1
      • 过滤器先后顺序问题:

        1. 注解配置:按照类名的字符串比较规则比较,值小的先执行

          • 如: AFilter 和 BFilter,AFilter就先执行了。
        2. web.xml配置:
          <filter-mapping>谁定义在上边,谁先执行
          
  • 使⽤场景
    1.如何防⽌⽤户未登录就执⾏后续操作
    String name=(String)session.getAttribute(“key”);
    if(name==null){
    //跳转到登录⻚⾯
    }
    2.设置编码⽅式–统⼀设置编码
    3.加密解密(密码的加密和解密)
    4.⾮法⽂字筛选
    5.下载资源的限制
    过滤器的特点:在servlet之前和之后都会被执⾏

十一、Listener

1.什么是监听器
监听器就是监听某个域对象的的状态变化的组件
监听器的相关概念:
事件源:被监听的对象(三个域对象 request、session、servletContext)
监听器:监听事件源对象事件源对象的状态的变化都会触发监听器
注册监听器:将监听器与事件源、事件进⾏绑定。事件源上发生某个事件后,执行监听器代码
响应⾏为:监听器监听到事件源的状态变化时所涉及的功能代码(程序员编写代码)

  • ServletContextListener:监听ServletContext对象的创建和销毁

    • 方法:

      • void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
      • void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
    • 步骤:
      1. 定义一个类,实现ServletContextListener接口
      2. 复写方法
      3. 配置
        1. web.xml<listener><!-- 监听器所在的路径 --><listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class></listener>2. 注解:* @WebListener
        

2.监听器分类

3.监听三⼤域对象的创建与销毁的监听器

  • ServletContextListener
    监听ServletContext域的创建与销毁的监听器
    Servlet域的⽣命周期
    何时创建:服务器启动创建
    何时销毁:服务器关闭销毁
    ServletContextListener监听器的主要作⽤
    初始化的⼯作:初始化对象、初始化数据(加载数据库驱动、连接池的初始化)
    加载⼀些初始化的配置⽂件(spring的配置⽂件)
    任务调度(定时器—Timer/TimerTask)
  • HttpSessionListener
    监听Httpsession域的创建和销毁的监听器
    HttpSession对象的⽣命周期
    何时创建:第⼀次调⽤request.getSession时创建
    何时销毁:服务器关闭销毁、session过期(默认30分钟,修改默认的30分钟是在
    Tomcat的web.xml,修改当前项⽬的过期时间是在⾃⼰项⽬的web.xml中)、⼿动销毁
    HttpSessionListener监听器的主要作⽤:
    由于每次访问⽹站都会默认创建session对象(jsp⻚⾯中page指令中的session属性默认为
    true,即被访问时创建session),可以⽤于计数⽹站访问过的⼈
  • ServletRequestListener
    监听ServletRequest域创建与销毁的监听器
    ServletRequest的⽣命周期
    创建:每⼀次请求都会创建request
    销毁:请求结束
    ⽤法同上,⽤处不是很⼤,此处省略。

十二、 MVC和三层架构

1.MVC设计模式

  1. jsp演变历史

    1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
    2. 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难于维护,难于分工协作
    3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性

  1. MVC:

    1. M:Model,模型。JavaBean

      • 完成具体的业务操作,如:查询数据库,封装对象
    2. V:View,视图。JSP
      • 展示数据
    3. C:Controller,控制器。Servlet
      • 获取用户的输入
      • 调用模型
      • 将数据交给视图进行展示
  • 优缺点:

      1. 优点:1. 耦合性低,方便维护,可以利于分工协作2. 重用性高2. 缺点:1. 使得项目架构变得复杂,对开发人员要求高
    

JavaBeans :是Java中⼀种特殊的类(换⾔之:JavaBean就是⼀个Java类).
⼀个Java类 ,满⾜以下要求,则可称为⼀个JavaBean
a. public修饰的类,提供public ⽆参构造⽅法
b. 所有属性 都是private
C. 提供getter和setter⽅法
从使⽤层⾯来看,JavaBean分为2⼤类:
a. 封装业务逻辑的JavaBean(eg:LoginDao.java 封装了登录逻辑)
b. 封装数据的JavaBean(实体类:eg:Student.java Vadio.java 。往往对应于数据库中的⼀张
表,即数据库中有个Student表,项⽬中就有个Student.java类)通常:表名=类名,列名=属性名
JavaBean是⼀个可以重复使⽤的组件,通过编写⼀个组件来实现某种通⽤功能,“⼀次编写、任何地⽅执⾏、任何地⽅重⽤”。

2.三层架构
三层架构 通常意义上的三层架构就是将整个业务应⽤划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。区分层次的⽬的即为了“⾼内聚,低耦合”的思想。
1、表现层(UI):通俗讲就是展现给⽤户的界⾯,即⽤户在使⽤⼀个系统的时候他的所⻅所得。
jsp/html
2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
servlet,service
3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、更新、查找
等。dao
表现层实现的代表作品是Struts,springmvc框架,
业务层实现的代表作品是Spring,
持久层实现的代表作品是Hibernate,mybatis。
层就相当于⼀个⿊盒⼦,我们不⽤知道它内部怎么实现,只需要知道如何去调⽤它就⾏了。每层只与上下相邻的两层打交道。当⼀层内部由于技术变迁发⽣变化时,只要接⼝不变,其他层不⽤做任何改变。分层之后灵活性提⾼,也便于团队分⼯开发。

3.三层架构和MVC的区别与联系

MVC可以是三层中的⼀个表现层框架,属于表现层。三层和mvc可以共存。
三层是基于业务逻辑来分的,⽽MVC是基于⻚⾯来分的。
MVC主要⽤于表现层,3层主要⽤于体系架构,3层⼀般是表现层、中间层、数据层,其中表现层⼜可以分成M、V、C,(Model View Controller)模型-视图-控制器
MVC是表现模式(Presentation Pattern)
三层架构是典型的架构模式(Architecture Pattern)
三层架构的分层模式是典型的上下关系,上层依赖于下层。但MVC作为表现模式是不存在上下关系的,⽽是相互协作关系。即使将MVC当作架构模式,也不是分层模式。MVC和三层架构基本没有可⽐性,是应⽤于不同领域的技术。

十三、Ajax

1. 概念: ASynchronous JavaScript And XML 异步的JavaScript 和 XML
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
功能:提升用户的体验

异步和同步:客户端和服务器端相互通信的基础上
* 同步: 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
* 异步:客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。
* 浏览器的普通交互⽅式(同步)

2.工作原理:
1.客户端浏览器发送JS请求Ajax引擎。
2.Ajax将JS请求转换成HTTP请求。
3.服务器对接收到的数据进行处理。
4.服务器返回XML、JSON或文本文档类型的数据给Ajax引擎。
5.AJax引擎接收服务器返回的数据进行渲染。

3. 实现方式:
(1)原生的JS实现方式(了解)

AJAX 的核⼼是 XMLHttpRequest 对象。
不同的浏览器创建 XMLHttpRequest 对象的⽅法是有差异的。
IE 6及以下浏览器使⽤ ActiveXObject,⽽其他的浏览器使⽤名为 XMLHttpRequest 的 JavaScript 内建对象

     //1.创建核心对象var xmlhttp;if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=new XMLHttpRequest();}else{// code for IE6, IE5xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}//2. 建立连接/*参数:1. 请求方式:GET、POST* get方式,请求参数在URL后边拼接。send方法为空参* post方式,请求参数在send方法中定义2. 请求的URL:3. 同步或异步请求:true(异步)或 false(同步)*/xmlhttp.open("GET","ajaxServlet?username=tom",true);//3.发送请求xmlhttp.send();//4.接受并处理来自服务器的响应结果//获取方式 :xmlhttp.responseText//什么时候获取?当服务器响应成功后再获取//当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。xmlhttp.onreadystatechange=function(){//判断readyState就绪状态是否为4,判断status响应状态码是否为200if (xmlhttp.readyState==4 && xmlhttp.status==200){//获取服务器的响应结果var responseText = xmlhttp.responseText;alert(responseText);}}
  • XMLHttpRequest常⽤属性

    • onreadystatechange 属性
      onreadystatechange 属性存有处理服务器响应的函数。
    xmlHttp.onreadystatechange = function() { }
    
    • readyState 属性
      readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会
      被执⾏。
      readyState 属性可能的值:
    • responseText 属性
      可以通过 responseText 属性来取回由服务器返回的数据。

AJAX状态码说明
1xx:请求收到,继续处理
2xx:操作成功收到,分析、接受
3xx:完成此请求必须进⼀步处理
4xx:请求包含⼀个错误语法或不能完成
5xx:服务器执⾏⼀个 完全有效请求 失败
再具体就如下:
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新⽂件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,⽤户代理必须复位当前已经浏览过的⽂件
206——服务器已经完成了部分⽤户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问⽅式
304——客户端已经执⾏了GET,但⽂件未变化
305——请求的资源必须从服务器指定的地址得到
306——前⼀版本HTTP中使⽤的代码,现⾏版本中不再使⽤
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现⽂件、查询或URl
405——⽤户在Request-Line字段定义的⽅法不允许
406——根据⽤户发送的Accept拖,请求资源不可访问
407——类似401,⽤户必须⾸先在代理服务器上得到授权
408——客户端没有在⽤户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且⽆进⼀步的参考地址
411——服务器拒绝⽤户定义的Content-Length属性请求
412——⼀个或多个请求头字段在当前请求中错误
413——请求的资源⼤于服务器允许的⼤⼩
414——请求的资源URL⻓于服务器允许的⻓度
415——请求资源不⽀持请求项⽬格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含IfRange请求头字段
417——服务器不满⾜请求Expect头字段指定的期望值,如果是代理服务器,可能是下⼀级服务器不能
满⾜请求
500——服务器产⽣内部错误
501——服务器不⽀持请求的函数
502——服务器暂时不可⽤,有时是为了防⽌发⽣系统过载
503——服务器过载或暂停维修
504——关⼝过载,服务器使⽤另⼀个关⼝或服务来响应⽤户,等待时间设定值较⻓
505——服务器不⽀持或拒绝⽀请求头中指定的HTTP版本

(2).JQeury实现方式

     1. $.ajax()* 语法:$.ajax({键值对});//使用$.ajax()发送异步请求$.ajax({url:"ajaxServlet1111" , // 请求路径type:"POST" , //请求方式//data: "username=jack&age=23",//请求参数data:{"username":"jack","age":23},success:function (data) {alert(data);},//响应成功后的回调函数error:function () {alert("出错啦...")},//表示如果请求响应出现错误,会执行的回调函数dataType:"text"//设置接受到的响应数据的格式(预期服务器返回的数据类型)});2. $.get():发送get请求* 语法:$.get(url, [data], [callback], [type])* 参数:* url:请求路径* data:请求参数* callback:回调函数* type:响应结果的类型(预期服务器返回的数据类型)3. $.post():发送post请求* 语法:$.post(url, [data], [callback], [type])* 参数:* url:请求路径* data:请求参数* callback:回调函数* type:响应结果的类型

十四、JSON

1. 概念: JavaScript Object Notation (JavaScript对象表示法)
JSON (JavaScript Object Notation) 是⼀种轻量级的数据交换格式。 易于⼈阅读和编写。同时也易于机器解析和⽣成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition -December 1999的⼀个⼦集。 JSON采⽤完全独⽴于语⾔的⽂本格式,但是也使⽤了类似于C语⾔家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语⾔。

* json现在多用于存储和交换文本信息的语法
* 进行数据的传输
* JSON 比 XML 更小、更快,更易解析。

1.jackson

  1. 语法:

    1. 基本规则

      • 数据在名称/值对中:json数据是由键值对构成的

        • 键用引号(单双都行)引起来,也可以不使用引号
        • 值得取值类型:
          1. 数字(整数或浮点数)
          2. 字符串(在双引号中)
          3. 逻辑值(true 或 false)
          4. 数组(在方括号中) {“persons”:[{},{}]}
          5. 对象(在花括号中) {“address”:{“province”:“陕西”…}}
          6. null
      • 数据由逗号分隔:多个键值对由逗号分隔
      • 花括号保存对象:使用{}定义json 格式
      • 方括号保存数组:[]
    2. 获取数据:
      1. json对象.键名

      2. json对象[“键名”]

      3. 数组对象[索引]

      4. 遍历
        //1.定义基本格式

         var person = {"name": "张三", age: 23, 'gender': true};var ps = [{"name": "张三", "age": 23, "gender": true},{"name": "李四", "age": 24, "gender": true},{"name": "王五", "age": 25, "gender": false}];//获取person对象中所有的键和值//for in 循环
        /* for(var key in person){//这样的方式获取不行。因为相当于  person."name"//alert(key + ":" + person.key);alert(key+":"+person[key]);}*///获取ps中的所有值for (var i = 0; i < ps.length; i++) {var p = ps[i];for(var key in p){alert(key+":"+p[key]);}}
        
  2. JSON数据和Java对象的相互转换

    • JSON解析器:

      • 常见的解析器:Jsonlib,Gson,fastjson,jackson
    1. JSON转为Java对象(jackson)

      1. 导入jackson的相关jar包

      2. 创建Jackson核心对象 ObjectMapper

      3. 调用ObjectMapper的相关方法进行转换

        1. readValue(json字符串数据,Class)
    2. Java对象转换JSON
      1. 使用步骤:

        1. 导入jackson的相关jar包
        2. 创建Jackson核心对象 ObjectMapper
        3. 调用ObjectMapper的相关方法进行转换
          1. 转换方法:

            • writeValue(参数1,obj):
              参数1:
              File:将obj对象转换为JSON字符串,并保存到指定的文件中
              Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
              OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
            • writeValueAsString(obj):将对象转为json字符串
          2. 注解:

            1. @JsonIgnore:被此注解标注的属性将不再被转为JSON格式
            2. @JsonFormat:属性值的格式化
              • @JsonFormat(pattern = “yyyy-MM-dd”) 如日期对象格式化,pattern用法与SimpleDateFormat类似
          3. 复杂java对象转换

            1. List:数组 存储的为对象则为对象数组 [{“key”:“value”},{“key”:“value”},{“key”:“value”}]
            2. Map:与对象格式一致

案例:
Person类:

public class Person {private String name;private int age ;private String gender;//@JsonIgnore // 忽略该属性@JsonFormat(pattern = "yyyy-MM-dd")private Date birthday;public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
}

测试类

public class JacksonTest {//Java对象转为JSON字符串@Testpublic void test1() throws Exception {//1.创建Person对象Person p  = new Person();p.setName("张三");p.setAge(23);p.setGender("男");//2.创建Jackson的核心对象  ObjectMapperObjectMapper mapper = new ObjectMapper();//3.转换/*转换方法:writeValue(参数1,obj):参数1:File:将obj对象转换为JSON字符串,并保存到指定的文件中Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中writeValueAsString(obj):将对象转为json字符串*/String json = mapper.writeValueAsString(p);//{"name":"张三","age":23,"gender":"男"}//System.out.println(json);//{"name":"张三","age":23,"gender":"男"}//writeValue,将数据写到d://a.txt文件中//mapper.writeValue(new File("d://a.txt"),p);//writeValue.将数据关联到Writer中mapper.writeValue(new FileWriter("d://b.txt"),p);}@Testpublic void test2() throws Exception {//1.创建Person对象Person p = new Person();p.setName("张三");p.setAge(23);p.setGender("男");p.setBirthday(new Date());//2.转换  Object -> JSONObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(p);System.out.println(json);//{"name":"张三","age":23,"gender":"男","birthday":1530958029263}//{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"}}// List集合 - > JSON    Set集合类似@Testpublic void test3() throws Exception {//1.创建Person对象Person p = new Person();p.setName("张三");p.setAge(23);p.setGender("男");p.setBirthday(new Date());Person p1 = new Person();p1.setName("张三");p1.setAge(23);p1.setGender("男");p1.setBirthday(new Date());Person p2 = new Person();p2.setName("张三");p2.setAge(23);p2.setGender("男");p2.setBirthday(new Date());//创建List集合List<Person> ps = new ArrayList<Person>();ps.add(p);ps.add(p1);ps.add(p2);//2.转换ObjectMapper mapper = new ObjectMapper();//   List -> JSONString json = mapper.writeValueAsString(ps);// [{},{},{}]//[{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"},{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"},{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"}]System.out.println(json);//  JSON -> ListList<Person> list = mapper.readValue(json, new TypeReference<List<Person>>() {});  // class java.util.ArrayListfor (Person pp : list) {System.out.println(pp);}}//Map集合 -> JSON@Testpublic void test4() throws Exception {//1.创建map对象Map<String,Object> map = new HashMap<String,Object>();map.put("name","张三");map.put("age",23);map.put("gender","男");//2.转换 map -> JSONObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(map);//{"name":"张三","age":23,"gender":"男"}System.out.println(json);//{"gender":"男","name":"张三","age":23}//  JSON -> Map//方式一: //class   java.util.LinkedHashMapMap<String,Object> hm = mapper.readValue(json, Map.class);//方式二: //class    java.util.LinkedHashMap//Map<String, Object> lhm= mapper.readValue(json, new TypeReference<Map<String, Object>>() {}); Set<String> set = hm.keySet();for (String str : set) {System.out.println(str + ":" + hm.get(str));}}//演示 JSON字符串转为Java对象@Testpublic void test5() throws Exception {//1.初始化JSON字符串String json = "{\"gender\":\"男\",\"name\":\"张三\",\"age\":23}";//2.创建ObjectMapper对象ObjectMapper mapper = new ObjectMapper();//3.转换为Java对象 Person对象Person person = mapper.readValue(json, Person.class);System.out.println(person);}/*** 将数组转换成json字符串* [{"name":"张三","age":23,"gender":"男"},{"name":"李四","age":24,"gender":"女"},{"name":"王五","age":25,"gender":"男"}]* @throws Exception*/@Testpublic void test6() throws Exception {Person p1 = new Person("张三", 23, "男");Person p2 = new Person("李四", 24, "女");Person p3 = new Person("王五", 25, "男");Person[] persons = {p1, p2, p3};ObjectMapper mapper = new ObjectMapper();// Array -> JSONString json= mapper.writeValueAsString(persons);System.out.println(json);// JSON ->ArrayPerson[] persons = mapper.readValue(json, Person[].class); // [Lcn.itcast.domain.Person;@43195e57String content = "";for (Person person : persons) {content+=person + "  ";}System.out.println(content);}}

2.Jsonlib

  1. JSON转为Java对象
    1. 导入Jsonlib的相关jar包

    java对象和json之间的转换
    《1》单个对象或map集合
    java->json:

    Users user2=new Users();
    user2.setUsername(“李四”);
    user2.setPassword(“abc”);
    user2.setAge(20);
    JSONObject obj=JSONObject.fromObject(user);//obj就是json格式的

    json->java:

    String str="{‘username’:‘李四’,‘password’:‘admin’,‘age’:19}";
    JSONObject json=JSONObject.fromObject(str);
    Users user=(Users)JSONObject.toBean(json,Users.class);

《2》对象集合和json的转换
java集合->json数组:

List list=new ArrayList();
list.add(“dd”);
list.add(“aa”);
JSONArray obj=JSONArray.fromObject(list);//set也是这么转

json数组->java集合:
⽅式1:
String str2="[{‘age’:20,‘password’:‘abc’,‘username’:‘李四’},
{‘age’:10,‘password’:‘adb’,‘username’:‘张三’}]";
JSONArray json2=JSONArray.fromObject(str2);
Object[] obj=(Object[])JSONArray.toArray(json2,Users.class);
⽅式2:
String str3="[{‘age’:20,‘password’:‘abc’,‘username’:‘李四’},
{‘age’:10,‘password’:‘adb’,‘username’:‘展示⼲’}]";
JSONArray json3=JSONArray.fromObject(str3);
//默认转换成ArrayList
List list=(List) JSONArray.toCollection(json3,Users.class);

感谢您能阅读至此!!respect!!!!

那些年关于JavaWeb的点点滴滴,你想看的这里全都有噢~相关推荐

  1. c语言写贪吃蛇什么水平_学了一些C语言,也不知道自己学到什么程度,自己想写个贪吃蛇但是写不出来,想看懂下面这个程序,求解释...

    已结贴√ 问题点数:20 回复次数:3 学了一些C语言,也不知道自己学到什么程度,自己想写个贪吃蛇但是写不出来,想看懂下面这个程序,求解释 #include//基本库 #include//系统库 #i ...

  2. (转)【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!...

    原文地址:http://www.cnblogs.com/chyingp/archive/2013/06/30/front-end-tmplate-start.html 写在前面 随着前端领域的发展和社 ...

  3. matlab超出矩阵索引维度_搜你想看“头条搜索”网页版上线 搜索引擎迎来新玩家...

    作者:七声 审校:一条辉 来源:GPLP犀牛财经(ID:gplpcn) 千呼万唤始出来,8月10日,今日头条旗下"头条搜索"网页版正式上线,slogan为"搜你想看&qu ...

  4. vue骨架屏、时间选择器、轮播图。。你想要的这里全都有

    骨架屏.时间选择器.轮播图..你想要的这里全都有,没有就补.补.补 项目伊始,秉承能自己写就不用额外install的原则,提取了一些项目中时常要用到的公用组件.插件和样式,github地址:https ...

  5. 《长津湖之水门桥》定档大年初一 想看热度跻进春节档TOP3

    1月13日消息,今日,电影<长津湖之水门桥>宣布定档大年初一.截至上午,淘票票数据显示,<长津湖之水门桥>的想看热度已经跻进春节档TOP3,仅次于<奇迹·笨小孩>& ...

  6. 测试底妆的软件,你最想看的粉底液测评,我一次性测了12款!!

    正文开始前,提醒大家不要忘记我们的[为你老公/老婆打call]征集还在 进行中哦 ,每天抽2个留言幸运鹅送现金红包也在火热开展中哟~ 仙女萌好呀~这里是放假超开心哒狗砸! 十一的第三天,没想到我就勤勤 ...

  7. pdf做成翻页电子书_想看书就别用手机了,电子书选购指南

    关注求真实验室 教你成为硬核买手 一个真正的读者,或是喜爱阅读的人,内心肯定有一份对纸质书的情怀.毫无疑问,纸质书能带来最真实的质感.最纯粹的阅读体验. 但在这个知识爆炸的时代,纸质书却在逐渐消逝.生 ...

  8. 自媒体全是带节奏的标题党,不是创作者不行,而是用户们想看

    一直以来标题党们,都占据着流量池里,很大的一部分.不论是大鱼号UC的"震惊部",还是QQ看点的"青铜这样,白银这样,而王者巴拉巴拉".都充斥着满满的套路味道,就 ...

  9. 【爬虫实战】斗鱼直播(你想看的都有呀!)

    Selenium实战:斗鱼直播 前言 1. 获取数据 2. 解析数据 3. 自动翻页 4. 保存数据 5. 完整代码 6. 效果展示 前言 斗鱼直播-每个人的直播平台 闲着没事儿,看起斗鱼的游戏直播了 ...

  10. 你想看啥电子书,这里能帮你免费下载哦。给友友们推荐30+电子书下载网站或搜索引擎,以及3+电子书下载导航网站。

    你想看啥电子书,这里能帮你免费下载哦 恩......今天开始不定期为大家更新干货资源哦,绝对的干货满满,以防找不到我可以点赞或关注一下我哦.喜欢看电子书的友友这篇文章能够帮助到你哦,给友友们推荐30+ ...

最新文章

  1. 苹果布局大数据,两亿美元收购暗数据企业
  2. Java 线程池必知的8 大拒绝策略
  3. 【PAT乙级】1078 字符串压缩与解压 (20 分)
  4. HDU 5486 Difference of Clustering 图论
  5. c语言程序设计教程本科,新编C语言程序设计教程(本科)第5篇.pdf
  6. js数字比较【牢记】
  7. 一步一步使用标c编写跨平台图像处理库_让一个图像变成反向图像
  8. python3源码安装_源码安装Python3
  9. 27.yii2 商城
  10. C# 嵌入式数据库LiteDB
  11. leet code 006:ZigZag Conversion
  12. adb 连接逍遥游模拟器搭配monkey命令 抓取 logcat日志
  13. 机器学习中的度量指标:ROC曲线,AUC值,K-S曲线
  14. 猫眼电影票房爬取到MySQL中_爬虫之爬取猫眼电影专业版实时数据排行榜
  15. 登录IE时常出现闪退:Internet Explorert停止工作解决办法
  16. Selenium应用系列2
  17. 坐下来谈谈如何写好一份简历?
  18. Mycat 分片规则---不以规矩,不能成方圆
  19. 02325《计算机系统结构》自考大题:第 4 章
  20. redis如何清空当前缓存和所有缓存

热门文章

  1. 最好的免费在线UML图表工具
  2. Eplan 各版本 软件 百度网盘 永久链接
  3. dematel matlab,决策与实验室方法,DEMATEL分析方法介绍
  4. 手机整人脚本html,vbs整人代码_手机vbs整人代码_如何让别人执行vbs代码(3)
  5. html5空白站位符号,空格代码(隐形空白符号)
  6. Hive窗口函数应用:级联累加求和场景
  7. linux镜像迅雷下载,【转】红帽 Red Hat Linux相关产品iso镜像下载【迅雷快传】【百度云】【更新7.1】...
  8. 用Excel和Python编程完成线性规划问题的求解
  9. c语言中两整数相除保留小数的方法
  10. 航班预定系统java源代码_飞机订票系统源代码(Java)