JavaWeb--Tomcat、Http、Servlet

day08

3 Web开发入门

                          3.1 引入

                                   之前的程序: java桌面程序,控制台控制,socket gui界面。javase规范

                                   现在和以后的程序:java web程序。浏览器控制。javaee规范

                          3.2 软件的结构

                                   C/S (Client - Server  客户端-服务器端)

                                                     典型应用:QQ软件 ,飞秋,红蜘蛛。

                                                     特点:

                                                             1)必须下载特定的客户端程序。

                                                             2)服务器端升级,客户端升级。

                                   B/S Broswer -Server 浏览器端- 服务器端)

                                                     典型应用: 腾讯官方(www.qq.com  163新闻网站, 传智官网(俗称:网站)

                                                     特点:

                                                             1)不需要安装特定的客户端(只需要安装浏览器即可!!)

                                                             2)服务器端升级,浏览器不需要升级!!!!

                                                     javaweb的程序就是b/s软件结构!!!

3.3 服务器

                                    从物理上来说,服务器就是一台PC机器。8核,8G以上,T来计算,带宽100M

                                   web服务器:PC机器安装一个具有web服务的软件,称之为web服务器

                                   数据库服务器:PC机器安装一个具有数据管理件服务的软件,称之为数据库服务器。

                                   邮件服务器:PC机器安装一个具有发送邮件服务的软件,称之为邮件服务器。

                          3.4 web服务软件

                                   web服务软件的作用:把本地的资源共享给外部访问。

                          3.5 常见的市面上web服务软件

                                            javase的规范,包含IO流,线程,集合,socket编程。。。。

                                   WebLogic: BEA公司的产品。 收费的。支持JavaEE规范。

                                   WebSphere: IBM公司的产品。收费的。支持JavaEE规范

                                   JBoss: Redhat公司的产品。收费的。支持JavaEE规范

  Tomcat 开源组织Apache的产品。免费的。支持部分的JavaEE规范。(servletjspjdbc,但     ejb rmi不支持)

总结下tomcat的三种部署方式:

第一种: 
非常简单,直接将 web 项目文件(一般是复制生成的war包)复制到tomcat的webapps目录中。

第二种: 
在本地tomcat的conf目录中,新建Catalina/localhost目录(这里要注意文件名的大小写),然后在该目录下新建一个xml文件,名字不可以随意取,要和path后 的名字一致,我这里就应该是jstore.xml文件,它的具体内容为:

<Context docBase="C:\work\jstore\web" path="/jstore" reloadable="true"/>
1
第三种: 
在tomcat中的conf目录下的server.xml文件中,在<Host/>节点中添加一个context,具体为:

<Context Path="/jstore"Docbase="C:\work\jstore\WebContent" Debug="0" Privileged="True" Reloadable="True"></Context>
这里的 Reloadable= “true” 这个属性是指tomcat在运行状态下会自动检测应用程序的WEB-INF/classes和WEB-INF/lib目录下的class文件,如果监测到有class文件有改动,服务器自动加载新的web应用程序,可以在不重起tomcat的情况下改变应用程序,也就是热部署; 
一般我们会在开发阶段将Reloadable属性设为true,有助于调试servlet和其它的class文件,但是由于这样会增加服务器的运行负荷,损耗系统性能,在项目运行阶段建议将它设为false。

总结:

①、第一种方法比较普通,但是我们需要将编译好的项目重新 copy 到 webapps 目录下,多出了两步操作

②、第三种方法直接在 server.xml 文件中配置,但是从 tomcat5.0版本开始后,server.xml 文件作为 tomcat 启动的主要配置文件,一旦 tomcat 启动后,便不会再读取这个文件,因此无法再 tomcat 服务启动后发布 web 项目

③、第二种方法是最好的,每个项目分开配置,tomcat 将以\conf\Catalina\localhost 目录下的 xml 文件的文件名作为 web 应用的上下文路径,而不再理会 <Context>中配置的 path 路径,因此在配置的时候,可以不写 path。

通常我们使用第三种方法

4 Tomcat基本使用

                          4.1 下载并按照

                          1)到apache官网。www.apache.org     http://jakarta.apache.org(产品的主页)

                          2)

                                   安装版:window (exe、msi) linux(rmp)

                                   压缩版:window(rar,zip) linux(tar,tar.gz)学习时候使用

                          3)运行和关闭tomcat

                                            3.1 启动软件

                                                     a)找到%tomcat%/bin/startup.bat ,双击这个文件

                                                     b)弹出窗口,显示信息(不要关闭次窗口)

                                                     c)打开浏览器,输出以下地址

                                                             http://localhost:8080

                                                     d)看到一只猫画面,证明软件启动成功!

                                            3.3 关闭软件

                                                     a)找到%tomcat%/bin/shutdown.bat,双击这个文件即可!

                                                     c)打开浏览器,输出以下地址。看到“无法连接”(最好先清空浏览器缓存)

                          4.2 tomcat软件使用的常见问题

                                   1)闪退问题

                                   原因:tomcat软件是java语言开发的。 tomcat软件启动时,会默认到系统的环境变量中查找一个名称叫JAVA_HOME的变量。这个变量的作用找到tomcat启动所需的jvm。

                                   解决办法; 到环境变量中设置JAVA_HOME的变量

                                       JAVA_HOME= C:\Program Files\Java\jdk1.6.0_30  (注意别配置到bin目录下)                 

                                   2)端口占用的错误

                                   原因: tomcat启动所需的端口被其他软件占用了!

                                   解决办法:

                                            a)关闭其他软件程序,释放所需端口

                                            b)修改tomcat软件所需端口

                                          找到并修改%tomcat%/conf/server.xml文件

                                                    

  <Connector port="8081" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443" />

                                   3)CATALINA环境变量问题

                                   原因: tomcat软件启动后,除了查找JAVA_HOME后,还会再查找一个叫CATALINA_HOME变量,这个变量的作用是设置tomcat的根目录。

                                   解决办法:建议不要设置CATALINA_HOME变量。检查如果有的话,清除掉!!!

                          4.3 体验tomcat软件作用

                                   webapps目录: tomcat共享目录。需要共享的本地资源放到此目录中。

        

