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()⽅法。

Java 添加页码到Word文档_Java 添加页码到Word文档

  • 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.xml
			2. 定义一个类,实现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)
	@Documented
	public @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. 定义类继承HttpServlet
		2. 复写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.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
  • 响应消息(报文)格式: 服务器端发送给客户端的数据
数据格式:
1. 响应行
	1. 组成:协议/版本     响应状态码      状态码描述
		示例: HTTP/1.1      200             OK
	2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
		1. 状态码都是3位数字 
		2. 分类:
			1. 1xx:服务器接收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
			2. 2xx:成功。代表:200
			3. 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 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>
  • 常见状态码

状态码

状态码描述

含义

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 之间)。
这个系统提供了身份验证与加密通讯方法。
它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。

三、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:1
			
	2. 获取请求头数据
		* 方法:
			* (*)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=123
		2. String[] getParameterValues(String name):根据参数名称获取参数值的数组  hobby=xx&hobby=game
		3. 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 ok
		2. 设置状态码:setStatus(int sc) 
2. 设置响应头:setHeader(String name, String value) 
	添加响应头:void addHeader(String name, String value)     //两者作用一致
3. 设置响应体:
	* 使用步骤:
		1. 获取输出流
			* 字符输出流:PrintWriter getWriter()

			* 字节输出流:ServletOutputStream getOutputStream()

		2. 使用输出流,将数据输出到客户端浏览器
  • 案例
1. 完成重定向
	* 重定向:资源跳转的方式
	* 代码实现:
		//1. 设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/day15/responseDemo2");
        //简单的重定向方法
        response.sendRedirect("/day15/responseDemo2");
        
* forward 和  redirect 区别
	* 重定向的特点:redirect
		1. 地址栏发生变化
		2. 重定向可以访问其他站点(服务器)的资源
		3. 重定向是两次请求。不能使用request对象来共享数据
	* 转发的特点:forward
		1. 转发地址栏路径不变
		2. 转发只能访问当前服务器下的资源
		3. 转发是一次请求,可以使用request对象来共享数据

2. 服务器输出字符数据到浏览器
		* 步骤:
			1. 获取字符输出流
			2. 输出数据

		* 注意:
			* 乱码问题:
				1. PrintWriter pw = response.getWriter();
					获取的流的默认编码是ISO-8859-1
				2. 设置该流的默认编码     
				  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();
  1. 功能:
  1. 获取MIME类型:
  • MIME类型:在互联网通信过程中定义的一种文件数据类型
  • 格式: 大类型/小类型 text/html image/jpeg
  • 获取:String getMimeType(String file)
  1. 域对象:共享数据
  1. void setAttribute(String name,Object value)
  2. Object getAttribute(String name)
  3. void removeAttribute(String name)
    // ServletContext对象范围:所有用户所有请求的数据
  1. 获取文件的真实(服务器)路径
  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。一次会话中包含多次请求和响应。

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

  1. 功能:在一次会话的范围内的多次请求间,共享数据
  2. 方式:
  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进行相应的操作

Java 添加页码到Word文档_tomcat_02

  • 细节
  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)
  1. 原理
  • Session的实现是依赖于Cookie的。
  • 第一次获取Session,没有Cookie,服务器会在内存中创建一个新的Session对象,假设其对应的Id属性值为 ID = 742938a4289。
  • 服务器会自动设置响应头set-cookie:JSESSIONID= 742938a4289响应消息给浏览器。
  • 浏览器解析set-cookie响应头,将JSESSIONID=742938a4289存入Cookie请求头。
  • 后续服务器再次创建Session对象时会根据请求头Cookie中的JSESSIONID先在内存中寻找对应的session实例,然后返回其引用。
  1. 细节:
    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对象即可。
  1. 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对象会在失效时间过后被销毁。

  1. 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代码。

Java 添加页码到Word文档_java_03


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 指令相关属性:

Java 添加页码到Word文档_服务器_04

  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:前缀,自定义的
  1. 注释:
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表达式
  1. 使用:
  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
  1. 获取值
  1. el表达式只能从域对象中获取值
  2. 语法:
  1. ${域名称.键名}:从指定域中获取指定键的值
  • 域名称:
  1. pageScope --> pageContext
  2. requestScope --> request
  3. sessionScope --> session
  4. applicationScope --> application(ServletContext)
  • 举例:在request域中存储了name=张三
  • 获取:${requestScope.name}
  1. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
  2. 获取对象、List集合、Map集合的值
  1. 对象:${域名称.键名.属性名}
  • 本质上会去调用对象的getter方法
  1. List集合:${域名称.键名[索引]}
  • 索引越界会返回空字符
  1. Map集合:
  • ${域名称.键名.key名称}
  • ${域名称.键名[“key名称”]}
  1. 隐式对象:
    * 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表达式一起使用
  1. 注意:
  • c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
  1. choose:相当于java代码的switch语句
  1. 使用choose标签声明 相当于switch声明
  2. 使用when标签做判断 相当于case
  3. 使用otherwise标签做其他情况的声明 相当于default
  1. 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>

