一 . Tomcat
1.对Tomcat的理解
Tomcat是一个运行JAVA的网络服务器,提供能够让别人访问自己写的页面的一个程序,是JSP和Serlvet的一个容器。
2.Tomcat的配置
两种方式,解压压缩包(配环境变量)、直接安装(不用配环境变量);
二 . Http
1.对http协议的理解
超文本传输协议,它是TCP/IP协议的一个应用层协议。HTTP协议就是客户端和服务器 交互的一种通迅的格式。
2.http请求
2.1请求行
请求行中的GET称之为请求方式,请求方式有:POST、GET、HEAD、OPTIONS、DELETE、TRACE、PUT
常用的有:POST,GET一般来说,当我们点击超链接,通过地址栏访问都是get请求方式。通过表单提交的数据一般是post方式。可以简单理解GET方式用来查询数据,**POST方式用来提交数据,get的提交速度比post快GET方式:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。POST方式:可以在请求的实体内容中向服务器发送数据,传送的数据量无限制。
2.2请求头
Accept: text/html,image/* 【浏览器告诉服务器,它支持的数据类型】
Accept-Charset: ISO-8859-1 【浏览器告诉服务器,它支持哪种字符集】
Accept-Encoding: gzip,compress 【浏览器告诉服务器,它支持的压缩格式】
Accept-Language: en-us,zh-cn 【浏览器告诉服务器,它的语言环境】
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【浏览器告诉服务器,带来的Cookie是什么】
Connection: close/Keep-Alive 【浏览器告诉服务器,请求完后是断开链接还是保持链接】
Date: Tue, 11 Jul 2000 18:23:51 GMT【浏览器告诉服务器,请求的时间】
3.http响应(状态行、响应头、空行、实体内容)
3.1状态行
3.2响应头
Location: http://www.it315.org/index.jsp 【服务器告诉浏览器要跳转到哪个页面】
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 【服务器告诉浏览器连接方式】
Date: Tue, 11 Jul 2000 18:23:51 GMT【服务器告诉浏览器回送数据的时间】
三 . Servlet
1.对Serlvet的理解
是一个遵循Servlet开发的java类。Serlvet是由服务器调用的,运行在服务器端,能够处理浏览器带来HTTP请求,并返回一个响应给浏览器,从而实现浏览器和服务器的交互。
2.Servlet生命周期
加载Servlet。当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
初始化(init)。当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
处理服务(service)。当浏览器访问Servlet的时候,Servlet会调用service()方法处理请求
销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
卸载。当Servlet调用完destroy()方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作。
简单总结:只要访问Servlet,service()就会被调用。init()只有第一次访问Servlet的时候才会被调用 ,destroy()只有在Tomcat关闭时调用 。
3.Servlet细节
3.1 一个已经注册的Servlet可以被多次映射(一个servlet 映射到多个URL)
3.2 servlet 映射的URL可以使用通配符
*.扩展名 (*.jsp 匹配jsp页面)//优先级低
正斜杠(/)开头并以“/*”结尾。(/* 匹配所有界面)
3.3 servlet 是单例模式
浏览器多次对Servlet的请求,一般情况下,服务器只创建一个Servlet对象,也就是说,Servlet对象一旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。
3.4 servlet 之间通讯(ServletContext的setAttribute(String name,Object obj)方法)
4.Servlet之 response
(HttpServletResponse(封装http响应的信息))
4.1 调用getOutputStream()向浏览器输出数据,输出二进制格式的数据。
(1)print()不能输出中文(Tomcat以ISO 8859-1编码对中文编码)
(2)输出中文:response.getOutputStream().write("你好".getBytes());
(3)为了保证通用性,使用UTF-8编码
//设置头信息,告诉浏览器我回送的数据编码是utf-8的
response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.getOutputStream().write("你好".getBytes("UTF-8"));
4.2 调用getWrite() 方法向浏览器输出数据 ,只能输出字符数据,不能输出二进制数据。
(1)response.setContentType("text/html;charset=UTF-8");//解决输出中文乱码问题
4.3 getWriter和getOutputStream细节
(1)getWriter()和getOutputStream()两个方法不能同时调用。如果同时调用就会出现异常
(2)Servlet的serice()方法结束后【也就是doPost()或者doGet()结束后】,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象.
4.4 实现文件下载(以下是步骤)
(1)保证站点有此图片
(2)写一个Servlet,当别人访问我这个Servlet的时候,它们就可以下载我这个图片了
(3)java的文件上传下载都是通过io流来完成的,既然要下载图片,首先要能够读取到它
//获取到资源的路径
String path =this.getServletContext().getRealPath("/download/1.png");
//读取资源
FileInputStream fileInputStream =newFileInputStream(path);
//获取到文件名,路径在电脑上保存是\\形式的。
String fileName = path.substring(path.lastIndexOf("\\") +1);
告诉浏览器,我要下载这个文件
//设置消息头,告诉浏览器,我要下载1.png这个图片
response.setHeader("Content-Disposition","attachment; filename="+fileName);
将读取到的内容回送给浏览器
//把读取到的资源写给浏览器
intlen =0;
byte[] bytes =newbyte[1024];
ServletOutputStream servletOutputStream = response.getOutputStream();
while((len = fileInputStream.read(bytes)) >0) {
servletOutputStream.write(bytes,0, len);
}
//关闭资源
servletOutputStream.close();
fileInputStream.close();
(4)访问浏览器就提示下载了。
(5)解决文件名是中文时的乱码问题:为了解决文件名乱码,我们要进行URL编码:
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
4.5 实现自动刷新
(1)response.setHeader("Refresh", "3"); // 3秒刷新一次
4.6 设置缓存
(1)浏览器本身就存在着缓存机制,禁止缓存功能:
//浏览器有三消息头设置缓存,为了兼容性!将三个消息头都设置了
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
//这里为了看效果
PrintWriter printWriter = response.getWriter();
printWriter.print("你好啊"+newDate().toString());
4.7 重定向跳转
(1) response.sendRedirect("/zhongxiang/index.jsp");
5.Servlet之 request
(HttpServletRequest(客户端的请求))
5.1 防盗链
(获取Referer消息头,判断是不是从我的首页来的。不是则跳转回首页。)
String referer = request.getHeader("Referer");//获取到网页是从哪里来的
if ( referer == null || !referer.contains("localhost:8080/herewell/index.jsp") ) {
response.sendRedirect("/herewell/index.jsp");}
5.2 表单提交数据,获取要提交的值
request.setCharacterEncoding("UTF-8"); //设置request字符编码的格式
String username = request.getParameter("username");//输入框和文本框一个值,获取到一个值
String[] hobbies = request.getParameterValues("hobbies"); //复选框下拉框有多个值,获取到多个值
5.3 解决中文乱码问题(Tomcat以ISO 8859-1编码对中文编码)
1. request.setCharacterEncoding("UTF-8");//post 解决乱码,因为post消息封装到了request中
2. get方法它的数据是从消息行带过去的,没有封装到request对象里,使用request设置编码无效。
String name = request.getParameter("username");//此时是被ISO 8859-1编码的字符串,乱码
byte[] bytes = name.getBytes("ISO8859-1");//乱码通过反向查ISO 8859-1得到原始的数据
String value = new String(bytes, "UTF-8");//通过原始的数据,设置正确的码表,构建字符串
6.Cookie
6.1 Cookie 定义:
给每一个用户都发一个通行证,无论谁访问的时候都需要携带通行证,这样服务器就可以从通行证上确认用户的信息。通行证就是Cookie
6.2 Cookie的流程:
浏览器访问服务器,如果服务器需要记录该用户的状态,就使用response向浏览器发送一个Cookie,浏览器会把Cookie保存起来。当浏览器再次访问服务器的时候,浏览器会把请求的网址连同Cookie一同交给服务器。
6.3 Cookie API
Cookie类用于创建一个Cookie对象
response接口中定义了一个addCookie方法,用于在其响应头中增加一个相应的Set-Cookie头字段
request接口中定义了一个getCookies方法,用于获取客户端提交的Cookie
常用的Cookie方法:
- public Cookie(String name,String value)
- setValue与getValue方法
- setMaxAge与getMaxAge方法//设置Cookie的时间
- setPath与getPath方法
- setDomain与getDomain方法
- getName方法
6.4 Cookie细节
1.Cookie不可跨域名性
Cookie具有不可跨域名性。浏览器判断一个网站是否能操作另一个网站的Cookie的依据是域名。所以一般来说,当我访问baidu的时候,浏览器只会把baidu颁发的Cookie带过去,而不会带上google的Cookie。
2.Cookie保存中文
2.1 Cookie使用Unicode字符时需要对Unicode字符进行编码。
Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));
2.2 在取出Cookie的时候要对中文数据进行解码
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
String name = cookies[i].getName();
String value = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
printWriter.write(name + "------" + value);}
3.Cookie的有效期(setMaxAge()来设置)
3.1 如果MaxAge为正数,浏览器会把Cookie写到硬盘中,只要还在MaxAge秒之前,登陆网站时该Cookie就有效
3.2 如果MaxAge为负数,**Cookie是临时性的,仅在本浏览器内有效,关闭浏览器Cookie就失效了,Cookie不会写到硬盘中。Cookie默认值就是-1。
3.3 如果MaxAge为0,则表示删除该Cookie。
4.Cookie的修改和删除
4.1 修改cookie
Cookie的名称相同,通过response添加到浏览器中,会覆盖原来的Cookie。
Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));
4.2 删除cookie
把MaxAge设置为0,并添加到浏览器中即可
cookie.setMaxAge(0);
response.addCookie(cookie)
注意:
删除,修改Cookie时,新建的Cookie除了value、maxAge之外的所有属性都要与原Cookie相同。否则浏览器将视为不同的Cookie,不予覆盖,导致删除修改失败!
5.Cookie的域名(domain属性决定运行访问Cookie的域名)
cookie.setDomain(".herewell.com");
6.Cookie的路径(path属性决定允许访问Cookie的路径)
一般地,Cookie发布出来,整个网页的资源都可以使用。现在我只想Servlet1可以获取到Cookie,其他的资源不能获取。
cookie.setPath("/Servlet1");
7.Cookie的安全属性
设置Cookie的secure属性为true,浏览器只会在HTTPS和SSL等安全协议中传输该Cookie。
7.Session
7.1 Session定义:
Session保存在服务器中。用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录在服务器,这就是Session
Session比Cookie使用方便,Session可以解决Cookie解决不了的事情【Session可以存储对象,Cookie只能存储字符串。】
7.2 Session API
long getCreationTime();【获取Session被创建时间】
String getId();【获取Session的id】
long getLastAccessedTime();【返回Session最后活跃的时间】
ServletContext getServletContext();【获取ServletContext对象】
void setMaxInactiveInterval(int var1);【设置Session超时时间】
int getMaxInactiveInterval();【获取Session超时时间】
Object getAttribute(String var1);【获取Session属性】
Enumeration getAttributeNames();【获取Session所有的属性名】
void setAttribute(String var1, Object var2);【设置Session属性】
void removeAttribute(String var1);【移除Session属性】
void invalidate();【销毁该Session】
boolean isNew();【该Session是否为新的】
7.3 Session作为域对象(传值)
只要Session对象没有被销毁,Servlet之间就可以通过Session对象实现通讯
HttpSession httpSession = request.getSession(); //得到Session对象
httpSession.setAttribute("name", "蔬菜!!"); //设置Session属性
String value = (String) httpSession.getAttribute("name");//在其他servlet获取传递的数据
7.4 Session的生命周期和有效期
1.Session在用户第一次访问服务器Servlet,jsp等动态资源就会被自动创建,Session对象保存在内存里
2.无论是否对Session进行读写,服务器都会认为Session活跃了一次。(最后一次)
3.为防止内存溢出,服务器会把长时间没活跃的Session从内存中删除,这个就是Session的超时时间。
4.Session的超时时间默认是30分钟,有三种方式可以对Session的超时时间进行修改
(1)在tomcat/conf/web.xml文件中设置,时间值为20分钟,所有的WEB应用都有效
(2)在单个的web.xml文件中设置,对单个web应用有效,如果有冲突,以自己的web应用为准。
(3)通过setMaxInactiveInterval()方法设置
7.5 Session的实现原理
HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一个用户。于是乎:服务器向用户浏览器发送了一个名为JESSIONID的Cookie,它的值是Session的id值。其实Session依据Cookie来识别是否是同一个用户。
简单来说:Session之所以可以识别不同的用户,依靠的就是Cookie
该Cookie是服务器自动颁发给浏览器的,不用我们手工创建的。该Cookie的maxAge值默认是-1,也就是说仅当前浏览器使用,不将该Cookie存在硬盘中
我理解的:每次连接服务器都会生成一个JESSIONID,他就是服务器自动颁发的cookie,cookie的默认maxAge是-1,过了cookie的时效期,就要重新连接服务器请求新的JESSIONID
7.6 Session禁用Cookie
1.禁用自己项目的Cookie(META-INF文件夹下context.xml)
2. 禁用全部web应用的Cookie( 在conf/context.xml中修改)
7.7 利用Session防止表单重复提交
1.常见的重复提交
- 在处理表单的Servlet中刷新。
- 后退再提交
- 网络延迟,多次点击提交按钮
2.session 处理
-判断Session域对象的数据和jsp隐藏域提交的数据是否对应。
-判断隐藏域的数据是否为空【如果为空,就是直接访问表单处理页面的Servlet】
-判断Session的数据是否为空【servlet判断完是否重复提交,最好能立马移除Session的数据,如果Session域对象数据为空,证明已经提交过数据了!】
向Session域对象存入的数据是一个随机数【Token--令牌】(生成的一个独一无二的随机数)。
实现原理:
在session域中存储一个token
然后前台页面的隐藏域获取得到这个token
在第一次访问的时候,我们就判断seesion有没有值,如果有就比对。对比正确后我们就处理请求,接着就把session存储的数据给删除了
等到再次访问的时候,我们session就没有值了,就不受理前台的请求了!
7.8 Session和Cookie的区别
从存储方式上比较
Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。
Session可以存储任何类型的数据,可以把Session看成是一个容器
从隐私安全上比较
Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。
从有效期上比较
Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。
从对服务器的负担比较
Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。
从浏览器的支持上比较
如果浏览器禁用了Cookie,那么Cookie是无用的了!
如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。
从跨域名上比较
Cookie可以设置domain属性来实现跨域名
Session只在当前的域名内有效,不可夸域名
7.9 Cookie和Session共同使用
1.创建Cookie,Cookie的值是Session的id返回给浏览器
2.在server.xml文件中配置,将每个用户的Session在服务器关闭的时候序列化到硬盘或数据库上保存(不常用)
参考资料: Java3Y公众号