4.4 URL

                                   URL全名叫统一资源定位符,用于定位互联网的资源。            

                                    问题: http://localhost:8081/myweb/test.html  看到文件?

                                   http://     协议。http协议。

                                   localhost    域名。为了找到IP地址。

                                                                      本地域名: localhost

                                                                      外部域名:www.baidu.com

                                   8081       端口。软件监听的

                                                             8080: tomcat默认的端口

                                                             3306:mysql数据库的端口

                                                             1521: orace数据库的端口。

                                   /myweb:   web应用的名称。默认情况下,在webapps目录下找

                                   /test.html  : 资源名称。     

5 Tomcat的目录结构

                  |-bin: 存放tomcat的命令。

                                   catalina.bat 命令:

                                            startup.bat  -> catalina.bat start  

                                            shutdown.bat - > catalina.bat stop

             |- conf: 存放tomcat的配置信息。其中server.xml文件是核心的配置文件。

                  |-lib:支持tomcat软件运行的jar包。其中还有技术支持包,如servlet,jsp

                  |-logs:运行过程的日志信息

                  |-temp: 临时目录

                  |-webapps: 共享资源目录。web应用目录。(注意不能以单独的文件进行共享)

                  |-work: tomcat的运行目录。jsp运行时产生的临时文件就存放在这里

6 Web应用的目录结构

                  |- WebRoot :   web应用的根目录

                                   |- 静态资源(html+css+js+image+vedio)
                                   |- WEB-INF : 固定写法。

                                            |-classes: (可选)固定写法。存放class字节码文件

                                            |-lib: (可选)固定写法。存放jar包文件。

                                            |-web.xml                                                           

                  注意:

                          1)WEB-INF目录里面的资源不能通过浏览器直接访问

                          2)如果希望访问到WEB-INF里面的资源,就必须把资源配置到一个叫web.xml的文件中。

7 手动开发动态资源

                          7.1 静态资源和动态资源的区别

                                   静态资源: 当用户多次访问这个资源,资源的源代码永远不会改变的资源。

                                   动态资源:当用户多次访问这个资源,资源的源代码可能会发送改变。

                          7.2 动态资源的开发技术

                          Servlet : 用java语言来编写动态资源的开发技术。

                          Servlet特点:

                                            1)普通的java类,继承HttpServlet类,覆盖doGet方法

                                          2)Servlet类只能交给tomcat服务器运行!!!!(开发者自己不能运行!!!)

                          Servlet手动编写步骤:

                                   1)编写一个servlet程序,继承HttpServlet

/**
 * 第一个servlet程序
 * @author APPle
 *
 */
public class HelloServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		//解决中文乱码问题
		resp.setContentType("text/html;charset=utf-8");
		//向浏览器输出内容
		resp.getWriter().write("这是第一个servlet程序。当前时间为:"+new Date());
	}
}

      2)找到HelloServlet类的class字节码,然后把拷贝到tomcat的一个web应用中WEB-INF/classes目录下。

       3)在当前web应用下的web.xml文件配置Servlet。

<!-- 配置一个servlet程序 -->
	<servlet>
		<!-- servlet的内部名称 ,可以自定义-->
		<servlet-name>HelloServlet</servlet-name>
		<!-- servlet类名: 包名+简单类名-->
		<servlet-class>gz.itcast.d_servlet.HelloServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<!-- servlet的内部名称,和上面的名称保持一致!!!-->
		<servlet-name>HelloServlet</servlet-name>
		<!-- servlet的访问名称: /名称 -->
		<url-pattern>/hello</url-pattern>
	</servlet-mapping>

     4)启动tomcat服务器,运行访问

                  访问servlet:  http://localhost:8080/myweb/ hello

8 工具开发动态资源

                  1)创建web project (javaweb工程)

                  2)在WebRoot下建立静态资源文件,

                  3)在src下建立动态资源文件

                            3.1 new -> Servlet( servlet的代码生成器)

                            3.2 写pacakge  -> class名 -> 修改mapping  url

                  4)关联tomcat服务器

                          4.1 window-> Preferences - > MyEcplise -> servers -> Tomcat 6.x (注意一定要enable)

                  5)部署web project应用。(拷贝web应用到tomcat的webapps目录下)

                  6)启动tomcat服务器

                  7)访问servlet                       

                                   http://localhost:8081/day08_web/hello

DAY09

2 Http协议入门

  2.1 什么是http协议

                http协议: 对浏览器客户端 和  服务器端 之间数据传输的格式规范

  2.2 查看http协议的工具

                                   1)使用火狐的firebug插件(右键->firebug->网络)

                                   2)使用谷歌的“审查元素”

                                   3)使用系统自带的telnet工具(远程访问工具)                           

                                                     a)telnet localhost 8080      访问tomcat服务器

                                                     b)ctrl+]     回车          可以看到回显

                                                     c)输入请求内容                                        

GET /day09/hello HTTP/1.1

Host: localhost:8080

                                                     d)回车,即可查看到服务器响应信息。

2.3 http协议内容         

请求(浏览器-》服务器)

GET /day09/hello HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

 

响应(服务器-》浏览器)

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Length: 24

Date: Fri, 30 Jan 2015 01:54:57 GMT

 

this is hello servlet!!!

3 Http请求

GET /day09/hello HTTP/1.1               -请求行

Host: localhost:8080                    --请求头(多个key-value对象)

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: keep-alive

                                    --一个空行

name=eric&password=123456             --(可选)实体内容

                  3.1 请求行

                          GET /day09/hello HTTP/1.1    

         #http协议版本

      http1.0:当前浏览器客户端与服务器端建立连接之后,只能发送一次请求,一次请求之后连接关闭。

     http1.1:当前浏览器客户端与服务器端建立连接之后,可以在一次连接中发送多次请求。(基本都使用1.1)

         #请求资源

              URL:  统一资源定位符。http://localhost:8080/day09/testImg.html。只能定位互联网资源。是URI 的子集。

             URI: 统一资源标记符。/day09/hello。用于标记任何资源。可以是本地文件系统,局域网的资源(//192.168.14.10/myweb/index.html),                                               可以是互联网。

         #请求方式

                          常见的请求方式: GET 、 POST、 HEAD、 TRACE、 PUT、 CONNECT 、DELETE        

                          常用的请求方式: GET  和 POST    

                          表单提交:

                                   <form action="提交地址" method="GET/POST">

 

                                   <form>

         GET   vs  POST 区别

                          1)GET方式提交

                                            a)地址栏(URI)会跟上参数数据。以?开头,多个参数之间以&分割。

GET /day09/testMethod.html?name=eric&password=123456 HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://localhost:8080/day09/testMethod.html

