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

news/2024/10/23 5:47:25/

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>
  • 常见状态码

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

变量名真实类型作用
pageContextPageContext当前页面共享数据,还可以获取其他八个内置对象
requestHttpServletRequest一次请求访问的多个资源(转发)间共享数据。
sessionHttpSession一次会话的多个请求间共享数据
applicationServletContext所有用户间共享数据
responseHttpServletResponseresponse 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。只在JSP⻚⾯内有效。
pageObject当前页面(Servlet)的对象,类似于this
outJspWriter输出对象,数据输出到页面上
configServletConfig主要作⽤是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() ⽅法可以获取⼀个config对象。当⼀个Servlet 初始化时,容器把某些信息通过config对象传递给这个Servlet。 开发者可以在web.xml ⽂件中为应⽤程序环境中的Servlet程序和JSP⻚⾯提供初始化参数。
exceptionThrowableexception 对象的作⽤是显示异常信息,只有在包含 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!!!!


http://www.ppmy.cn/news/783866.html

相关文章

滴滴工程师带你深入理解 HTTP通信细节

点击蓝字加关注&#xff0c;人在江湖不迷路 作者&#xff1a;饶全成 出处&#xff1a;码农桃花源 上一篇文章中&#xff0c;我们学会了用wireshark和tcpdump来分析TCP的“三次握手&#xff0c;四次挥手”&#xff0c;非常好用。这哥俩就是传说中的 锤子&#xff0c;拿着 锤子&a…

移动硬盘使用时滴滴响的原因。

今天拿来了移动硬盘要拷贝一下系统镜像&#xff0c;不料接口插上之后电脑就滴滴响&#xff0c;我也不清楚是硬盘响还是主机在响&#xff0c;下了我一大跳&#xff0c;还以为电脑要爆炸了&#xff0c;后台我百度了一下网上说是因为电流不够的原因&#xff0c;解决办法是用双usb的…

D - Eating Candies

题意有 n 个糖果从左往右放在桌子上, Alice 和 Bob 吃糖果, Alice可以从左边开始吃, Bob可以从右边开始吃,他们需要连续吃,不能跳过任何一颗糖果,如果 Alice 吃掉了糖果, Bob 就不能吃,反之亦然&#xff0c;他们的目标是吃到等重的糖果。 Sample 1 InputcopyOutputcopy 4 3 1…

为什么游戏加速器都会设置韩国节点

经常玩游戏的朋友们都会知道很多游戏平台&#xff0c;尤其是像steam、ubisoft、epic这样的平台&#xff0c;如果从中国大陆地区直接访问的话由于在中国大陆地区没有国内节点很多都要走绕路的国际线路&#xff0c;所以经常会出现例如游戏离线、成就无法同步严重的话甚至可能出现…

移动游戏机和PC已合并游戏的奇点

As crossplay unifies player communities, gaming hardware differences are less relevant than ever. The walls are breaking down, all paths now lead to the same destination, and games are better for it. 由于交叉游戏统一了玩家社区&#xff0c;因此游戏硬件差异变…

epic堡垒之夜显示服务器离线,堡垒之夜epic服务器进不去 | 手游网游页游攻略大全...

发布时间:2017-12-19 堡垒之夜开国服了,那么有的小伙伴就发现自己的国服为什么进不去,下面牛游戏小编就为你们带来了堡垒之夜国服进不去的解决办法,想了解的小伙伴就一起来看看吧,希望能对你们有帮助. 解决办法如下: 1.重新下载并安装游戏,下载前关 ... 标签: 攻略 发布时间:…

玩游戏?Linux才高端!

2019独角兽企业重金招聘Python工程师标准>>> Linux操作系统一直被供奉在圣坛之上&#xff0c;只有程序猿、攻城狮和技术大牛才能用。但是很多菜鸟怀着敬畏的精神安装了Linux操作系统&#xff0c;却发现…太高端…不会用… 对此&#xff0c;很多人询问&#xff0c;在…

学会用这个工具,小白也能在Linux上畅玩手机游戏

目前主流Linux系统多数用于程序开发&#xff0c;很少有用于休闲娱乐的应用&#xff0c;比如&#xff1a;看电影、听歌、看小说、玩游戏等功能。 有些爱好游戏的朋友初学Linux&#xff0c;常常问我&#xff1a;“我可以在Linux上玩游戏吗&#xff1f;”答案是&#xff1a…