Java 添加页码到Word文档_Java 添加页码到Word文档_05


代码案例:

<%@ 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标签做数字判断         相当于case
            4.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>

Java 添加页码到Word文档_服务器_06


代码案例:

<%@ 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中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
  • 过滤器的作用:
  • 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤…
  1. 快速入门:
  1. 步骤:
  1. 定义一个类,实现接口Filter
  2. 复写方法
  3. 配置拦截路径
  1. web.xml
  2. 注解
  1. 代码:
@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() {
	
	    }
	}
  1. 过滤器细节:
  1. web.xml配置

    demo1
    cn.itcast.web.filter.FilterDemo1


    demo1

    /*
  2. 过滤器执行流程
  1. 执行过滤器
  2. 执行放行后的资源
  3. 回来执行过滤器放行代码下边的代码
  1. 过滤器生命周期方法
  1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
  2. doFilter:每一次请求被拦截资源时,会执行。执行多次
  3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
  1. 过滤器配置详解
  • 拦截路径配置:
  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>
  1. 过滤器链(配置多个过滤器)
  • 执行顺序:如果有两个过滤器:过滤器1和过滤器2
  1. 过滤器1
  2. 过滤器2
  3. 资源执行
  4. 过滤器2
  5. 过滤器1
  • 过滤器先后顺序问题:
  1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
  • 如: AFilter 和 BFilter,AFilter就先执行了。
  1. 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.监听器分类

Java 添加页码到Word文档_tomcat_07


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开发模式,使得程序的设计更加合理性

Java 添加页码到Word文档_java_08

  1. MVC:
  1. M:Model,模型。JavaBean
  • 完成具体的业务操作,如:查询数据库,封装对象
  1. V:View,视图。JSP
  • 展示数据
  1. 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的区别与联系

Java 添加页码到Word文档_java_09

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)如果需要更新内容,必须重载整个网页页面。
功能:提升用户的体验

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

Java 添加页码到Word文档_服务器_10

2.工作原理:

1.客户端浏览器发送JS请求Ajax引擎。

2.Ajax将JS请求转换成HTTP请求。

3.服务器对接收到的数据进行处理。

4.服务器返回XML、JSON或文本文档类型的数据给Ajax引擎。

5.AJax引擎接收服务器返回的数据进行渲染。

Java 添加页码到Word文档_intellij-idea_11

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

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

//1.创建核心对象
         var xmlhttp;
         if (window.XMLHttpRequest)
         {// code for IE7+, Firefox, Chrome, Opera, Safari
             xmlhttp=new XMLHttpRequest();
         }
         else
         {// code for IE6, IE5
             xmlhttp=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响应状态码是否为200
             if (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 格式
  • 方括号保存数组:[]
  1. 获取数据:
  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]);
     }
 }
  1. JSON数据和Java对象的相互转换
  • JSON解析器:
  • 常见的解析器:Jsonlib,Gson,fastjson,jackson
  1. JSON转为Java对象(jackson)
  1. 导入jackson的相关jar包
  2. 创建Jackson核心对象 ObjectMapper
  3. 调用ObjectMapper的相关方法进行转换
  1. readValue(json字符串数据,Class)
  1. 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字符串
  1. 注解:
  1. @JsonIgnore:被此注解标注的属性将不再被转为JSON格式
  2. @JsonFormat:属性值的格式化
  • @JsonFormat(pattern = “yyyy-MM-dd”) 如日期对象格式化,pattern用法与SimpleDateFormat类似
  1. 复杂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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

测试类

public class JacksonTest {


    //Java对象转为JSON字符串
    @Test
    public void test1() throws Exception {
        //1.创建Person对象
        Person p  = new Person();
        p.setName("张三");
        p.setAge(23);
        p.setGender("男");

        //2.创建Jackson的核心对象  ObjectMapper
        ObjectMapper 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);
    }


    @Test
    public void test2() throws Exception {
        //1.创建Person对象
        Person p = new Person();
        p.setName("张三");
        p.setAge(23);
        p.setGender("男");
        p.setBirthday(new Date());



        //2.转换  Object -> JSON
        ObjectMapper 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集合类似
    @Test
    public 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 -> JSON
        String 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 -> List
        List<Person> list = mapper.readValue(json, new TypeReference<List<Person>>() {
        });  // class java.util.ArrayList

        for (Person pp : list) {
            System.out.println(pp);
        }
    }

	//Map集合 -> JSON
    @Test
    public 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 -> JSON
        ObjectMapper 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.LinkedHashMap
        Map<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对象
    @Test
    public 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
	 */
    @Test
    public 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 -> JSON
        String json= mapper.writeValueAsString(persons);
        System.out.println(json);
		// JSON ->Array
		Person[] persons = mapper.readValue(json, Person[].class); // [Lcn.itcast.domain.Person;@43195e57
        String 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 jsnotallow=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!!!!