Connection: keep-alive

                                            b)GET提交参数数据有限制,不超过1KB。

                                            c)GET方式不适合提交敏感密码。

                                            d)注意: 浏览器直接访问的请求,默认提交方式是GET方式

                           2)POST方式提交

                   a)参数不会跟着URI后面。参数而是跟在请求的实体内容中。没有?开头,多个参数之间以&分割。

POST /day09/testMethod.html HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://localhost:8080/day09/testMethod.html

Connection: keep-alive

 

name=eric&password=123456

 

                                            b)POST提交的参数数据没有限制。

                                            c)POST方式提交敏感数据。

                  3.2 请求头

Accept: text/html,image/*      -- 浏览器接受的数据类型

Accept-Charset: ISO-8859-1     -- 浏览器接受的编码格式

Accept-Encoding: gzip,compress  --浏览器接受的数据压缩格式

Accept-Language: en-us,zh-       --浏览器接受的语言

Host: www.it315.org:80          --(必须的)当前请求访问的目标地址(主机:端口)

If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT  --浏览器最后的缓存时间

Referer: http://www.it315.org/index.jsp      -- 当前请求来自于哪里

User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)  --浏览器类型

Cookie:name=eric                     -- 浏览器保存的cookie信息

Connection: close/Keep-Alive            -- 浏览器跟服务器连接状态。close: 连接关闭  keep-alive:保存连接。

Date: Tue, 11 Jul 2000 18:23:51 GMT      -- 请求发出的时间

 

          3.3 实体内容

                                   只有POST提交的参数会放到实体内容中

      3.4 HttpServletRequest对象

                          HttpServletRequest对象作用是用于获取请求数据。

                                      核心的API:

                                            请求行:

                                                     request.getMethod();   请求方式

                                                     request.getRequetURI()   / request.getRequetURL()   请求资源

                                                     request.getProtocol()   请求http协议版本                                         

                                            请求头:

                                                     request.getHeader("名称")   根据请求头获取请求值

                                                     request.getHeaderNames()    获取所有的请求头名称

                                            实体内容:

                                                     request.getInputStream()   获取实体内容数据

package gz.itcast.b_request;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

注意:tomcat服务器首先会调用servlet的service方法,然后在service方法中再根据请求方式来分别调用对应的doXX方法
 * (例如,如果是GET请求方式,在service方法中调用doGet方法)
 * 
 *   因为最常的请求方式是GET 和POST,所以编写servlet程序,只需要覆盖doGet和doPost即可!!!!

/**
 * 请求数据的获取
 * @author APPle
 *
 */
public class RequestDemo1 extends HttpServlet {

	/**
	 * 1)tomcat服务器接收到浏览器发送的请求数据,然后封装到HttpServetRequest对象
	 * 2)tomcat服务器调用doGet方法,然后把request对象传入到servlet中。
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/**
		 * 3)从request对象取出请求数据。
		 */
		t1(request);
		
		t2(request); 
		
		
	}
	
	// 为了接收POST方式提交的请求
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse resp)
			throws ServletException, IOException {
		/**
		 * 3.3 请求的实体内容
		 */
		InputStream in = request.getInputStream(); //得到实体内容
		byte[] buf = new byte[1024];
		int len = 0;
		while(  (len=in.read(buf))!=-1 ){
			String str = new String(buf,0,len);
			System.out.println(str);
		}
	}

	private void t2(HttpServletRequest request) {
		/**
		 * 3.2 请求头
		 */
		String host = request.getHeader("Host"); //根据头名称的到头的内容
		System.out.println(host);
		
		//遍历所有请求头
		Enumeration<String> enums = request.getHeaderNames(); //得到所有的请求头名称列表
		while(enums.hasMoreElements()){//判断是否有下一个元素
			String headerName = enums.nextElement(); //取出下一个元素
			String headerValue = request.getHeader(headerName);
			System.out.println(headerName+":"+headerValue);
		}
	}

	private void t1(HttpServletRequest request) {
		/**
		 * 3.1 请求行   格式:(GET /day09/hello HTTP/1.1)
		 */
		System.out.println("请求方式:"+request.getMethod());//请求方式
		System.out.println("URI:"+request.getRequestURI());//请求资源
		System.out.println("URL:"+request.getRequestURL());
		System.out.println("http协议版本:"+request.getProtocol());//http协议
	}

}

3.8 传递的请求参数如何获取            

                           GET方式: 参数放在URI后面

                           POST方式: 参数放在实体内容中

                          获取GET方式参数:

                                            request.getQueryString();

                          获取POST方式参数:

                                            request.getInputStream();

                          问题:但是以上两种不通用,而且获取到的参数还需要进一步地解析。

                          所以可以使用统一方便的获取参数的方式:                                  

                                  核心的API:

                              request.getParameter("参数名");  根据参数名获取参数值(注意,只能获取一个值的参数)

                              request.getParameterValue("参数名“);根据参数名获取参数值(可以获取多个值的参数)

                               request.getParameterNames();   获取所有参数名称列表  

package gz.itcast.b_request;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 获取GET方式和Post方式提交的参数
 * @author APPle
 *
 */
public class RequestDemo5 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/**
		 * 设置参数查询的编码
		 * 该方法只能对请求实体内容的数据编码起作用。POST提交的数据在实体内容中,所以该方法对POST方法有效!
		 * GET方法的参数放在URI后面,所以对GET方式无效!!!
		 */
		request.setCharacterEncoding("utf-8");
		
		
	/*	System.out.println("GET方式");
		//接收GET方式提交的参数
		String value = request.getQueryString();
		System.out.println(value);*/
		
		
		/**
		 * 统一方便地获取请求参数的方法
		 */
		System.out.println(request.getMethod()+"方式");
		//getParameter(name): 根据参数名得到参数值(只能获取一个值的参数)
		String name = request.getParameter("name");
		
		/**
		 * 手动重新解码(iso-8859-1 字符串-> utf-8 字符串)
		 */
		/*if("GET".equals(request.getMethod())){
			name = new String(name.getBytes("iso-8859-1"),"utf-8");
		}*/
		
		String password = request.getParameter("password");
		
		/*if("GET".equals(request.getMethod())){
			password = new String(password.getBytes("iso-8859-1"),"utf-8");
		}*/
		
		System.out.println(name+"="+password);
		
		System.out.println("=============================");
		Enumeration<String> enums = request.getParameterNames();
		while( enums.hasMoreElements() ){
			String paramName = enums.nextElement();
			
			//如果参数名是hobit,则调用getParameterValues
			if("hobit".equals(paramName)){
				/**
				 * getParameterValues(name): 根据参数名获取参数值(可以获取多个值的同名参数)
				 */
				System.out.println(paramName+":");
				String[] hobits = request.getParameterValues("hobit");
				for(String h: hobits){
				/*	if("GET".equals(request.getMethod())){
						h = new String(h.getBytes("iso-8859-1"),"utf-8");
					}*/
					System.out.print(h+",");
				}
				System.out.println();
				//如果不是hobit,则调用getParameter
			}else{
				String paramValue = request.getParameter(paramName);
				/*
				if("GET".equals(request.getMethod())){
					paramValue = new String(paramValue.getBytes("iso-8859-1"),"utf-8");
				}*/
				
				System.out.println(paramName+"="+paramValue);
			}
		}
	
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*System.out.println("POST方式");
		InputStream in = request.getInputStream();
		byte[] buf = new byte[1024];
		int len = 0;
		while(  (len=in.read(buf))!=-1 ){
			System.out.println(new String(buf,0,len));
		}*/
		
		/**
		 * 统一方便地获取请求参数的方法
		 */
		/*System.out.println("POST方式");
		//根据参数名得到参数值
		String name = request.getParameter("name");
		String password = request.getParameter("password");
		System.out.println(name+"="+password);
		
		System.out.println("=============================");
		Enumeration<String> enums = request.getParameterNames();
		while( enums.hasMoreElements() ){
			String paramName = enums.nextElement();
			String paramValue = request.getParameter(paramName);
			System.out.println(paramName+"="+paramValue);
		}*/
		
		//一定调用doGet方式
		this.doGet(request, response);
	}

}

