Java基础ArrayList、Servlet与Filter
一、技术分享
迭代器(Iterator)
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
迭代器应用:
list l = new ArrayList();
l.add("aa");
l.add("bb");
l.add("cc");
for (Iterator iter = l.iterator(); iter.hasNext();) {
String str = (String)iter.next();
System.out.println(str);
}
/*迭代器用于while循环
Iterator iter = l.iterator();
while(iter.hasNext()){
String str = (String) iter.next();
System.out.println(str);
}
*/
ArrayList
1、什么是ArrayList
ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处:
动态的增加和减少元素
实现了ICollection和IList接口
灵活的设置数组的大小
2、如何使用ArrayList
最简单的例子:
ArrayList List = new ArrayList();
for( int i=0;i <10;i++ ) //给数组增加10个Int元素
List.Add(i);
//..程序做一些处理
List.RemoveAt(5);//将第6个元素移除
for( int i=0;i <3;i++ ) //再增加3个元素
List.Add(i+20);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));//返回ArrayList包含的数组
这是一个简单的例子,虽然没有包含ArrayList所有的方法,但是可以反映出ArrayList最常用的用法
3、ArrayList重要的方法和属性
1)构造器
ArrayList提供了三个构造器:
public ArrayList();
默认的构造器,将会以默认(16)的大小来初始化内部的数组
public ArrayList(ICollection);
用一个ICollection对象来构造,并将该集合的元素添加到ArrayList
public ArrayList(int);
用指定的大小来初始化内部的数组
2)IsSynchronized属性和ArrayList.Synchronized方法
IsSynchronized属性指示当前的ArrayList实例是否支持线程同步,而ArrayList.Synchronized静态方法则会返回一个ArrayList的线程同步的封装。
如果使用非线程同步的实例,那么在多线程访问的时候,需要自己手动调用lock来保持线程同步,例如:
ArrayList list = new ArrayList();
//...
lock( list.SyncRoot ) //当ArrayList为非线程包装的时候,SyncRoot属性其实就是它自己,但是为了满足ICollection的SyncRoot定义,这里还是使用SyncRoot来保持源代码的规范性
{
list.Add( “Add a Item” );
}
如果使用ArrayList.Synchronized方法返回的实例,那么就不用考虑线程同步的问题,这个实例本身就是线程安全的,实际上ArrayList内部实现了一个保证线程同步的内部类,ArrayList.Synchronized返回的就是这个类的实例,它里面的每个属性都是用了lock关键字来保证线程同步。
3)Count属性和Capacity属性
Count属性是目前ArrayList包含的元素的数量,这个属性是只读的。
Capacity属性是目前ArrayList能够包含的最大数量,可以手动的设置这个属性,但是当设置为小于Count值的时候会引发一个异常。
4)Add、AddRange、Remove、RemoveAt、RemoveRange、Insert、InsertRange
这几个方法比较类似
Add方法用于添加一个元素到当前列表的末尾
AddRange方法用于添加一批元素到当前列表的末尾
Remove方法用于删除一个元素,通过元素本身的引用来删除
RemoveAt方法用于删除一个元素,通过索引值来删除
RemoveRange用于删除一批元素,通过指定开始的索引和删除的数量来删除
Insert用于添加一个元素到指定位置,列表后面的元素依次往后移动
InsertRange用于从指定位置开始添加一批元素,列表后面的元素依次往后移动、
二、转发和重定向
if (username.equals("yangmin")&&password.equals("123456"))
{
//演示转发请求
request.getRequestDispatcher("/success.jsp").forward(request,response);
//通过请求request获取请求转发器
//在请求转发器中设置要转发的位置
//调用请求转发器的forward()方法进行转发
//转发时,把request和response传递给下一个页面(Servlet或JSP)
//转发 成功时,响应状态码通常是200
//转发时,浏览器不知道最终是哪个页面(地址)返回了响应
//经常表现 为浏览器的地址不变化或者与真实地址不同
}else {
//演示重定向【响应】
response.sendRedirect(request.getContextPath() +"/fail.jsp");
//通过response的sendRedirect()方法发送一个重定向响应
//sendRedirect方法会把响应状态设置为301、302
//还会添加Location头,Location头的值就是参数指定的重定向的地址
//重定向成功时,响应状态码为301(永久地移动到其他位置)、302(临时重定向到一个位置)
//浏览器的地址栏会变化,能看到最终是哪个页面(servlet或jsp)返回了HTML
}
三、如何附加Tomcat源代码
方法一、
随便找一个Servlet类,按F3找它的定义,在弹出的页面上点击“Attach Source”按钮,在弹出的按钮上选择源代码所在的位置即可(通常选择external
files)
方法二、
在项目视图java Resources里面的Libraries找到Apache Tomcat展开,找到servlet-api.jar右键properties,属性,java
Source Attachment
选择源代码位置
四、Servlet
接口
接口定义
关键词:interface
在java中,接口是一种特殊类型
可以在接口中声明一些属性和方法
声明的方法可以不实现(类似于抽象方法)
接口的实现
其他类可以选择实现某个接口,或者某一些接口
格式: implements
接口名1,接口名2,接口名3.....
实现接口通常意味着要实现接口规定的方法和属性
接口对于程序设计的意义
1》接口是给设计师使用的工具
2》目的是规范程序代码,保证编码者实现统一设计意图
(不实现接口指定的方法,或者方法签名走样就会报错)
3》接口是一个约定,方便双方或多方合作
可以使各方写的类能够相互找到并调用
比如Tomcat是一种通用的网络程序,它只能处理网络和协议的功能
但是不懂客户的业务逻辑
此时就需要第三方开发者实现具体的业务逻辑
实现之后Tomcat怎么调用开发者实现的方法呢?
解决的方法就是大家商量并定义一个接口
开发者实现这个接口
、 Tomcat调用这个接口
注意:继承只能写一个,因为java是单继承的,但是可以实现多个接口
Servlet
1. 是一个接口
2. 是开发者和Tomcat的约定
3. init 初始化Servlet
4. getServletConfig 返回配置信息
5. getServletInfo 返回描述 信息
6. service 处理请求的一手方法
7. destory 销毁
获取协议
String protocol = req.getProtocol();
HttpServlet
继承自 -->GenericServlet-->实现了Servlet, ServletConfig,java.io.Serializable接口
HttpServlet是抽象类
它实现了基本的HTTP协议
支持GET、HEAD、TRACE、PUT、POST、OPTIONS、DELETE
GET 获取资源
POST 新增资源
PUT 修改资源
DELETE 删除资源
基本实现了对资源的增删改查操作
GET请求支持If-Modified-Sence缓存检查机制(如果有缓存状态码会使304)
Head不会返回响应体
TRACE 将请求头信息收集到响应体中返回
OPTIONS 返回了所支持的请求方法(子类实现几个doXXX就返回几个doXXX)
其他请求默认返回Not_Alloweed,所以子类实现相应方法时
不用调用super.doXXX()
service 方法会检查请求报文中的请求方法 request.getMethod()
根据请求
方法将请求转发给doXXX方法处理
所以service方法只是简单实现了调度作用
GenericServlet 几乎什么都没干
创建servlet时对话框
Name --><servlet-name>
Description --> <description> Servlet 处理什么请求、特殊注意事项
Initialization Parameters --> <init-param> 传入Servlet类的参数
URL mappings --> <url-pattern> 映射到Servlet类的URL,可以指定多个
<url-pattern>的几种写法
精确匹配 /api/user/login , /admin/user
后缀名 *.jsp *.action *.do
路径 /admin/* 凡是/admin/开头的都匹配
/* 所有请求
缺省 / 当其他匹配没有成功时,交给这个映射处理
注意:每一个服务都是由一个引擎和连接器组成的
应用路径
一个应用对应一个Dynamic Web Project
应用路径不是固定的
在开发阶段,通过Eclipse可以改变它,Context root
在生产环境,由部署位置或配置决定
所以应用路径在源代码(包括JSP、Servlet)中不能写死!!
如果在jsp中,优先使用<c:url value =“/login”/>
如果在java代码中(Servlet)中
使用request.getContextPath()获取
五、Session
session的工作原理
(1)当一个session第一次被启用时,一个唯一的标识被存储于本地的cookie中。
(2)首先使用session_start()函数,PHP从session仓库中加载已经存储的session变量。
(3)当执行PHP脚本时,通过使用session_register()函数注册session变量。
(4)当PHP脚本执行结束时,未被销毁的session变量会被自动保存在本地一定路径下的session库中,这个路径可以通过php.ini文件中的session.save_path指定,下次浏览网页时可以加载使用。
Session图解
Session 是一个跨页(Servlet、jsp)面的数据共享机制
Session默认存储在内存中。当应用分布式部署到多台服务器,首先要解决的就是Session问题
Session 通过javax.servlet.http.HttpSession实现
常用的方法
1》setAttribute(key,value) 把数据(基本类型或对象)存储到session中
2》getAttribute(key) 获取session值,返回类型是Object
强制转换后才可以方便使用
3》removeAttribute(key) 删除指定的session值
4》invalidate() 清除所有的session(让所有的session值都失效)
在JSP中获取session值
方法1:使用<% session.getAttribute(key) %> JSP代码块
<%%>代码块,它可以让你把java代码和html混写在一块
Session内置对象,可以在页面上直接通过session对象访问session
方法2:使用EL表达式 ${sessionScope.key}
EL表达式是为了简化对内置对象中的数据的访问、
JSP有九大内置对象,四大作用域
关于九大内置对象,四大作用域的详解
request 请求对象 类型javax.servlet.ServletRequest 作用域Request
response 响应对象 类型javax.servlet.SrvletResponse 作用域Page
pageContext 页面上下文对象 类型javax.servlet.jsp.PageContext 作用域Page
session 会话对象 类型javax.servlet.http.HttpSession 作用域Session
application 应用程序对象 类型javax.servlet.ServletContext 作用域Application
out 输出对象 类型javax.servlet.jsp.JspWriter 作用域Page
config 配置对象 类型javax.servlet.ServletConfig 作用域Page
page 页面对象 类型javax.lang.Object 作用域Page
exception 例外对象 类型javax.lang.Throwable 作用域page
“exception” 对象则代表了JSP文件运行时所产生的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了“<%@
page isErrorPage="true "%>”的JSP文件中使用。
何为作用域
先让我们看看效果:
大概流程是这样的,我们访问index.jsp的时候,分别对pageContext, request, session,application四个作用域中的变量进行累加。(当然先判断这个变量是不是存在,如果变量不存在,则要把变量初始化成1)。计算完成后就从index.jsp执行forward跳转到test.jsp。在test.jsp里再进行一次累加,然后显示出这四个整数来。
从显示的结果来看,我们可以直观的得出结论:
page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,它们就不见了。
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
session和application里的变量一直在累加,开始还看不出区别,只要关闭浏览器,再次重启浏览器访问这页,session里的变量就重新计算了。
application里的变量一直在累加,除非你重启tomcat,否则它会一直变大。
作用域规定的是变量的有效期限
如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。
从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。
所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。
所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。
整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。
application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page,
request,session都是完全隔离的,无论如何修改都不会影响其他人的数据。
六、Sessionld
Session.getId() 可以获取SessionId
SessionId是一个随机字符串(随机数)
每次会话使用一个SessionId
在用户访问服务器的过程中,服务器会在某一次响应中通过Set-Cookie头向浏览器发送一个JSESSIONID。浏览器接到这个Cookie之后,会将之存储下来。以后每一次请求服务器时,都会通过Cookie头携带这个JSESSIONID
服务器通过JSESSIONID区分不同的用户
而且服务器端Session数据也被JSESSIONID分成不同的区域
通过session.setAttribute()及getAttribute等方法操作Session数据时,都只会在当前JSESSIONID关联的区域内操作。即,每个用户只能操作自己的Session区域
Cookie机制
服务器通过Set-Cookie响应头可以向浏览器设置Cookie
浏览器会将收到的Cookie保存下来
以后每次请求时都很通过Cookie头将Cookie发给服务器
Cookie可以设置保存时间(可以使绝对时间,也可是在浏览器关闭时清除)
Cookie可以设置域名(在本域名中有效,在其他域名中无法获取)-----Cookie不能跨域
Cookie可以设置路径(在本路径有效,在其他路径中无法获取)
Cookie可以区分协议,(可以设置Cookie只在https/http的协议中能获取)
如果浏览器不支持Cookie,Session难道就没法用了
浏览器不支持Cookie,或者程序员不选择通过Cookie保存JSESSIONID时
可以通过URL夹带JSESSIONID
七、Filter
Filter作用
Filter 可以在请求处理之前以及请求处理之后对请求或响应进行限制、加工、装换
比如:登录保护、保存日志、转换编码、业务统计、响应格式转换等.....
Filter是一个接口
三个方法:
1> init 初始化
2> doFilter 执行过滤
3> destory 销毁
Filter 和Servlet组成了一个链条chain
多个Filter时,谁的<filter-mapping>在web.xml的前面谁先执行
如果使用注解的话,按照名字的字母排序
通过Filter实现登录保护(用户身份验证)
登录叫身份认证
与权限相关的叫用户授权
步骤:
创建过滤器
在过滤器的前处理部分检查session中是否有用户数据
没有的话就是没有登录、
重定向到登录页
Return 停止后续处理
有数据就是已经登录
调用chain.doFilter继续处理
退出的实现
创建LogoutServlet
在doGet方法中
清除session数据
重定向的登录页
Java基础ArrayList、Servlet与Filter的更多相关文章
- Java基础——ArrayList
Java基础--ArrayList 作用:提供一个可变长度的集合,底层实际上是一个可变长度的数组 格式:ArrayList <E> arr=new ArrayList<>(); ...
- Java基础-ArrayList和LinkedList的区别
大致区别: 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为Lin ...
- Java基础——ArrayList与LinkedList(二)
今天练习ArrayList与LinkedList,在网上看到有关它俩应用效率的题型.觉得很有价值,保留一下. import java.util.ArrayList; import java.util. ...
- Java基础——ArrayList与LinkedList(一)
一.定义 ArrayList和LinkedList是两个集合类,用于储存一系列的对象引用(references). 引用的格式分别为: ArrayList<String> list = n ...
- JAVA基础篇—Servlet小结
一.get请求和post请求的区别: 1.get请求是通过url传递参数,post请求是通过请求体传递参数的 2.get请求最多允许传递255个字符,对长度有限制,所以数据比较大的时候我们使用post ...
- java基础: ArrayList集合应用, ArrayList增删改查详解,综合java基础实现学生管理系统,
1.ArrayList 集合和数组的区别 : 共同点:都是存储数据的容器 不同点:数组的容量是固定的,集合的容量是可变的 1.1 -ArrayList的构造方法和添加方法 public ArrayLi ...
- java基础篇---Servlet监听器
在写此篇前,看了一下园友写的,感觉其基础知识归纳的十分全面,我在此就不累赘的写了,链接地址(http://www.cnblogs.com/sherryueda/p/4273169.html), 我就写 ...
- java基础篇---Servlet过滤器
Servlet过滤器从字面上的字意理解为景观一层次的过滤处理才达到使用的要求,而其实Servlet过滤器就是服务器与客户端请求与响应的中间层组件,在实际项目开发中Servlet过滤器主要用于对浏览器的 ...
- Java基础 ArrayList源码分析 JDK1.8
一.概述 本篇文章记录通过阅读JDK1.8 ArrayList源码,结合自身理解分析其实现原理. ArrayList容器类的使用频率十分频繁,它具有以下特性: 其本质是一个数组,因此它是有序集合 通过 ...
随机推荐
- RPC服务框架dubbo(三):Dubbo支持的协议
1.Dubbo 1.1 Dubbo官方推荐的协议. 1.2 本质:使用NIO和线程池进行处理. 1.3 缺点:大文件传输时可能出现文件传输失败问题. 2.RMI 2.1 JDK提供的协议,远程方法调用 ...
- Ubuntu14.04下安装docker 1.9
有以下几种方式: 1. 通过系统自带包安装(可能不是最新版) $ sudo apt-get update $ sudo apt-get install -y docker.io $ sudo ln - ...
- 取得COM对象的UUID并以string输出
IID tmp = __uuidof(ClassLibrary1::Class1); OLECHAR * buf; StringFromIID(tmp, &buf); 好像要#include ...
- 【Android】13.4 使用SQLite.NET.Async-PCL访问SQLite数据库
分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 这一节演示如何利用以异步方式(async.await)访问SQLite数据库. 二.示例4运行截图 下面左图为初始 ...
- 利用GitHub Pages和Hexo搭建个人博客
本文首发地址: 非生异也 本项目源码托管在GitHub上 Why 阮一峰曾经说过:喜欢写Blog的人,会经历3个阶段. 第一阶段,刚接触Blog,觉得很新鲜,试着选择一个免费空间来写. 第二阶段,发现 ...
- Python 切片那些事
- python学习笔记(9)--Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法 这篇文章主要介绍了Python UnicodeEncodeErro ...
- python walk函数
os.walk方法 import os for i in os.walk(r'C:\Users\jack\Desktop\test\3_语文语文版七年级上册\1_一单元'): print(i[0]) ...
- lua工具库penlight--04路径和目录
使用路径 程序不应该依赖于奇葩的系统,这样你的代码会难以阅读和移植.最糟糕的是硬编码的路径, windows和Unix的路径分隔符正好相反.最好使用path.join,它可以帮助你解决这个问题. pl ...
- C++ 类的继承二(赋值兼容性原则)
//赋值兼容性原则 #include<iostream> using namespace std; class PointA{ public: PointA(){ x = ; y = ; ...