3.9 请求参数编码问题

                                   修改POST方式参数编码:

                                                  request.setCharacterEncoding("utf-8");

                                   修改GET方式参数编码:

                                                手动解码:String name = new String(name.getBytes("iso-8859-1"),"utf-8")

4 Http响应

HTTP/1.1 200 OK                --响应行

Server: Apache-Coyote/1.1         --响应头(key-vaule)

Content-Length: 24

Date: Fri, 30 Jan 2015 01:54:57 GMT

                                   --一个空行

this is hello servlet!!!                  --实体内容

 

                          4.1 响应行

                   #http协议版本

                      #状态码: 服务器处理请求的结果(状态)

                                            常见的状态:

                                                     200 :  表示请求处理完成并完美返回

                                                     302:   表示请求需要进一步细化。
                                                     404:   表示客户访问的资源找不到。

                                                     500:   表示服务器的资源发送错误。(服务器内部错误)

                     #状态描述        

      4.2 常见的响应头

Location: http://www.it315.org/index.jsp   -表示重定向的地址,该头和302的状态码一起使用。

Server:apache tomcat                 ---表示服务器的类型

Content-Encoding: gzip                 -- 表示服务器发送给浏览器的数据压缩类型

Content-Length: 80                    --表示服务器发送给浏览器的数据长度

Content-Language: zh-cn               --表示服务器支持的语言

Content-Type: text/html; charset=GB2312   --表示服务器发送给浏览器的数据类型及内容编码

Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT  --表示服务器资源的最后修改时间

Refresh: 1;url=http://www.it315.org     --表示定时刷新

Content-Disposition: attachment; filename=aaa.zip --表示告诉浏览器以下载方式打开资源(下载文件时用到)

Transfer-Encoding: chunked

Set-Cookie:SS=Q0=5Lb_nQ; path=/search   --表示服务器发送给浏览器的cookie信息(会话管理用到)

Expires: -1                           --表示通知浏览器不进行缓存

Cache-Control: no-cache

Pragma: no-cache

Connection: close/Keep-Alive           --表示服务器和浏览器的连接状态。close:关闭连接 keep-alive:保存连接

 

                          4.3 HttpServletResponse对象

                          HttpServletResponse对象修改响应信息:

                                            响应行:

                                                             response.setStatus()  设置状态码

                                            响应头:

                                                             response.setHeader("name","value")  设置响应头

                                            实体内容:

                                                             response.getWriter().writer();   发送字符实体内容

                                                             response.getOutputStream().writer()  发送字节实体内容

总结:

                                   http协议: 浏览器和服务器之间数据传输的格式规范

                                   1)http请求:

                                                     格式:

                                                                      请求行

                                                                      请求头

                                                                      空行

                                                                      实体内容(POST提交的数据在实体内容中)

                                                     重点:

                                                             使用HttpServletRequest对象: 获取请求数据

                          2)http响应;

                                            格式:

                                                             响应行

                                                             响应头

                                                             空行

                                                             实体内容(浏览器看到的内容)

                                            重点:

                                                     使用HttpServletResponse对象: 设置响应数据

DAY10

  servlet编程 

Servlet学习的大纲:

  • 1. servlet概念及相关接口简介
  • 2. servet 执行过程
  • 3. servlet路径映射
  • 4. 缺省servlet          --应用
  • 5. servlet生命周期(重点)   --理解(重点)
  • 6. Servlet自动加载
  • 7. Servlet线程安全
  • 8. servletConfig对象
  • 9. Servlet相关接口详解
  • 10. ServletContext对象     --知识点

1 如何开发一个Servlet

                  1.1 步骤:

                                   1)编写java类,继承HttpServlet类

                                   2)重新doGet和doPost方法

                                   3)Servlet程序交给tomcat服务器运行!!

                                                     3.1 servlet程序的class码拷贝到WEB-INF/classes目录

                                                     3.2 在web.xml文件中进行配置

<!-- 配置一个servlet -->
  <!-- servlet的配置 -->
  <servlet>
  	<!-- servlet的内部名称,自定义。尽量有意义 -->
  	<servlet-name>FirstServlet</servlet-name>
  	<!-- servlet的类全名: 包名+简单类名 -->
  	<servlet-class>gz.itcast.a_servlet.FirstServlet</servlet-class>
  </servlet>
  
  
  <!-- servlet的映射配置 -->
  <servlet-mapping>
  	<!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->
  	<servlet-name>FirstServlet</servlet-name>
  	<!-- servlet的映射路径(访问servlet的名称) -->
  	<url-pattern>/first</url-pattern>
  </servlet-mapping>

问题:访问次URL:  http://localhost:8080/day10/first                  

前提: tomcat服务器启动时,首先加载webapps中的每个web应用的web.xml配置文件。        

                  http://: http协议

                  localhost: 到本地的hosts文件中查找是否存在该域名对应的IP地址

                          127.0.0.1

                  8080:    找到tomcat服务器

                  /day10     在tomcat的webapps目录下找 day10的目录

                  /first    资源名称。

                                   1)在day10web.xml中查找是否有匹配的url-pattern的内容(/first

                                   2)如果找到匹配的url-pattern,则使用当前servlet-name的名称到web.xml文件中查询是否相同名称的servlet配置

                                   3)如果找到,则取出对应的servlet配置信息中的servlet-class内容:

                                                     字符串: gz.itcast.a_servlet.FirstServlet

             通过反射:

                a)构造FirstServlet的对象

                b)然后调用FirstServlet里面的方法

2 Servlet的映射路径               

<servlet-mapping>

    <!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->

    <servlet-name>FirstServlet</servlet-name>

    <!-- servlet的映射路径(访问servlet的名称) -->

    <url-pattern>/first</url-pattern>

  </servlet-mapping>

                    url-pattern                   浏览器输入

精确匹配             /first                 http://localhost:8080/day10/first

                                            /itcast/demo1          http://localhost:8080/day10/itcast/demo1

 

模糊匹配             /*                   http://localhost:8080/day10/任意路径

                          /itcast/*               http://localhost:8080/day10/itcast/任意路径

                         *.后缀名              http://localhost:8080/day10/任意路径.do

                         *.do

                         *.action

                         *.html(伪静态)

注意:

                  1url-pattern要么以 / 开头,要么以*开头。  例如, itcast是非法路径。

                  2)不能同时使用两种模糊匹配,例如 /itcast/*.do是非法路径

                  3)当有输入的URL有多个servlet同时被匹配的情况下:

                                   3.1 精确匹配优先。(长的最像优先被匹配)

                                   3.2 以后缀名结尾的模糊url-pattern优先级最低!!!

3 servlet缺省路径

                  servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件

                  问题: URL输入http://localhost:8080/day10/index.html 如何读取文件????

                  1)到当前day10应用下的web.xml文件查找是否有匹配的url-pattern。

                  2)如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理

                  3)DefaultServlet程序到day10应用的根目录下查找是存在一个名称为index.html的静态文件。

                  4)如果找到该文件,则读取该文件内容,返回给浏览器。

                  5)如果找不到该文件,则返回404错误页面。

               结论: 先找动态资源,再找静态资源。

4 Sevlet的生命周期(重点)

                    4.1 引入

                          Servlet的生命周期: servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。

                          以前的对象: new Student(); stu.study();   stu=null;        

                          Servlet程序的生命周期由tomcat服务器控制的!!!!                                  

                    4.2 Servlet重要的四个生命周期方法

            构造方法: 创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象只调用1次。证明servlet对象在tomcat是单实例的。

                   init方法: 创建完servlet对象的时候调用。只调用1次。

                  service方法: 每次发出请求时调用。调用n次。

                  destroy方法: 销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。 只调用1次。

4.3 伪代码演示servlet的生命周期

                  Tomtcat内部代码运行:

                          1)通过映射找到到servlet-class的内容,字符串: gz.itcast.a_servlet.FirstServlet

         2)通过反射构造FirstServlet对象

                2.1 得到字节码对象

                Class clazz = class.forName("gz.itcast.a_servlet.FirstServlet");

                2.2 调用无参数的构造方法来构造对象

                Object obj = clazz.newInstance();     ---1.servlet的构造方法被调用

          3)创建ServletConfig对象,通过反射调用init方法

                3.1 得到方法对象

                Method m = clazz.getDeclareMethod("init",ServletConfig.class);

                3.2 调用方法

                m.invoke(obj,config);             --2.servletinit方法被调用

          4)创建request,response对象,通过反射调用service方法

                4.1 得到方法对象

    Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

                4.2 调用方法

                m.invoke(obj,request,response);  --3.servletservice方法被调用

          5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法

                5.1 得到方法对象

                Method m = clazz.getDeclareMethod("destroy",null);

                5.2 调用方法

                m.invoke(obj,null);            --4.servletdestroy方法被调用

4.4 用时序图来演示servlet的生命周期

5 Servlet的自动加载

                          默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。

                          改变servlet创建对象的时机: 提前到加载web应用的时候!!!

         在servlet的配置信息中,加上一个<load-on-startup>即可!!

<servlet>

    <servlet-name>LifeDemo</servlet-name>

    <servlet-class>gz.itcast.c_life.LifeDemo</servlet-class>

    <!-- servlet对象自动加载 -->

    <load-on-startup>1</load-on-startup>  注意: 整数值越大,创建优先级越低!!

  </servlet>

7 有参的init方法和无参的init方法

package gz.itcast.d_init;


import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * 有参数的init和无参的init方法
 * @author APPle
 *
 */
public class InitDemo extends HttpServlet {
		
	/**
	 * 有参数的init方法
	 * 该方法是servlet的生命周期方法,一定会被tomcat服务器调用
	 */
	/**
	 * 注意:如果要编写初始代码,不需要覆盖有参数的init方法
	 */
	/*@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("有参数的init方法");
	}*/
	
	/**
	 * 无参数的init方法
	 * 该方法是servlet的编写初始化代码的方法。是Sun公司设计出来专门给开发者进行覆盖,然后在里面编写servlet的初始逻辑代码的方法。
	 */
	@Override
	public void init() throws ServletException {
		System.out.println("无参数的init方法");
	}
	
	
}

8 Servlet的多线程并发问题

                  注意: servlet对象在tomcat服务器是单实例多线程的。

                 因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

                  解决办法:

               1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

                  2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

                 Servlet学习:

                                    HttpServletRequest  请求对象:获取请求信息

                                    HttpServletResponse 响应对象: 设置响应对象

                                    ServletConfig对象    servlet配置对象

                                    ServletContext对象; servlet的上下文对象

              9.1 作用

             ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

            9.2 对象创建和得到

                          创建时机: 在创建完servlet对象之后,在调用init方法之前创建。

                          得到对象: 直接从有参数的init方法中得到!!!

           9.3 servlet的初始化参数配置

 <servlet>
    <servlet-name>ConfigDemo</servlet-name>
    <servlet-class>gz.itcast.f_config.ConfigDemo</servlet-class>
    <!-- 初始参数: 这些参数会在加载web应用的时候,封装到ServletConfig对象中 -->
    <init-param>
    	<param-name>path</param-name>
    	<param-value>e:/b.txt</param-value>
    </init-param>
  </servlet>

           注意: servlet的参数只能由当前的这个sevlet获取!!!!

         ServletConfig的API:

                       java.lang.String getInitParameter(java.lang.String name)  根据参数名获取参数值

                       java.util.Enumeration getInitParameterNames()    获取所有参数

                      ServletContext getServletContext()     得到servlet上下文对象

                       java.lang.String getServletName()       得到servlet的名称

package gz.itcast.f_config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ConfigDemo extends HttpServlet {
	/**
	 * 以下两段代码GenericServlet已经写了,我们无需编写!!
	 */
	/*private ServletConfig config;*/
	
	/**
	 *  1)tomcat服务器把这些参数会在加载web应用的时候,封装到ServletConfig对象中 
	 *  2)tomcat服务器调用init方法传入ServletConfig对象
	 */
	/*@Override
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
	}*/
	
	

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/**
		 * 读取servlet的初始参数
		 */
		String path = this.getServletConfig().getInitParameter("path");

		File file = new File(path);
		//读取内容
		BufferedReader br = new BufferedReader(new FileReader(file));
		String str = null;
		while( (str=br.readLine())!=null ){
			System.out.println(str);
		}
		
		//查询当前servlet的所有初始化参数
		Enumeration<String> enums = this.getServletConfig().getInitParameterNames();
		while(enums.hasMoreElements()){
			String paramName = enums.nextElement();
			String paramValue = this.getServletConfig().getInitParameter(paramName);
			System.out.println(paramName+"="+paramValue);
		}
		
		//得到servlet的名称
		String servletName = this.getServletConfig().getServletName();
		System.out.println(servletName);
	}

}

10 ServletContext对象

                     10.1 引入

                ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一 个ServletContext对象。

                     10.2 对象创建和得到

                          创建时机:加载web应用时创建ServletContext对象。

                          得到对象: ServletConfig对象的getServletContext方法得到

                                

                                   我们设计:

                                            创建ServletConfig对象

                                            public void init( ServletConfig configServletContext context ){  多了一个参数

                                                     得到ServletConfig对象

                                                     得到ServletContext对象;

                                            }

 

                                   Sun公司设计

                         1)创建ServletContext对象   ServletContext  context = new ServletContext()              

                           2)创建ServletConfig对象   ServetConfig config = new ServletConfig();

                                              config.setServletContxt(context);

                                            class  ServletConfig{

                                                              ServletContext context;

                                                             public ServletContext getServletContxt(){

                                                                      return contxt;

                                                             }

                                            }

 

                                            public void init( ServletConfig config ){

                                                     得到ServletConfig对象

                                                     ServletConfig对象中得到ServletContext对象

                                                     SerlvetContext context = config.getServletContext();

                                            }

      10.1 ServletContext对象的核心API(作用)

                 

                           java.lang.String getContextPath()   --得到当前web应用的路径

 

                          java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数

                          java.util.Enumeration getInitParameterNames() 

 

                          void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法

                          java.lang.Object  getAttribute(java.lang.String name) 

                          void removeAttribute(java.lang.String name) 

 

                          RequestDispatcher getRequestDispatcher(java.lang.String path)   --转发(类似于重定向)

 

                          java.lang.String getRealPath(java.lang.String path)     --得到web应用的资源文件

                          java.io.InputStream getResourceAsStream(java.lang.String path) 

package gz.itcast.f_context;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 得到web应用路径
 * @author APPle
 *
 */
public class ContextDemo1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//1.得到ServletContext对象
		//ServletContext context = this.getServletConfig().getServletContext();
		ServletContext context = this.getServletContext(); //(推荐使用)
		
		
		//2.得到web应用路径  /day10
		/**
		 * web应用路径:部署到tomcat服务器上运行的web应用名称
		 */
		String contextPath = context.getContextPath();
		
		System.out.println(contextPath);
		
		
		/**
		 * 案例:应用到请求重定向
		 */
		response.sendRedirect(contextPath+"/index.html");
	}

}
package gz.itcast.f_context;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 得到web应用参数
 * @author APPle
 *
 */
public class ContextDemo2 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//得到SErvletContext对象
		ServletContext context = this.getServletContext();
		
		System.out.println("参数"+context.getInitParameter("AAA"));
		
		Enumeration<String> enums = context.getInitParameterNames();
		while(enums.hasMoreElements()){
			String paramName = enums.nextElement();
			String paramValue  =context.getInitParameter(paramName);
			System.out.println(paramName+"="+paramValue);
		}
		
		//尝试得到ConfigDemo中的servlet参数
		String path = this.getServletConfig().getInitParameter("path");
		System.out.println("path="+path);
	}

}
package gz.itcast.f_context;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 保存数据
 * @author APPle
 *
 */
public class ContextDemo3 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//1.得到域对象
		ServletContext context = this.getServletContext();
		
		//2.把数据保存到域对象中
		//context.setAttribute("name", "eric");
		context.setAttribute("student", new Student("jacky",20));
		System.out.println("保存成功");
	}

}


class Student{
	private String name;
	private int age;
	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 Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}
	
}
========================================================================
package gz.itcast.f_context;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 获取数据
 * @author APPle
 *
 */
public class ContextDemo4 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//1.得到域对象
		ServletContext context = this.getServletContext();
		
		//2.从域对象中取出数据
		//String name = (String)context.getAttribute("name");
		Student student = (Student)context.getAttribute("student");
		//System.out.println("name="+name);
		
		System.out.println(student);
	}

}

10.3 得到web应用路径

                                   java.lang.String getContextPath()  用在请求重定向的资源名称中

10.4得到web应用的初始化参数(全局)

                          java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数

                          java.util.Enumeration getInitParameterNames() 

 

                                   web应用参数可以让当前web应用的所有servlet获取!!!

   10.5域对象有关的方法

域对象:作用是用于保存数据,获取数据。可以在不同的动态资源之间共享数据

 

                                            案例:  

                                            Servlet1                   Servlet2

                                  name=eric                    

                                   response.sendRedirect("/Servlet2?name=eric")             String request.getParameter("name");

                                            保存到域对象中                                                       从域对象获取

                                            Student                 

                                   方案1: 可以通过传递参数的形式,共享数据。局限:只能传递字符串类型。

                                   方案2: 可以使用域对象共享数据,好处:可以共享任何类型的数据!!!!!

 

                                   ServletContext就是一个域对象!!!!

 

                           保存数据:void setAttribute(java.lang.String name, java.lang.Object object)                                      

                          获取数据: java.lang.Object getAttribute(java.lang.String name)  

                          删除数据: void removeAttribute(java.lang.String name) 

 

                          ServletContext域对象:作用范围在整个web应用中有效!!!

 

                                            所有域对象:

                                                     HttpServletRequet 域对象

                                                     ServletContext域对象

                                                     HttpSession 域对象

                                                     PageContext域对象      

 

                          10.6 转发

                           RequestDispatcher getRequestDispatcher(java.lang.String path)

 

                           1)转发

                                    a)地址栏不会改变

                                    b)转发只能转发到当前web应用内的资源

                                   c)可以在转发过程中,可以把数据保存到request域对象中

 

                          2)重定向                       

                                   a)地址栏会改变,变成重定向到地址。

                                   b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。

                                   c)不能再重定向的过程,把数据保存到request中。

 

                          结论: 如果要使用request域对象进行数据共享,只能用转发技术!!!

/**
		 * 保存数据到request域对象
		 */
		request.setAttribute("name", "rose");
		
		
		//转发	
		/**
		 * 注意:不能转发当前web应用以外的资源。
		 */
		/*RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/GetDataServlet");
		rd.forward(request, response);*/
		this.getServletContext().getRequestDispatcher("/GetDateServlet").forward(request, response);
==============================================================
/**
		 * 保存数据到request域对象
		 */
		request.setAttribute("name", "rose");
		
		//重定向
		/**
		 * 注意:可以跳转到web应用内,或其他web应用,甚至其他外部域名。
		 */
		//response.sendRedirect("/day09/adv.html");
		response.sendRedirect("/day10/GetDataServlet");

 

                          总结:

                                   Servlet编程:

                                            Servlet生命周期(重点)

                                            其他都是应用的东西(敲代码练习)

DAY11 

1 课程回顾

Servlet编程

          1)Servlet生命周期(重点)

                  构造方法: 创建servlet对象。默认情况下,第一次访问servlet对象时。只调用1次。

                  init方法(有参): 创建完servlet对象后调用。只调用1次。

                                   注意: 会调用无参的init方法。

                  service方法: servlet提供服务的方法。每次发出请求调用。

                                   注意: request对象 ,response对象

                  destroy方法: tomcat服务器停止或web应用重新部署,servlet对象销毁,destroy方法被调用。

         2)ServletConfig对象

                          获取servlet的初始化参数:

                                   getInitParameter("name ");

                                   getInitParameterNames();

         3)ServletContext对象

                          得到web应用路径:

                                            context.getContextPath();

                                            request.getContextPath();  等价于上面的代码

                          得到web应用参数:

                                            context.getInitParameter("name");

                                            context.getInitParameterNames();

                          域对象:

                                            context.setAttribute("name",Object): 保存数据

                                            context.getAttribute("name")   得到数据

                                            context.removeAttribue("name")  清除数据

                          转发

                                            context.getRequestDispatcher("路径").forward(request,response);

                                            request.getRequestDispacher("路径").forward(request,response);  等价于上面的代码

                          得到web应用中的资源文件

                                            context.getRealPath("路径")

                                            context.getResourceAsStream("路径");

 

今天的目标: 会话管理

会话管理: 管理浏览器客户端 服务器端之间会话过程中产生的会话数据。

                          域对象: 实现资源之间的数据共享。

                          request域对象

                          context域对象             

                  登录场景:

                小张: 输入“张三” (保存数据: context.setAttribute("name","张三")) -> 用户主页(显示“张三”)

              小李: 输入“李四”(保存数据:context.setAttribute("name","李四")) ->   用户主页(显示“李四”)

 

                      问题: context是所有用户公有的资源!!!会覆盖数据。

             小张: 输入“张三”(保存数据: request.setAttribute("name","张三"))- > 用户主页(显示“张三”)   问题: 一定要使用转发技术来跳转页面!!!

            解决办法: 可以使用session域对象来保存会话数据!!!

2.3 会话技术

                          Cookie技术:会话数据保存在浏览器客户端。

                          Session技术:会话数据保存在服务器端。

3 Cooke技术

                          3.1 特点

                          Cookie技术:会话数据保存在浏览器客户端。

                          3.2 Cookie技术核心

                          Cookie类:用于存储会话数据

 

                                   1)构造Cookie对象

                                            Cookie(java.lang.String name, java.lang.String value)

                                   2)设置cookie

                                            void setPath(java.lang.String uri)   :设置cookie的有效访问路径

                                            void setMaxAge(int expiry) : 设置cookie的有效时间

                                            void setValue(java.lang.String newValue) :设置cookie的值

                                   3)发送cookie到浏览器端保存

                                            void response.addCookie(Cookie cookie)  : 发送cookie

                                   4)服务器接收cookie

                                            Cookie[] request.getCookies()  : 接收cookie

package gz.itcast.b_resource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 读取web应用下的资源文件(例如properties)
 * @author APPle
 */
public class ResourceDemo extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/**
		 *  . 代表java命令运行目录。java运行命令在哪里?? 在tomcat/bin目录下
		 *   结论: 在web项目中, . 代表在tomcat/bin目录下开始,所以不能使用这种相对路径。
		 */
		
		
		//读取文件。在web项目下不要这样读取。因为.表示在tomcat/bin目录下
		/*File file = new File("./src/db.properties");
		FileInputStream in = new FileInputStream(file);*/
		
		/**
		 * 使用web应用下加载资源文件的方法
		 */
		/**
		 * 1. getRealPath读取,返回资源文件的绝对路径
		 */
		/*String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
		System.out.println(path);
		File file = new File(path);
		FileInputStream in = new FileInputStream(file);*/
		
		/**
		 * 2. getResourceAsStream() 得到资源文件,返回的是输入流
		 */
		InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
		
		
		Properties prop = new Properties();
		//读取资源文件
		prop.load(in);
		
		String user = prop.getProperty("user");
		String password = prop.getProperty("password");
		System.out.println("user="+user);
		System.out.println("password="+password);
		
	}

}
package gz.itcast.c_cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 第一个cookie的程序
 * @author APPle
 *
 */
public class CookieDemo1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//1.创建Cookie对象
		Cookie cookie1 = new Cookie("name","eric");
		//Cookie cookie2 = new Cookie("email","jacky@qq.com");
		//Cookie cookie1 = new Cookie("email","eric@qq.com");
		
		
		/**
		 * 1)设置cookie的有效路径。默认情况:有效路径在当前web应用下。 /day11
		 */
		//cookie1.setPath("/day11");
		//cookie2.setPath("/day12");
		
		/**
		 * 2)设置cookie的有效时间
		 * 正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
			负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
			零:表示删除同名的cookie数据

		 */
		//cookie1.setMaxAge(20); //20秒,从最后不调用cookie开始计算
		cookie1.setMaxAge(-1); //cookie保存在浏览器内存(会话cookie)
		//cookie1.setMaxAge(0);
		
		
		//2.把cookie数据发送到浏览器(通过响应头发送: set-cookie名称)
		//response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()+",email=eric@qq.com");
		//推荐使用这种方法,避免手动发送cookie信息
		response.addCookie(cookie1);
		//response.addCookie(cookie2);
		//response.addCookie(cookie1);
		

		
		//3.接收浏览器发送的cookie信息
		/*String name = request.getHeader("cookie");
		System.out.println(name);*/
		Cookie[] cookies = request.getCookies();
		//注意:判断null,否则空指针
		if(cookies!=null){
			//遍历
			for(Cookie c:cookies){
				String name = c.getName();
				String value = c.getValue();
				System.out.println(name+"="+value);
			}
		}else{
			System.out.println("没有接收cookie数据");
		}
		
	}

}

3.3 Cookie原理

                                   1)服务器创建cookie对象,把会话数据存储到cookie对象中。

                                                     new Cookie("name","value");

                                   2)  服务器发送cookie信息到浏览器

                                                     response.addCookie(cookie);

                                                     举例: set-cookie: name=eric  (隐藏发送了一个set-cookie名称的响应头)

                                   3)浏览器得到服务器发送的cookie,然后保存在浏览器端。

                                   4)浏览器在下次访问服务器时,会带着cookie信息

                                                举例: cookie: name=eric  (隐藏带着一个叫cookie名称的请求头)

                                   5)服务器接收到浏览器带来的cookie信息

                                                     request.getCookies();

3.4 Cookie的细节

                          1)void setPath(java.lang.String uri)   :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。                      

                          2)void setMaxAge(int expiry) : 设置cookie的有效时间。

                                       正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。

                                       负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!

                                       零:表示删除同名的cookie数据

                          3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

4 Session技术

                          4.1 引入

                          Cookie的局限:

                                   1)Cookie只能存字符串类型。不能保存对象

                                   2)只能存非中文。

                                   3)1个Cookie的容量不超过4KB。

                          如果要保存非字符串,超过4kb内容,只能使用session技术!!!

                          Session特点:

                                            会话数据保存在服务器端。(内存中)

4.2 Session技术核心

                          HttpSession类:用于保存会话数据

                           1)创建或得到session对象

                                   HttpSession getSession() 

                                   HttpSession getSession(boolean create) 

                          2)设置session对象

                                   void setMaxInactiveInterval(int interval)  设置session的有效时间

                                   void invalidate()      销毁session对象

                                   java.lang.String getId()  得到session编号

                          3)保存会话数据到session对象

                                   void setAttribute(java.lang.String name, java.lang.Object value)  保存数据

                                   java.lang.Object getAttribute(java.lang.String name)  获取数据

                                   void removeAttribute(java.lang.String name) 清除数据

4.3 Session原理

                                   问题: 服务器能够识别不同的浏览者!!!

                          现象:

            前提: 在哪个session域对象保存数据,就必须从哪个域对象取出!!!!

                          浏览器1:(给s1分配一个唯一的标记:s001,把s001发送给浏览器)

                                            1)创建session对象,保存会话数据

                                                              HttpSession session = request.getSession();   --保存会话数据 s1

                          浏览器1 的新窗口(带着s001的标记到服务器查询,s001->s1,返回s1) 

                                            1)得到session对象的会话数据

                                                         HttpSession session = request.getSession();   --可以取出  s1

                          新的浏览器1:(没有带s001,不能返回s1)

                                            1)得到session对象的会话数据

                                               HttpSession session = request.getSession();   --不可以取出  s2

                          浏览器2:(没有带s001,不能返回s1)

                                            1)得到session对象的会话数据

                                                         HttpSession session = request.getSession();  --不可以取出  s3                         

                          代码解读:HttpSession session = request.getSession();                                  

                          1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID

                                            new HttpSession();

                          2)把JSESSIONID作为Cookie的值发送给浏览器保存

                                            Cookie cookie = new Cookie("JSESSIONID", sessionID);

                                            response.addCookie(cookie);

                          3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器

                          4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。

                                            if(找到){

                                                     return map.get(sessionID);

                                            }

                                            Map<String,HttpSession>]

                                            <"s001", s1>

                                            <"s001,"s2>

                          5)如果找到对应编号的session对象,直接返回该对象

                          6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程        

                           结论:通过JSESSIONcookie值在服务器找session对象!!!!!

         4.4 Sesson细节

                           1)java.lang.String getId()  : 得到session编号

                          2)两个getSession方法:

                       getSession(true) / getSession()  : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。

                          getSession(false):              得到session对象。没有匹配的session编号,返回null

                           3)void setMaxInactiveInterval(int interval)  : 设置session的有效时间

                                                     session对象销毁时间:

                                                             3.1 默认情况30分服务器自动回收

                                                             3.2 修改session回收时间

                                                             3.3 全局修改session有效时间

<!-- 修改session全局有效时间:分钟 -->
	<session-config>
		<session-timeout>1</session-timeout>
	</session-config>

3.4.手动销毁session对象

                             void invalidate()     : 销毁session对象

                          4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题

            

/**
		 * 手动发送一个硬盘保存的cookie给浏览器
		 */
		Cookie c = new Cookie("JSESSIONID",session.getId());
		c.setMaxAge(60*60);
		response.addCookie(c);

      

总结:

                                   1)会话管理: 浏览器和服务器会话过程中的产生的会话数据的管理。

                                   2)Cookie技术:

                                                     new Cookie("name","value")

                                                     response.addCookie(coookie)

                                                     request.getCookies()

                                    3)Session技术

                                                     request.getSession();                                              

                                                     setAttrbute("name","会话数据");

                                                     getAttribute("会话数据")

                         

 

 

 

转载于:https://my.oschina.net/u/3299202/blog/3057229

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值