传智播客JavaWeb听课总结
一、 JavaWeb基础
第一天:
1.Eclipse详解:
(1).Bad versionnumber in .class file:编译器版本和运行(JRE)版本不符合。高的JRE版本兼容低版本的编译器版本。
(2).当程序有错误的时候,使用Debug as 运行程序。双击语句设置断点。程序运行到此处停止。点击跳入方法的内部代码。点击跳过,执行下一条代码,点击跳出,跳出方法。观察变量的值,选中变量右击 选择watch. 跳入下一个断点。查看断点,调试完后一定要清除断点。结束运行断点的jvm.
2.HashSet和hashCode和equals方法
java系统首先调用对象的hashCode()方法获得该对象的哈希吗,然后根据哈希吗找到相应的存储区域,最后取出该存储区域内的每个元素与该 元素进行比较.两个equals相等,hashCode()相等。需要重写equals,hashCode()方法.更改数据的值,hashCode() 的值也更改了,并未删除.内存泄露.有个东西不在被用,但是未被删除,导致内存泄露.
3.Junit测试框架
(1).在测试类,方法前加注解:@Test,不然出现初始化异常。
(2).方法before,after前加@Before,@After注解。在测试方法之前和之后运行方法。
(3).静态方法beforeClass,afterClass方法前加上注解@BeforeClass,@AfterClass,类加载的时候运行
(4).Assert断言。判断两个对象是否相等。期望值和实际值相等。
4.得到配置文件的路径
通过类加载器 reflect.class.getClassLoader.getResourceAsStream();在class指定目录下查找指定的类文件进行 加载.编译器把src中的.java文件编译成class文件,所有非.java文件,原封不动的搬过去.但是这种方法是只读的.
通过类的信息reflect.class.getResourceAsStream();相对路径
一般用绝对路径,使用配置文件告诉用户路径.
一定要记住要用完整的路径,但是完整的路径不是硬编码的,是计算出来的.
5.反射
(1).反射主要用于框架开发
(2).一个类有多个组成部分,例如:成员变量,方法,构造方法等,反射就是加载类,并解析类的各个组成部分。
(3).加载类使用Class.forName()静态方法,给类的完整名称,包名和类名。
(4).Class提供了解析public的构造方法,方法,字段等方法以及private。字段封装数据,方法执行功能
(5).静态方法无需传递对象,method.invoke()
(6).升级时保持兼容性,main函数的解析有点麻烦,反射解析数组参变量的时候的问题。启动Java程序的main方法的参数是一个字符串数 组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按照jdk1.5的语法,整个数组是一个参数,而按照 jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理 呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成若干个单独的参数。所以,在给main方法传递参数时, 不能使用代码mainMethod.invoke(null,newString[]{“xxx”}),javac只把它当做jdk1.4的语法进行理 解,而不把它当做jdk1.5的语法解释,因此会出现参数类型不对的问题。解决的方法:
mainMethod.invoke(null,newObject[]{new String[]{“xxx”}});
mainMethod.invoke(null,(Object)newString[]{“xxx”});编译器会做特殊处理,编译时不把参数当做数组看待,也就不会把数组打散成若干个参数了.
(7).对数组进行反射:相同的维数(不是数组元素的个数,例如都是一维数组,不关心数组的大小),相同的8种基本数据类型时数组有相同的字节码.
6. 泛型
(1).泛型是对象类型,不能是基本类型,泛型存在源代码级别上,给编译器看的,生成class文件就不存在泛型了
(2).参数类型变量,实际类型变量,泛型类型,参数化的类型
(3).自定义泛型方法:public void method(T args){};public<T,K,V> void method(T a,K b,V c){};
(4).静态方法public static void method(T t){};泛型类不作用静态方法
7.可变参数
(1).可变参数就看成数组,可以使用增强for循环
(2).可变参数列表为最后一个参数
(3).可以给可变参数传递一个数组
(4).可变参数的类型是基本类型还是对象类型
8.课程介绍
(1).在谷歌心目中,“云”必须具备以下条件:数据都存在网上,而非终端里,软件最终消失,只要你的“云”设备拥有浏览器就可以运行现在的一切, “云”时代的互联网终端设备将不仅仅是PC,手机,汽车,甚至手表,只要有简单的操作系统加个浏览器就完全可以实现,由于数据都在“云”端,企业的IT管 理越来越简单,企业和个人用户也不同在担心病毒,数据丢失等问题。
(2).李开复描述了这样一个场景,只要你的PC或手机等终端里安装了一个简单的操作系统和完整功能的浏览器,开机后输入自己的用户名和密码,你存在“云”中的应用软件和数据就会同步到终端里。
9.快捷键
(1).配置快捷键:window->preferences->key
(2).Alt+/ :内容提示
Ctrl+1 :快速修复
Ctrl+Shift+O :快速导入包
Ctrl+Shift+F :格式化代码
Alt+方向键 :跟踪代码
Ctrl+Shift+/ :添加注释
Ctrl+Shift+\ :取消注释
Ctrl+Shift+X :更改为大写
Ctrl+Shift+Y :更改为小写
Ctrl+Shift+向下键 :复制代码
Ctrl+Shift+向上,向下 :改变代码行的顺序
Ctrl+T :查看继承关系
Ctrl+Shift+T :查看源代码
Ctrl+Shift+L :查看所有的快捷键
10.类加载器及其委托机制的深入分析
(1).Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader
(2).类加载器也是Java类,因为其他java类的加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这正是BootStrap(内嵌到JVM的内核中,使用C++语言编写的)
(3).Java虚拟机中的所有类装载器采用具有父子关系的属性结构进行组织,在实例化每个类转载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载器为其父级类加载器
(4).
public class ClassLoaderTest{
public static void main(String[] args){
System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());
//输出为sun.misc.Lanuncher$AppClassLoader;
System.out.println(System.class.getClassLoader());
//输出为null,因为类System是由BootStrap加载的;
}
}
(5).BootStrap->ExtClassLoader->AppClassLoader
ClassLoader loader= ClassLoaderTest.class.getClassLoader();
while(loader!=null){
System.out.println(loader.getClass().getName());
loader = loader.getParent();//往上顺序打印
}
System.out.println(loader);//最后打印老祖宗
(6).
BootStrap——>JRE/lib/rt.jar
ExtClassLoader—–>JRE/lib/ext/*.jar
AppClassLoader——>ClassPath指定的所有jar或目录
用Eclipse的打包工具将ClassLoaderTest打包成itcast.jar,然后放在jre/lib/ext目录下,在 eclipse中运行这个类,运行结果显示为ExtClassLoader,此时的环境状态是classpath目录有 ClassLoaderTest.class,ext/itcast.jar包中也有ClassLoaderTest.class,这时我们在打印 ClassLoaderTest类的类加载名称,发现是ExtClassLoader,而不是AppClassLoader.
(7).类加载的委托机制:
当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢:
首先当前线程的类加载器去加载线程中的第一个类
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器来加载类B
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类
每个类加载器加载类时,又先委托给其上级类加载器
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那么多个儿子,找哪一个呢?
对着类加载器的层次结构图和委托加载原理
(8).Thread类有一个方法setContextClassLoader(ClassLoader classLoader)//加载当前的类.
(9).每个类加载都首先会委托送到BootStrap,那么BootStrap很累,这样,那为什么不多搞几个BootStrap呢,之所以不这 样做,是因为,便于统一管理,因为所有的类都会找BootStrap,可能这时有几个相同的类进行加载,那么BootStrap,不会多次将他们的 class文件加载内存中,只会加载一份即可.这样效率就高了.
(10).
public class MyClassLoader{
public static void main(String[]args){
String srcPath=args[0];
String destDir=args[1];//得到目录
String destFileName =srcPath.substring(srcPath.lastIndexOf(\’/\’)+1);//得到文件名
String destFilePath=destDir+”\”+destFileName;
FileInputStream fis = newFileInputStream(srcPath);
FileOutputStream fos=new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
private static void cyp(InputStreamips,OutputStream ops){
int b =-1;
while((b=ips.read())!=-1){
ops.write(b^0xff);//对内容进行异或处理
}
}
}
class ClassLoader extends Date{
public String toString(){
return “hello,itcast”;
}
}
args[0]:ClassLoader.class的绝对路径
args[1]:itcastlib
有包名的类不能调用无包名的类.
(11).编写自己的类加载器:
知识讲解:
自定义的类加载器必须继承ClassLoader(抽象类)
覆盖findClass方法
defineClass方法:得到class文件转换成字节码
编程步棸:
编写一个文件内容进行简单加密的程序
编写了一个自己的类加载器,可实现对加密过的类进行装载和解密
编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类,程序中可以出了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName
(12).
模板设计模式:
父类—>loadClass(相同的)
子类1(自己干的)
子类2(自己干的)
覆盖findClass方法(自己干)
(13).
public class MyClassLoader extendsClassLoader{
public MyClassLoader(){
}
public MyClassLoader(String classDir){
this.classDir = classDir;
}
@Override
protected Class<?> findClass(Stringname){
String classFileName = classDir +”\” + name + “.class”;
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream bos = newByteArrayOutputStream();
cypher(fis,bos);
fis.close();
byte[] bytes = bos.toByteArray();
defineClass(bytes,0,bytes.length);
return super.findClass(name);
}
public static void main(String[] args){
Class clazz = newMyClassLoader(“itcastlib”).loadClass(“ClassLoaderAttachment”);
ClassLoaderAttachment d1 =clazz.newInstance();
}
}
(14).windows->showview->problem查看错误.
(15).可以查看Servlet的类加载委托继承树
11. 枚举
(1).枚举的作用限定指定的值,没有枚举前设计一个类,将构造函数设置成私有的,变量设置成静态常量
(2).枚举可以有构造函数(私有的),字段,方法
(3).可以定义set,get方法,获取变量的值。
(4).带有抽象方法的枚举,不能new出新的对象了。在new对象的时候就重写抽象方法,使用匿名内部类
(5).枚举中的每个枚举值代表枚举类的一个对象。
(6).枚举也可以实现接口,或继承抽象类
(7).JDK5中的switch拓展为除了接受int,short,char,byte外,也可以接受枚举类型。
(8).枚举的方法,name,ordial,valueOf,将字符串转换成枚举值。表单提交数据的时候。values返回枚举的所有的枚举值
12.内省
(1).内省:Introspector,专门操作Bean的属性。
(2).Bean的属性:只有字段提供了set/get方法,就是属性。只要有get/set的方法,就有一个属性,所以属性是有get/set方法决定的
(3).任何类都继承了Object类,又因为Object中有一个class属性
(4).内省的入口类:Introspector,方法getPropertyDescriptors()获取Bean的属性
(5).操作Bean的指定属性
(6).BeanUtils框架操作Bean
(7).在工程中新建一个文件夹,将架包复制到文件夹中,还需另外的架包loging,选中架包,右击build path加入到工程的环境中
(8).BeanUtils使用方便,类型自动转化,只支持8中基本数据类型
(9).给BeanUtils注册类型转换器,ConvertUtils.register()
(10).将Map中的数据整合到对象中,BeanUtils.populate()方法
13.配置Java模板代码
window->preferences->java->Editor->Template:编辑模板代码:line_selection,光标cursor,右击选择source with
14.享元模式
相同的对象只实例化一个,实例:桌面上的图标,word中字符,有很多小的对象,有很多相同的属性,不同的属性叫做外部行为,相同的属性叫做内部行为integer的缓冲池
15.注解
(1).@SuppressWarning(“deprecation”)过时注解
(2).@Deprecated注解,表示该方法是否过时,架包升级时添加的注解
(3).注解相当于一种标记,通过反射了解你的类及各种元素上有无何种标记
(4).注解相当于一个类:@interface Annotation{};注解类,应用注解类的类,对应用了注解类的类进行反射操作的类
(5).AnnotationTest.class.getAnnotation(ItcastAnnotation.class)得到类AnnotationTest上的注解ItcastAnnotation,注解上使用注解叫做元注解,元数据,元信息
(6).@Retention(RetentionPolicy.RUNTIME)(保持到运行阶段),@Retention(RetentionPolicy.SOURCE)(保持在源文件阶 段),@Retention(RetentionPolicy.CLASS)(保持在class文件中):源代码->class文件->(类加载)内存中的文件(字节码)
(7).@Override注解保持到SOURCE,@SuppressWarning注解保持到SOURCE,@Deprecated注解保持到RUNTIME(只有将该类调到内存中才知道该类中的方法是否过时了)
(8).@Target({ElementType.METHOD,ElementType.TYPE})注解只能标记到方法上或类,接口等类型上 (9).注解的属性:String color();类有个color属性,还有一个特殊的属性value,属性的默认值default,数组的属性值,枚举的属性值,注解的属性值
第二天:
1.dom4j解析XML文档
(1).Dom4j是一个简单、灵活的开放源代码的库,Dom4j是由早期开发JDOM的人分离出来而后独立开发的,与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的api相对要复杂一些,但是他提供了比JDOM更好的灵活性
(2).Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点,现在很多软件采用的Dom4j,例如hibernate,包括sun公司自己的JAXM也使用了Dom4j
(3).使用Dom4j开发,需要下载dom4j相应的jar文件
- XML语法
(1).编写XML文档时,需要先使用文档声明,声明XML文档的类型,使用IE校验XML文档的正确性.
(2).XML文档中的”中国”保存为本地的码表的”中国”
(3).在XML文档中,空格和换行都作为原始内容被处理
(4).XML区分大小写,一个标签可以有多个属性,每个属性都有它自己的名称和取值,在XML技术中,
标签属性所代表的信息也可以被表示子标签表示
(5).XML文件中的注释采用:”<!– >”格式
(6).CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出
(7).转义字符: “<“:< “>”:>
- Xml语言
在xml语言中,它允许用户自定义标签,一个标签用于描述一段数据,一个标签可分为开始标签和结束标签之间,又可以使用其他标签描述其他数据,以此来实现数据关系的描述.用于配置文件,以描述程序模块之间的关系
- XML约束
(1).在XML技术里,可以编写一个文档来约束一个XML文档的书写规范
(2).常用的约束技术:XML DTD 和 XML Schema
(3).如果dtd文件中含有中文,一定要存为utf-8格式.
(4).IE5以上的浏览器内置了XML解析工具:Microsort.XMLDOM,开发人员可以编写javascript代码,利用这个解析工具装载xml文件,并对xml文件进行dtd验证.创建xml文档解析器对象:
var xmldoc = newActiveXObject(“Microsoft.XMLDOM”);
开启xml校验
xmldoc.validateOnParse= “true”;
装载xml文档
xmldoc.load(“book.xml”);
获取错误信息
xmldoc.parseError.reason;xmldoc.parseError.line
(5).将DTD文件导入到eclipse中,可进行校验xml是否遵循dtd文件
在xml文件中编写DTD
第三天:
1.HTTP请求头各个头字段详解
请求头详解:
Accept:text/html,image/*用于告诉服务器,客户机支持的数据类型,
Accept-Charset:客户机采用的编码
Accept-Encoding:客户机支持的压缩格式
Accept-Language:客户机的语言环境,不同国家访问的内容也是不同的,就是通过这个头实现的,用于实现国际化
Host:www.it315.org:8080:告诉服务器,想访问的主机名
If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间,提高访问效率
Referer:客户机告诉服务器,他是从哪个资源来访问服务器的(防盗链),通过检查该头是否是从本网站点击过来的,如不是的,就让他跳到本网站的首页来
User-Agent:客户机告诉服务器,客户机的软件环境
Cookie:客户机通过这个头向服务器带点数据
2.Http请求行和请求方式
一个完整的HTTP请求包含:一个请求行,若干个请求头,以及实体内容,请求行,请求头,之后空一行,带有请求信息(如表单提交数据为post方式)如下所示
Get/books/java.html HTTP/1.1 :请求行,用于描述客户端的请求方式,请求的资源名称,以及使用的HTTP的协议版本号
Accept:*
Accept-Language:en-us
Connection:Keep-Alive
Host:localhost
Referer:http://localhost/links.asp
User-Agent:Mozilla/4.0
Accept-Encoding:gzip,deflate
以上的内容为多个消息头,用于描述客户端请求哪台主机,以及客户端的一些环境信息等
请求行中的GET称之为请求方式,请求方式:post,get,head,options,delete,trace,put,常用的 有:get,post,用户没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点连接访问都是get,用户如想把请 求方式改为post,可通过更改表单的提交方式实现.不管post或get,都用于向服务器请求某个web资源,这两种方式的区别主要表现在数据传递上: 请求方式为get方式,则可以再请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分割,同时在URL地址后附带的参数是 有限制的,其数据容量通常不能超过1k,若请求方式为post方式,则可以再请求的实体内容中向服务器发送数据,post方式的特点:传送的数据无限制
<ahref=”1.html?name=aaaaaaa”>连接get方式
3.Http响应头字段详解
响应头:
Location:
这个头配合302状态码使用,用于告诉用户找谁
,response.setStatus(302),response.setHeader(“Location”,”/day04/1.html”);请求重定向,判断浏览器的地址栏的地址是否发生变化,实例是用户登录
Server:服务器通过这个头,告诉浏览器的类型
Content-Encoding:服务器通过这个头,数据的压缩格式,收费是靠数据出口量算的, 所以为了省钱和效率高,要进行数据压缩,jdk中的GZIPOutputStream类,压缩类流,包装流和底层流,最好将包装流关了或者刷新,数据写入到底层流中去,
response.setHeader(“Content-Encoding”,”gzip”);response.setHeader(“Content-length”,gzip.length+””);
Content-Length:服务器会送的数据的长度
Content-Type:服务器会送数据的类型,response.getOutputStream().write();服务器会送数据都是二 进制,通过这个头,可以告诉浏览器这个二进制是什么类 型,this.getServletContext().getResourceAsStream(“/1.bmp”);intlen = 0;byte buffer[] =new byte[1024];OutputStream out =response.getOutputStream();while((len=in.read(buffer))>0) {out.write(buffer,0,len)},在服务器的目录下的web.xml中查看各个数据类型的 respose.setHeader(“content-type”,””)的写法.
Refresh:告诉浏览器隔多长时间刷新一次,response.setHeader(“refresh”,”3;url=”””)控制浏览器隔三秒跳到指定的网页上
Content-Disposition:告诉浏览器以下载的方式打开文件,response.setHeader(“content-disposition”,”attachment;filename=3.jpg);
Transfer-Encoding:告诉浏览器数据的传送格式
ETag:缓存相关的头,服务器根据数据的内容生产一个字符串,客户机第二次访问服 务器时带来的ETag的值和服务器的值一样,就拿缓存给客户,实时更新,
Expires:高速浏览器,把会送的资源缓存多少时间,-1或0,则是不缓存的
Pragma:no-cache
Cache-Control:no-cache
控制浏览器不要缓存数据,当数据不发生改变时,就要缓存,当实时性要求很高的数据不能缓存.
4.Http响应状态行
HTTP /1.1 200OK :状态行,用于描述服务器对请求的处理结果
Server:Microsoft-IIS/5.0
Date:….
Content-Length:2291
Content-Type:text/html
Cache-control:private
多个消息头:用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会它会送的数据
实体内容:代表服务器向客户端会送的数据
具体:
状态行:
格式:HTTP版本号 状态码 原因叙述
举例:HTTP1.1 200 OK
状态码用于表示服务器对请求的处理结果,他是一个三位的十进制数,响应状态码分为5类,
100-199:表示接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200-299:表示成功接收请求并已完成整个处理过程,常用200
300-399:为完成请求,客户需进一步细化请求,例如,请求的资源已经移动一个新地址,常用302(你请求我,我叫你去找别人),307和304(拿缓存)
400-499:客户端的请求有错误,常用404,403(没有权限访问)
500-599:服务器端出现错误,常用500
5.http协议概述
(1).浏览所有的服务器:
在命令行中敲入
telnet localhost 8080
GET /aa/1.html HTTP/1.1
Host:
(2).在HTTP1.0协议中,客户端和Web服务器建立连接后,只能获得一个web资源。在HTTP1.1协议,允许客户端与web服务器建立连接后,在一个连接上获取多个web资源。
(3).在命令行中敲入以上的命令,HTTP/1.0获取一次资源,就断开连接,而HTTP/1.1不会断开连接
(4).一个web页面中,使用img标签引用了三幅图片,当客户端访问服务器中的这个web页面时,客户端总共会访问几次服务器,即向服务器发送了几次HTTP请求:
共四次请求,浏览器认识img标签,浏览器解析img,则img一次请求,最好将这三张图片整合到一张图片上,这样就只有两次请求了
(5).<scriptsrc=”1.js”>
<scriptsrc=”1.js”>
共三次请求,可以将多个js文件整合到一个js文件,避免多次向服务器发出请求
6. tomcat服务器目录结构
bin:存放启动和关闭Tomcat的脚本文件(命令)
conf:存放Tomcat服务器的各种配置文件(核心文件:server.xml)
lib:存放Tomcat服务器的支撑jar包
logs:存放Tomcat的日志文件(catalina文件)
temp:存放Tomcat运行时产生的临时文件
webapps:web应用所在目录,即供外界访问的web资源的存放目录
work:Tomcat的工作目录,jsp翻译成servelet文件
7.web服务器启动问题
(1).tomcat是使用Java编写的,启动的时候需要JVM,java环境设置不正确的话可能导致服务器不能启动,还有就是8080端口被占用了.
(2).在conf->中server.xml中对tomcat服务器进行配置
(3).我的电脑->计算机管理->服务->停止windows服务
(4).http://www.sina.com/是url;www.sina.com是主机名;sina.com是域名,在域名下可以搭建多个网站
(5).tomcat文件下的webapps下新建一个web资源
(6).Cataline_home环境变量的设置问题,服务器的目录,启动的服务器的目录要和服务器存放的目录一致
8. web开发相关概念和常见web服务器
(1).自己开发服务器:
public class Server
{
public static void main(String[] args)throws Exception{
ServerSocket server = newServerSocket(9999);//服务器建立端口
Socket sock server.accept();//客户端访问
FileInputStream in = newFileInputStream(“c:\a\1.html”);
OutputStream out = sock.getOutputStream();
int len = 0;
byte buffer[] new byte[1024];
while((len = in.read(buffer))>0){
out.write(buffer,0,len);
}in.close();
out.close();
sock.close();
server.close();
}
}
(2).WebLogic是BEA公司的产品,是目前应用最广泛的Web服务器,支持J2EE规范,是商业产品,需要收费
(3).常用的Web服务器IBM公司的WebShpere,也遵循J2EE规范,也要收费
(4).Tomcat服务器只支持JSP以及Servlet规范,不支持EJB,如果要支持可以使用JBOSS
(5).http:80,smtp:25,pop3:110,ftp:23,https:443
- web应用和虚拟目录
(1).web应用虚拟目录映射:自己开发好的web应用项目到部署到服务器上的web应用项目的关系目录,在服务器的配置文件中配置,虚拟目 录,<Context path=”/itcast”docBase=”c:\news”/>,”/itcast”就是虚拟目录,”c:\news”是磁盘上web应用的 目录,修改配置文件后一定要重启服务器.http://localhost:8080/itcast/1.html,浏览c:\news\1.html文 件.当path=””时,就是缺省设置
(2).tomcatdocument中reference中观察tomcat的配置文件设置方法.在Catanena\localhost\新建一个context.xml文件.这种方法无需重启服务器.
<ContextdocBase=”c:\news”/>,http://localhost:8080/1.html;多级虚拟目 录:文件名:a#b#c.xml,http://localhost:8080/a/b/c/1.html;缺省的虚拟目录,把文件名改成 ROOT.xml重启服务器,覆盖原先的缺省设置.
(3).webapps文件夹中的web应用可以让外界访问,又服务器自动映射目录,把news文件放到webapps中去,http://localhost:8080/news/1.html,当服务器和webapps不在一个目录时,此方法不可以.
- web应用组织结构
(1).mail:Web应用所在目录
html,jsp,css,js文件等,这些文件一般存在web应用根目录下,根目录下的文件外界可以直接访问,java类,jar包,web应用 的配置文件存在这个目录下WEB-INF,这个文件夹的文件名一个单词都不能写错,这个文件要新建,在这个文件夹下载新建一个classes文件夹,放置 java程序,新建一个lib文件夹,放置架包,该目录下的文件外界无法非法直接访问,由web服务器负责调用.每个web应用应该有个web配置文件, 是最重要的一个配置文件,一切配置可以通过这个文件进行配置web.xml
(2).对于web.xml文件,可以从server.xml中拷贝,拷贝头和尾部分.
- web资源访问流程
(1).服务器认识war包,自动解压,放到webapps中,自动生成应用.
(2).配置context元素的reloadable=”true”,应用程序修改,不需要重新发布应用,建议不要配置,因为只要一修改,就要重新加载,出现问题.
(3).context.xml中中配置,被所有的web应用使用.
- 配置虚拟主机
(1).在一个tomcat服务器中可以放置多个网站,所谓配置虚拟主机,就是在tomcat服务器中配置一个网站
(2).如需在Web服务器中配置一个网站,需使用Host元素进行配置, 例:<Hostname=”site1″appBase=”c:\app”>,配置的主机(网站)要想被外部访 问,必须在DNS服务器或windows系统中注册.
(3).在server.xml新建一个主机,新建一个Host标签,<Contextpath=”/.mail” docBase=”c:\sina\main”/>
(4).互联网访问流程:ie中输入错误!超链接引用无效。 返回给ie,接着使用ip地址访问sina.com
(5).ie开始会访问windows的host文件,如果这个文件知道这个地址,就不会去问DNS,没有则会去访问DNS服务器:/windows/system32/drivers/etc/hosts文件进行配置.
- 软件密码学和配置tomcat的https连接器
(1).对称加密:加密和解密的密码是相同的.
(2).非对称加密:接受者生成一对公钥和私钥,公钥加密的数据只能私钥解,私钥加密的数据只能公钥解,然后接受者将公钥传给发送者,用接受者的公 钥进行加密,然后接受者用私钥解密.然而,在传送公钥的途中可能被黑客拦截,然后黑客自己生成自己的公钥和私钥,然后将公钥送给发送者,发送者如何知道公 钥是不是接受者的公钥?这是在互联网上有个叫CA的机构,接受者产生一对公钥和私钥,然后让CA认证,CA给接受者一份数字证书,这时发送者受到的是数字 证书,发送者验证数字证书是不是接受者的数字证书.信任点就是CA.网上银行出示一份数字证书(公钥),浏览器可以验证数字证书正确,注册,当你填写信息 时,浏览器就是用这份数字证书验证.但是数字证书可能被黑客拦截,怎么确定数字证书是接受者发的还是黑客发的,数字签名(私钥加密),发送者自己生成一对 公钥和私钥,发送者想让接受者相信是自己加密的,发送者就需要签名(使用自己的私钥),然后只有接受者使用公钥解密,就相信是发送者将内容加密的.MD5 算法得到数据指纹.然后对数据指纹加密.将密文和指纹加密信息传给接受者,可以判断在传送过程没有被篡改,用密文生成数据指纹,和传过来的数据指纹对比.
第四天:
1.Eclipse开发servlet
(1).web工程的名称,该工程部署时,在webapps目录下就会有一个example的web应用
(2).src文件夹,Java程序的开发目录,该目录下编写的所有程序在部署时,会自动部署到example/web-inf/classes目录下
(3).WebRoot文件夹,webroot对应于web应用的根目录,该目录下的所有子目录和子文件夹在部署时,会原封不动的发布到web应用目录下
(4).Web rootfolder:WebRoot应用的根目录,Context root URL:映射到服务器的目录,在WebRoot目录下新建Web资源,应用发布时,将src文件夹中的源文件编译成class到webRoot\web- inf下的classes文件夹
(5).servlet导入源码,到tomcat服务器的目录下查找文件夹
(6).为servlet配置对外访问路径,
别名
类名(全称)
别名
/aa
(7).还可以更改tomcat的运行java环境
2. HttpServlet和一些开发细节
Servlet接口sun公司定义了两个默认实现:
GenericServlet,HttpServlet
httpservlet指能够处理HTTP请求的servlet,它在原有的servlet接口上添加了一些与http协议处理方法,它比servlet接口的功能更为强大,因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口
httpservlet在实现servlet接口时,复写了service方法,该方法体内的代码会自动判断用户的请求方式,如为get请求,则调 用httpservlet的doGet方法,如为post请求,则调用doPost方法,因此,开发人员在编写Servlet时,通常只需要复写 doGet或doPost方法,而不要去复写service方法.可以查看httpservlet的源码,
修改servlet的模板代码.进入myeclipse,搜索Servlet.java文件,打开修改文件.
3.ServletConfig对象以及它的开发场景
(1).在servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数,当 servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到servletconfig对象中,并在调 用servlet的init方法时,将servletConfig对象传递给servlet,进而,程序员通过servletconfig对象就可以得到 当前servlet的初始化参数信息.
(2).web服务器创建的容器对象
request,response,servletconfig,servletcontext,session,cookie
(3).servletconfig
配置参数信息.
dataxxxx
(4).覆写init()方法带有servletconfig参数的,服务器自动将参数信息封装到servletconfig对象中.调用 init()方法时,servlet可以得到这些参数信息.在servlet中定义一个servletconfig对象,将init()传递过来的 servletconfig接收到.private ServletConfig config;public voidinit(ServletConfig config){this.config = config;}String value =config.getInitParameter(“data”);System.out.println(value);参数信息不在程序中,而是在 配置文件.同时this.getServletConfig();代替privateServletConfig config;因为父类已经定义了ServletConfig对象,只需调用父类的getServletConfig方法即可.
(5).可以配置多个参数信息,同时为得到所有的参数信息:
Enumeration e =this.getServletConfig().getInitParameterName();
while(e.hasMoreElements())
{
String name = (String)e.nextElement();
String value =this.getServletConfig().getInitparameter(name);
System.out.println(value);
}
(6).开发过程中,参数不能在程序中写死,需要在配置文件中给出参数信息.实例:字符集,连接不通的数据库.读取不同的配置文件.
(7).struts就是个实例.可以到struts实例中查看struts的web.xml文件
- ServletContext读取web应用中的资源文件
(1).在web开发中,用于资源文件的类型一般为两种xml,property,如果数据之间是没有关系就是用property,有关系就使用xml,数据库的连接关系没有关系,一般用property文件,
(2).db.properties文件,url=jdbc:MySQL://localhost:3306/test;username=root;password=root;读取db.properties文件.通用代码:
InputStream in
= this.getServletContext().getResourceAsStream(“/WEB-INF/classes/db.properties”);
斜杠就代表web应用根目录,Properties props = new Properties();props.load(in);把文件load到Properties对象中,用Map对象存储String url =props.getProperty(“url”);
String username =props.getProperty(“username”);
String password = props.getProperty(“password”);
(3).web应用中不使用FileInputStream in = newFileInputStream(“src/db.properties”);采用的是相对路径,相对路径中有这个资源,这是相对路径相对的是 jvm的启动目录.当时jvm的启动目录是服务器的启动目录:服务器/bin
(4).另外的读取资源的方法:
String path = this.getServletContext().getRealPath(“/WEB-INF/classes/db.properties”);得 到硬盘的绝对路径 此时就可以使用FileInputStream in = new FileInputStream(path);需求:下载,可以得到资源的名称,读取文件时客户机带来的,当前读取的资源文件的名称.可以从path中截 取出来.
String filename =path.substring(path.lastIndexOf(“\”)+1);
(5).在servlet中用dao对象操作数据库,dao对象需要properties文件的内容即数据库的连接信息.dao一般放到 cn.itcast.dao包中.不能将servlet中的context对象传递给dao对象,web层和服务层不能有交织了.如果读取资源文件的程序 不是servlet的话,此时要通过类装载器读取资源,在UserDao对象中InputStream in =UserDao.class.getClassLoader().getResourceAsStream,资源文件 (“db.properties”);一般只需读取一次,有个习惯:将读取文件代码放在static{};静态代码块中.通常抛出初始化错误throw new ExcepitonInitaliterError(e);文件不能太大,类加载器要装载到内存中
(6).有人可能把properties文件改了.然后读取的内容是原始的,还是修改的,读取的是原始的,因为类装载的方式,但是类只装载一次.但 是想读取更新后的内容:String path =UserDao.class.getClassLoader.getResource(“db.properties”).getPath();然后用 FileInputStream去读取.
- ServletContext对象
(1).web容器在启动时,它会为每个web应用程序都创建一个对应的ServletContext对象,它代表当前web应 用,servletconfig对象中维护了servletcontext对象的引用,开发人员在编写servlet时,可以通过 servletconfig.getServletContext方法得到servletContext对象.同时也可以context = this.getServletContext();得到父类的context查看servletContext api 文档了解servletContext对象的功能.
(2).servletContext为所有的servlet对象实现数据共享.是全局概念.方法getContext()为了得到别的web应 用.getInitParmeter()方法可以得到web应用的配置信息.getNameDispatcher()得到一个转发对 象.getRealPath()方法得到资源的硬盘真实路径,方法getResource()得到资源的路径,只是返回的是URL地 址.getResourcePaths()方法返回给定目录下的所有资源.getServletContextName()方法返回web应用的名 称.setAttribute(),getAttribute(),removeAttribute();
(3).由于一个web应用中所有servlet共享同一个servletcontext对象,所以多个servlet通过 servletcontext对象是实现数据共享。servletcontext对象通常也被称之为context域对象.可以获取web应用的初始化参 数,实现servlet的转发,利用servletcontext对象读取资源文件:得到文件路径,读取资源文件的三种方式,.properties文件 (属性文件),context域,request域,session域,page域.
(4).实例:聊天室,资源共享.开个浏览器说,开个浏览器读
(5).data
XXXX
和config不同,config是给某个servlet初始化参数,而context是所有的servlet初始化参数
(6).servletconfig中的初始化信息中连接数据库信息,应该写成context的初始化信息,因为可能有多个servlet需要数据库连接
(7).转发和重定向:转发:你找我,我帮你去找他,重定向:你找我,我告诉你,你自己去找他;如果是转发:只有一次请求,地址栏不发生改变重定 向:两次请求。servlet中不适合浏览器的数据的输出,因为要数据的排版,应该在html,jsp中输出数据.servlet要将输出数据要转发给 jsp显示.
RequestDispatcherrd = this.getServletContext().getRequestDispatcher(“/1.jsp”);
rd.forward(request,response);
在jsp中取数据,
<% String.data=application.getAttribute(“data”);out.write(data);%> servletcontext可以,但是在开发过程中是有问题的:有一个人来访问数据,把它的数据存到context中,当他在jsp中取数据的时候,此 时又来一个人,也来存数据,可能覆盖前一个人的数据,那前一个人取得数据可能是后来的那个人的数据,因为context是共享资源,存在线程安全问题.在 开发过程中一般用request域带数据.
(8).服务器启动时,为每个web应用创建servletcontext对象,当服务器停止时,servletcontext对象被销毁.
- Servlet的生命周期
ie浏览器,web服务器,Servelet程序
浏览器输入地址->连接web服务器,发送HTTP请求,解析出客户机想访问的主机名,解析客户机想访问的web应用和web资源 –>使用反射技术创建一个servlet实例对象(servlet第一次访问的时候被创建)–>调用servlet.init()完成对 象的初始化->调用servlet.service()响应客户端的请求,服务器创建request,response容器,service方法执 行->向response容器中写入客户机请求的数据->服务器从response中取出数据构建一个HTTP响应回写给客户机–> 回写http响应
客户机第一次访问服务器,生成一个servlet,第二次在访问同一个servlet就不会再创建了,当关闭服务器时servlet就消亡了
- Servlet的线程安全
(1).当多个客户端并发访问同一个servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用servlet的 service方法,因此service方法如果访问了同一个资源的话,就有可能引发线程安全的问题,如果某个servlet实现了 SingleThreadModel接口,那么servlet引擎将以单线程模式来调用其service方法。SingleThreadModel接口中 没有定义任何方法,只要在servlet类的定义中增加实现SingleThreadModel接口的声明即可.对于实现了 SingleThreadModel接口的servlet,servlet引擎仍然支持对该servlet的多线程并发访问,其采用的方式是产生多个 servlet实例对象,并发的每个线程分别条用一个独立的servlet实例对象。实现SingleThreadModel接口并不能真正解决 servlet的线程安全问题,因为servlet的引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个servlet实例 对象被多个线程同时调用的问题,事实上,在servlet api2.4中,已经将SingleThreadModel标记为Deprecated(过时的).标准的解决方案是同步方式sychronized
(2).如果线程向person的静态list集合中加入了数据(aaa),数据用完后,一般要移除静态集合中的数据(aaa),否则集合中的数据越来越多,就会导致内存溢出。对象销毁了,静态资源的字节码仍然驻留在内存中.
(3).web中的异常一般不能抛,要catch住.
- Servlet开发的一些重要细节
(1).由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL 地址上,这个工作在web.xml文件中,使用元素和元素完成
(2).元素用于注册Servlet,它包含有两个主要的子元素:和,分别用于设置Servlet的注册名称和Servlet的完整名.
一个元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元 素:和,分别用于指定Servlet的注册名称和Servlet的对 外访问路径
(3).进入myeclipse->Web更改Web-Content-root
(4).一个servlet可以映射到多个对外访问路径.只需多复制个
(伪静态)
(5).同一个Servlet可以映射到多个URL上,即多个元素的子元素的设置值可是同一个servlet的注册名
(6).在servlet映射到的URL中可以使用通配符,但是只能有两种固定的格式:一种格式是:”.扩展名”,另一种格式是以正斜杠/开头并以”/*”结尾的.
anyName
*.do
匹配所有后缀名为do的访问路径(也可以不需要后缀名, 匹配所有的文件)anyName</servlet- name>/action/*</servlet- mapping>服务器在更改web.xml时,无需重启,WEB- INF/web.xml在服务器的conf文件夹下的context.xml配置文件中,监视 web.xml是否发生改动
(7).servlet1 映射到 /abc/*
servlet2 映射到 /*
servlet3 映射到 /abc
servlet4 映射到 *.do
问题:
1.当请求URL为”/abc/a.html”,”/abc/“和”/“都匹配,但是servlet引擎会调用servlet1
2.当请求URL为”/abc”时,”/abc/*”和”/abc”都匹配,但是servlet引擎会调用servlet3
3.当请求URL为”/abc/a.do”时,”/abc/“和”.do”都匹配,但是servlet引擎会调用servlet1
4.当请求URL为”/a.do”时,”/“和”.do”都匹配,但是servlet引擎会调用servlet2
5.当请求URL为”/xxx/yyy/a.do”时,”/“和”.do”都匹配,但是servlet引擎会调用servlet2
总结:谁长的最像,谁先匹配,同时*的优先级最低.
(8).Servlet是一个供其他Java程序(Servlet引擎:服务器端调用servlet的程序)调用的Java类,它不能独立运行,它 的运行完全由servlet引擎来控制和调度.针对客户端的多次servlet请求,通常情况下,服务器只会创建一个servlet实例对象,也就是说 servlet实例对象一旦创建,他就会驻留在内存中,为后续的其他请求服务,直至web容器退出,servlet实例对象才会销毁.在servlet的 整个生命周期内,servlet的init方法只会被调用一次,而对一个servlet的每次访问请求都导致servlet引擎调用一次servlet的 service方法,对于每次访问请求,servlet引擎都会创建一个新的httpservletrequest请求对象和一个新的 httpservletresponse响应对象,然后将这两个对象作为参数传递给她调用的servlet的service方法,service方法再根 据请求方式分别调用doXXX方法.
(9).右击,可以选择父类的方法,进行重写父类的方法
(10).服务器启动时,servlet并未创建,只有当访问web资源时会创建一个servlet,调用init()方法.一个servlet为多个请求服务,当服务器停了,servlet就被摧毁了,调用destory()方法.
(11).针对客户端的每一次请求,服务器端都会为用户创建一个request和reponse,他们的生命周期很短,如果是并发的请求,大量的请求可能创建大量的request和reponse对象,可能导致服务器运行变慢,但是不是并发的话,可能不会创建那么多个对象
(12).如果在元素中配置一个元素,那么web应用程序在启动 时,就会装载并创建servlet的实例对象,以及调用servlet实例对象的init()方 法,invoker</servlet- name>…2;用途为web应用写一个initservlet,这个servlet配置为 启动时装载,为整个web应用创建必要的数据库表和数据.(即启动服务器时就创建了servlet),struts就是一个非常大的servlet,其中 数字的大小就是启动的优先级,数值越小优先级越高.struts中的数值为2,担心用户需要扩张,所以不使用1.
(13).如果某个servlet的映射路径仅仅为一个正斜杠/,那么这个servlet就成为当前web应用程序的缺省servlet;凡是在 web.xml文件中找不到匹配的元素的URL,它们的访问请求都将交给缺省servlet处理,也就是 说,缺省servlet用于处理所有其他servlet都不处理的访问请求.在<tomcat的安装目录>\conf\web.xml文件 中,注册了一个名称为org.apach.catalina.servlets.DefaultServlet的Servlet,并将这个servlet 设置为缺省servlet;当访问tomcat服务器中的某个静态html文件和图片时,实际上是在访问这个缺省servlet。这个用途主要用于:用户 请求一个数据(html,jpg,avi等)服务器将启动一个缺省的servlet提供给客户数据.在浏览器看到的任何内容都是数据都需要由一个 servlet来为客户提供数据,包括错误信息.
(14).配置文件修改了,不需要重启服务器,但是源程序修改了,要重启服务器.
- Servlet开发入门
(1).jsp就是servlet,servlet是sun公司提供的一门用于开发动态web资源的技术,编写一个java类,实现servlet 接口.获得servlet启动信息,通过getServletConfig(),service的两个参数,ServletRequest req,ServletResponse res,这个方法是服务器调用的,获取客户机的对象,只需找request,输出信息找response.getOutputStream();
(2).进入服务器的目录,新建一个web应用,在应用中新建一个java,class,lib,在文件夹java下新建一个servlet文件,
package cn.itcast
public classFistServlet extendsGenericServlet{
public void service(
ServletRequest req,ServletResponseres)throws ServletException,java.io.IOException{
OutputStream out = res.getOutputStream();
out.write(“Servlet”.getBytes());
}
}
(3).servlet所需的架包导入,tomcat能运行servlet,则在服务器的lib目录下含有架包,为servlet配置对外访问路径web.xml,代码可以到服务器的web.xml文件中拷贝
第五天:
-
HttpServletResponse简介
(1).web服务器收到客户端的http请求,会对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的reponse对 象.request和reponse对象既然代表请求和响应,那我们要获取客户及提交过来的数据,只需要找request对象就行了,要向客户机输出数 据,只需要找response对象就行了.
(2).reponse的相关方法,构建一个http响应的方法,getStatus(),setHeader(),getWriter(),getOutputStream();字节流可以写任何数据
2.request获取请求头和请求数据
(1).用户点击链接和表单提交向服务器提交数据
(2).在服务器端获取数据:
request.getParameter(“username”);
request.getParmeterName();
得到所有的名称的枚举.
request.getParameterValues();
得到名称相同的值
(3).在用户提交的数据中,可能抛空指针异常,加强代码的健壮性.
(4).Mapmap=request.getParameterMap();将用户的数据封装到对象中User,先获取Map,再用 JavaBeans将Map转化成对象User,其中map关键字是请求参数名称,关键字的类型是String,值的类型是String[],因为可能有 多个相同名称对应的值就有多个,所以是个数组;Map将值填充对象User,迭代Map,得到关键字和对应的值,利用反射技术将这些数据填充到User对 象中.设计一个对象代表表单.BeanUtils.copyProperties(user,formbean);将表单beans拷贝到user对象 beans中;BeanUtils.populate(user,map);对象上的字段必须是八种基本类型,不是的话,要自己写个转换器.
(5).服务器以断点的方式运行进行调试,
(6).request.getInputStream();获取输入流,进行获取数据,进行文件上传.
- request简介.txt
(1).HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息.
(2).getMethod();获取请求方式,getRequestURI();获取客户想我访问的资 源;getHeader();getDateHeader();getHeaderNames();获取所有的头信息,getHeaders();与 getHeaderNames();不同的是:可能有同名的头信息,此时就要用getHeaders()方法,a-xx;y- xx;getParameter获取客户带来的数据name=”aaa”;password=”rot”;getParameterNames(); getParameterValues();getInputStream():将用户的数据当做流读入,如:客户进行文件上传;
(3).getRequestURL():/day07/servlet/demo1;
getRequestURI():http://localhost:8080/day07/servlet/demo1
用在权限拦截上,不同的网页有不同访问权限,做个拦截器,过滤器,还有是在记录页面的访问次数.getQueryString()客户携带的查询信 息,地址栏后的类容,getRemoteAddr();得到访问者的ip地址;getRemoteHost():主机在DNS注册了,打印了主机 名.getRemotePort();来访者的端口,ie也是一个程序,需要一个端口getLocalAddr();返回web服务器的ip地 址,getMethod():获取请求方式,默认是get方式
4.request乱码
(1).在文本框中敲入中文,浏览器提交数据的码表就是浏览器使用哪个码表打开.request容器也是默认码表是iso8859码表,所以在获取 数据时,request.setCharsetsEncoding(“UTF-8”);这种改变码表的方式只对post方式有效,对get方式无效.这种 方式解决的是post方式提交的数据.
(2).但是这种方式不能用于get方式,如果是get提交,必定是乱码,所以必须在servlet中手动的改变乱码,newString(username.getBytes(“iso8859″),”UTF-8”);
(3).用户使用超链接提交数据时,带有中文,其实超链接就是一个get方式,所以要使用get方式去解决乱码问题.
(4).更改服务器的配置,解决乱码问题,但是在开发中严禁这种方式的使用,从浏览器中进入tomcat,修改连接 器,HTTP->URLEncoding,然后到tomcat目录下的server.xml中修改连接器Connector,在其中添加一个属 性:URLEncoding=”UTF-8″;还有一种方法,在连接器中添加一个属性,useBodyEncodingForURI=”true”;是将 post方式解决乱码的方法可以用于解决get方式乱码.所以还要事先设置好request容器的码表.
(5).request.setCharacterEncoding(“UTF-8”);
String username =request.getParameter(“username”);
response.setCharacterEncoding(“gb2312”);
response.setContentType(“text/html”;charset=”gb2312″);
response.getWriter.write(username);不会有乱码
5.request实现请求转发和mvc设计模式.txt
(1).request是个域对象,request作用的范围是请求范围中,主要用于设计mvc中.
(2).servlet中转发到jsp显示数据,
request.getRequestDispatcher(“/mesage.jsp”).forward(request,response);
在开发中一般都是用这种方式,而不是用ServletContext的转发方式.每一次请求都对应一个request,正好,request的作用域是一个请求,所有request的转发,都是一个请求,都在这个作用域中.
(3).request.getParameter()方法是获取客户机带来的数据,而request.getAttribute()方法是获取request域中获取数据.
(4).forward方法用于将请求转发到requestDispatcher对象封装的资源,如果在调用forward方法之前,在 servlet程序中写入的部分内容已经被真正的传送到了客户端(关闭response流),forward方法将抛出 IlegalStateExcepiton异常,如果在调用forward方法之前向servlet引擎的缓冲区(response)中写入了内容,只要 写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已经写入到 HTTPServletResponse对象中的响应头字段信息保持有效.
(5).if(true){request.getRequestDispatcher(“/index.jsp”).forward(request,response)}
跳转到index.jsp向客户机写数据
request.getRequestDispatcher(“/index.jsp”).forward(request,response)也要向用户写数据。所以一个良好的习惯是跳转之后一定要return;
(6).String data =”aaa”;response.getWriter().write(data);不要关闭这个流,这是可以 request.getRequestDispatcher(“/index.jsp”).forward(request,response);理论上 应该是两部分内容的组合,即data和jsp中的内容,但是实际上只显示jsp中的内容,因为jsp的内容将覆盖data内容,但是消息头不改变,在这个 过程中创建了两个servlet,因为jsp也是一个servlet,但是只有一起请求.不会创建两个容器.
-
request实现页面包含
所有的网页都有相同的网头和网脚,此时只需要将网头和网脚设置共同的部分 html,request.getRequesetDispatcher(“head.jsp”).include(request,response);response.getWriter().writer(“hhh”);request.getRequestDispatcher(“foot.jsp”).incude(request,response); 被包含页面不能出现全局架构标签,因为可能重复.实现页面包含的作用
7.response的outputstream输出数据的问题
(1).在程序中的”中国”变成了UTF-8码表,但是浏览器默认的是gb2312打开内容,在程序中发送一个头,告诉浏览器用哪个码表打开.
response.setHeader(“Content-type”,”text/html;charset=UTF-8″);
(2).html中的标签可以模拟一个http响应头.<meta http-equiv=\’conten-type\’content=\’text/html;charset=\’UTF-8\’>;
(3).当Content-type写成content-type就变成下载了.
(4).out.write(1);在浏览器上显示的并不是1,因为1对应的码表.
8.response的writer输出数据的问题.txt
(1).String data =”中国”;PrintWriter out =response.getWriter();out.writer(data);有问题显示乱码
(2).servlet将”中国”写入response中,但是response用的是iso8859码表,对应没有” 中国”,所以在浏览器中看到乱码,response.setCharacterEncoding(“UTF-8”);设置response的码表为 UTF-8;同时也要告诉浏览器以utf-8码表打开.
(3).简便的调用response.setContentType(“text/html;charset=”UTF-8”);可以代替以上两条设置码表的代码.
9.response实现请求重定向和response的一些细节
(1).怎么实现请求重定向:发送状态码302,
response.setStatus(302);response.setHeader(“location”,”/day06/index.jsp”);
同时sun公司提供了一个方法response.sendRedirect(“/day06/index.jsp”);重定向的特点是地址栏发生改 变.可能加重服务器的负担,因为有多次请求,一般用于用户登录,因为转发,地址栏不变,用户看不到是否跳到首页了,重定向的地址栏变化,可以告诉用户跳到 首页,还有一种是购物,点击购买,服务器的一个servlet帮你买成了,servlet会跳到购物车显示页面,显示你购买的东西.当使用转发时,用户点 击刷新,可能又买了一次,重新干一次就不好了,所以用重定向,其他情况下都最好使用转发,减轻服务器的负担
(2).getOutputStream和getWriter方法分别用于得到输出二进制数据,输出文本数据的 servletoutputstream,printwriter对象,但是这两个方法是互斥的,条用了其中的任何一个方法后,就不能再调用另一个方 法,servlet程序向ServletOutputStream或printwriter对象中写入的数据将被servlet引擎从response里 面获取,servlet引擎将这些数据当做响应消息的正文,然后再与响应状态行和个响应头组合后输出到客户机,servlet的service方法结束 后,servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没 有,servlet引擎调用close方法关闭该输出流对象
(3).当在demo1中使用了getOutputStream()方法,转发到demo2,但是在demo2中使用了getWriter();就 是在一条调用链中不能存在这两个方法,当使用重定向了,有两次请求,产生了两个response对象所以不会有问题,但是转发就有问题了.
(4).无需关心流的关闭,servlet引擎会自动关闭,但是你自己定义的流需要自己关闭,引擎不会去关闭的.
10.response实现文件下载
(1).在webroot应用下新建一个download文件夹,存放下载资源.
当下载的文件是中文文件,则文件名需要经过url编
码,URLEncoder.encode(filename,”UTF-8″);filename是下载文件名.
11.web工程中各类地址的写法
(1).request.getRequestDispatcher(“/form1.html”).forward(request,response);给服务器用的
(2).response.sendRedirect(“/day05/form1.html”);给浏览器用的
(3).this.getServletContext().getRealPath(“/form1.html”);给服务器用的
(4).this.getServletContext().getResourceAsStream(“/form1.html”);给服务器用的
(5).<ahref=”/day05/form1.html”>ddd给浏览器用的
(6).<formaction=”/day05/form1.html”>给浏览器用的
总结:写地址以斜杠开头,如果地址是给浏览器用的,这个斜杠代表一个网站,如果是给服务器用的,这个斜杠代表web应用.浏览器向服务器发送请求,就是给浏览器用的
- 防盗链
首先检查你是否从我指定的网页来的,没有的话,String referer =request.getHeader(“referer”);直接在地址栏上粘贴地址,还有就是 refer.startsWith(“http://localhost“);检查是否从首页跳转过来的.首页上放广告,再有凤姐日记的链接.网站就是靠 广告运行的.
13.输出随机认证码图片
(1).BufferedImage:内存中的一幅图片.构造函数指定了图片的长和宽,像图片上写随机数,getGraphics()方法返回一个 图形的对象,然后向该图像上写数据.在把内存中的这幅图片输出到浏览器,ImageIO图像的输入输出;write();方法,指定一个和浏览器相关的输 出流.
(2).告诉浏览器以图片的方式读取数据.
(3).<imgsrc=”/day04/servlet/ResponseDemo3″>;
(4).刷新后图片为改变,没有控制浏览器是否进行缓存,浏览器默认是进行缓存的,所以每次拿的都是缓存图片,没有改变,所以要控制浏览器不要缓存,
response.setDateHeader(“expries”,-1);response.setHeader(Cache- Control”,”no-cache”);response.setHeader(“Parma”,”no-cache”);必须三个都要设置好,才起 作用.刷新有两个作用:重新向服务器发出请求,还有就是把上一次的事情在干一次.(防止表单重复提交);
(5).<imgsrc=”/day05/servlet/ResponseDemo4″ onclick=”change(this)”alt=”换一张”style=”cusor:hand”>
< scripttype=”text/javascript”>function change(img){img.src = img.src+”?”+new Date().getTime()}如果后面不跟随机数,还是拿缓存了.
14. 用Expires头控制浏览器缓存
(1).控制浏览器缓存,在servlet向客户会送的数据不变,就需要进行缓存,不需要向服务器发送请求,只需要到硬盘的缓存存放文件夹中读取缓存
(2).Internet选项->常规->点击设置->查看文件,浏览器把index.jsp缓存了,缓存时间是当前时间值:System.currentTime()+1000*3600;
15. 用refresh控制浏览器定时刷新
(1).刷新头:response.setHeade(“refresh”,”3;url=\’/day04/index.jsp\'”);控制浏览器每隔3秒刷新一次,
(2).假设是一个用于登陆的servlet:提交用户名和密码,需要到数据库查询是否登陆成功,response.getWriter(“恭喜 你,登陆成功,本浏览器将在3秒后,跳到首页,如果没有调,请点击点击“);
(3).this.getServletContext().getRequestDispatcher(“/message.jsp”).forword(request,response);
(4).servlet怎么告诉jsp定时刷新.字符串写给jsp”<metahttp-equiv=\’refresh\’conten=\’3;url=/day08/index.jsp\’>”
第六天:
- Cookie的细节
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(name)和设置值(value),一个web站点可以给以一个web浏览器 发送多个Cookie,一个web浏览器也可以存储多个web站点提供的Cookie,浏览器一般只允许存放300个Cookie,每个站点最多存放20 个Cookie,每个Cookie的大小限制为4KB,如果创建了一个cookie,并将他发送到浏览器,默认情况下它是浏览器之后即被删除,若希望浏览 器将该cookie存储到磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间,将最大失效设置为0,则是命令浏览器删除该cookie,注意, 删除cookie时,path必须一致,否则不会删除.cookie不能太大,不然可能造成网络拥堵,也可以将cookie删除.当两个cookie的名 称相同时,删除其中一个,就是删除两个.即这两个cookie必须相同,setPath();也要设置.可以到ie保存Cookie的文件中查看文 件.javascript也可以删除cookie
2.Cookie显示用户上次访问网站的时间
(1).javax.servlet.http.Cookie类用于创建一个Cookie,response接口也定义了一个addCookie方 法,它用于在其响应头中增加了一个相应的Set-Cookies方法,它用于获取客户端提交的Cookie,使用Cookie封装用户的数据.
(2).构造函数,Cookie(name,value);给Cookie一个名称name,用户下一次访问时,带着上一次访问的Cookiet, 所以在Request.getCookies();返回一个Cookie数组,即用户的所有Cookie,Cookie的有效期默认是浏览器的进程过程, 可以通过setMaxAge()方法设置有效期,案例:用户在一段时间内自动登录。方法setPath();用于设置访问哪个web资源时携带 Cookie,方法setDomain(),设置访问哪个域名时携带Cookie.IE默认禁止这种第三方Cookie,你访问我的网站,我给你带回一个 的网站的Cookie.
(3).用户第一次访问时,没有携带Cookie,Cookie cookie[] =request.getCookies();cookie可能为空,
首先要判断一下是否为空,
for(inti=0;cookies!=null&&i<cookies.length;i++){if(cookies[i].getName().equals(“lastAccessTime”)
{long cookieValue= Long.parseLong(cookies[i].getValues()}};
新建一个
Cookie:Cookiecookies = new Cookie(“lastAccessTime”,System.currentTimeMillis());
设置Cookie有效期:cookie.setMaxAge(,,,);
设置有效路径(默认的是”/day04/servlet”);cookie.setPath(“/day04”);
3.session的工作原理
(1).如果把Cookie禁止,则不能购买东西,Internet选项->隐私->高级
(2).URL重写,你访问我的服务器,都是超链接点击过来的,不同用户访问首页时,就帮用户创建session得到session的id号,然后将id号放在超链接URL中携带过来,不是Cookie携带了,所以所有的URL要重写,
request.getSession();Stringurl = response.encodeURL(“/day03/servlet/SessionDemo”)此方法自动将session的id号加入该地址 中.点击
(3).如果没有禁止Cookie,浏览器带一个Cookie来了,就不会进行URL重写
4.session的一些细节问题
(1).一个浏览器就占用一个session,开一个新的网页,不创建session,超链接弹出的新窗口也是共享一个session,同时开多个 浏览器,创建多个session,这个问题也不是绝对的,不同的浏览器,功能不一样,将session的id号写到浏览器进程,
5.Session简介
(1).默认情况下,一个浏览器独占一个session对象
(2).HttpSessionsession = request.getSession();
session.setAttribute(“name”,”value”);
session.getAttribute(“name”);
(3).写好过滤器,就可以解决web应用中的乱码问题
(4).一个session只为一个会话服务.(只打开一个浏览器窗口)
(5).session的生命周期,第一次访问getSession()方法时,session就被创建,session是30分钟没有人用了(即使浏览器不关闭),服务器就将其删除.而不是结束会话服务.当然这个时间可以实现的.
10</session- timeout>单位是分钟,同时在代码中也可以控 制,session.invalidate();request.getSession(true)方法是指:有session,不创建,没有 session就创建,request.getSession(false)方法是指:只获取session,不创建session,显示购物车的时候, 没必要创建session只需要获取session.
(6).request.getSession()方法怎么知道获取指定用户的session,即session的工作原理:servlet1 中:session=request.getSession(),产生一个session的id号,以Cookie的形式回写给用户,下一次用户就带着 session的id号来,所以该方法就知道获取指定用户的session,但是这个Cookie没有写有效期,会话结束后,这个id号就没有了,下一次 访问,服务器又要创建session,买东西的过程中,关闭浏览器,下一次再接着买,上次买的东西,都没有了,所以解决这个问题,只需设置到这个 Cookie的有效期即可.sessionid = session.getId();回写一个Cookie,名称为JSESSIONID,值为sessionid,覆盖默认的Cookie.
6.防止表单的重复提交
(1).用javascript防止表单的重复提交,
<formaciton=”/day01/servlet/Demo1″ method=”post”onsubmit=”return dosubmit()”>客户端阻止,第一个问题是,用户可以查看页面的源代码,修改js代码,用户也可以点击刷新,把上次干的事在干一次,也可以 点击后退按钮.但是在开发过程中还是用js,
(2).在服务器端防止表单提交,表单是由程序给出,为用户提交的表单提供一个随机数(表单号),服务器端,查看表单的id号,检查表单是否提交过 了,如果提交了,删除该表单的id号,产生令牌的发生器class TokenProcessor{}为了保证令牌是独立的,一般讲其设置为单例模式,是一个对象创建的随机数重复性低,还是多个对象创建的随机数重复对象 低,是后一种重复性低,为了得到随机数的长短一样,就要用数据的指纹(摘要),数据的指纹都是一样大的,是128位,类MessageDigest dis =MessageDigest.getInstatnce(“md5”);使用md5码,byte[] md5 = dis.digest(input);input是传过来的数据,用字节数组变成字符串返回,用到新的算法:base64编码,任何数据的base64码 变成ASCII码,原理:将数据字节变成四个字节,0011 0010 1100 1101 0010 1001,这三个字节变成四个字节,每六位装到一个字节,少两位,就在前面补两个零,为:00001100 00101100 00110100 00101001,最小数为0,最大数为63,不会超过64,base64自己定义了一个码表,比如:0:a,1:b,3:c ……..63: 所以任何数据都可以变成键盘上对应的字符,人们熟悉的字符,应用在数据的传输过程中,需要给数据的带一个结束符号和开始符号,所以把要传输的数据变成 base64,开始符号和结束符号使用base64中没有的字符即可,BASE64Encoder encoder=newBASE64Encoder();return encoder.encoder(md5);这个方法可能在api中查找不到,
(3).在servlet中产生一个令牌String token 然后跳到jsp中,这是将token存到session域中,而不是request中,因为token是id号,以后还要使用,在jsp 中<input type=”hidden”name=”token” value=”${token}”>在用户不知道的情况下将令牌带过去,
(4).将已经提交过的表单号删除,struts中就是这样防止表单的重复提交的.
7.会话管理
(1).会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话,
(2).会话过程中要解决的一些问题:每个用户与服务器进行交互的过程中,各自会有一些数据,程序想办法保存每个用户的数据,例如:用户点击超链接 通过一个servlet购买一个商品,程序应该保存用户购买的商品,以便用户点结账servlet时,结账servlet可以得到用户商品,为用户结账。
(3).如果用户的数据存到request中,结账servlet是一个重新的浏览器请求,所以结账servlet与购买servlet是两次请 求,不是共享request,所以结账servlet不能得到购买servlet的内容.ServletContext存在并发问题
(4).一般使用Cookie和Session;Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用 户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去,这样,web资源处理的就是用户各自的数据,你找我买个的东西,买完了东西,你带回 去(可能将东西cookie放在ie缓存,在本地硬盘中),当你来结账时,把东西在带来,即访问结账请求,浏览器拿缓存(cookie);
(5).Session是服务器端技术,利用这个技术,服务器在运行时可以为每个用户的浏览器创建一个其独享的Session对象,由于 session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他 web资源时,其他web资源再从用户各自的session中取出数据为用户服务.用户的数据存在服务器端.购买Servlet:session =request.getSession();Session.setAttribute(name,object);结账 Servlet:Session=request.getSession();obj=Session.getAttribute(name);不会再为 这个用户创建一个session,而去拿服务器中该用户的session
8.三个域对象的总结
(1).request,session,servletContext三个域:request:程序显示完,数据没有用了,就用 request(转发);session:程序显示完数据后,该数据还有用,就用session,servletContext:显示完了,除了该自己 用,还要给别人用(聊天室)
(2).md5码,数据指纹,保存用户名的密码,为了安全性,将密码的指纹保存,根据md5码反推,需要时间很长,也可以暴力破解,因为密码的长度是一定的,所以一般把数据加上一个随机数,还有一种用途是进行数据完整性的校验,
第七天:
-
jsp入门和jsp运行原理
(1).<%Date date= new Date();out.write(date.toLocaleString();%>显示当前时间.
(2).jsp的运行原理:首先将jsp中翻译成servlet放在服务器的work目录下,调用servlet的service方法,在这个方法 中将jsp中内容通过流out.write()写到浏览器中,jsp中的java代码将原封不动的运行,可以查看jsp的servlet代码,查看所有定 义的对象,不仅有out对象,还有其他对象,JspWriter就相当于PrintWriter
(3).最佳实践:一种技术可以用在多个地方,但是只有一个最佳的地方就是最佳实践.
-
jsp语法page指令详解
(1).修改jsp的模板,进入到MyEclipse,搜索servlet.java,在这个目录下,点开jsp找到Jsp.vtl
(2).jsp指令是为jsp引擎,引擎就是将jsp翻译成servlet的程序,他们并不直接产生任何可见输出,而是告诉引擎如何处理jsp页面中的其余部分,在jsp2.0规范中共定义了三个指令:page指令,include指令,taglib指令
(3).指令的语法:<%@ 指令属性名=“值”%>,不会产生任何输出,举例:<%@ pagecontentType=”text/html;charset=gb2312″%>,如果一个指令有多个属性,这多个属性可以写在一个指 令中,也可以分开写,例如:<%@ pagecontenType=”text/html”;charsetgb2312″%><%@ pageimport=”java.util.Date”%>也可以写作<%@ pagecontentType=”text/html;charset=gb2312″ import=”java.util.Date”%>
(4).page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它的作用都是整个JSP页面,为了保持程序的可读性和遵循良好的变成习惯,page指令最好是放在整个JSP页面的起始位置.
(5).JSP2.0规范中定义的page指令的完整语法:
<%@ page
[language=”java”]
[extends=”package.class”]
[import=”{package.class|package.*},…”]
JSP引擎自动导入下面的 包:java.lang.;javax.servlet.;javax.servlet.jsp;javax.servlet.http;可以在一条 page指令的import属性中引入多个类或包,其中的每个包或类之间使用逗号分隔:<%@ pageimport=”java.util.Date,java.sql.,java.io.“%>
[session=”true|false”]:session是否创建,如果为true,则翻译成servlet时,就创建一个session, 否则不创建,设置true,后就可以在JSP中片段中使用session对象,否则不能使用,默认值为true,因为session的周期比较长,为了减 轻服务器的负载
[buffer=none|8kb|sizeKb]:默认值为none,jsp的out直接写到response中,没有缓冲了
[autoFlush=”true|false”]:自动刷新,默认值为true
[isThreadSafe=”true|false”]:JSP是否是线程安全的,设置true后,将发现翻译后的servlet就继承了SingleThreade接口,一个servlet只为一次请求服务,不会出现线程安全问题
[errorPage=”relative_url”]:指定JSP错误的处理页面,errorPage属性的设置值必须使用相对路径,如果 以”/”开头,表示相对于当前web应用程序的更目录(注意不是站点根目录),否则,表示相对于当前页面,errorPage=”/errors /error.jsp”;也可以在web.xml文件中使用元素为整个web应用程序设置错误处理页面,其中 的子元素指定异常类的完全限定名,元素指定以”/”开头的错误处理页面的 路径.作用域不同一个是在一个页面,一个是全局的配置,java.lang.ArithmeticException></exception- type>/errors/error.jsp</error- page>;404</error- code>/errors/404.jsp</error- page>;如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用,全局性的优先级 高,会覆盖页面的配置
[isErrorPage=”true|false”]:这个页面是否为错误处理页面,默认值为false,好处是:服务器在翻译成servlet 时将异常封装成一个对象,九大隐式对象中包含一个Excepiton,但是这个对象并不是任何时候都有,只有设置这个参数后,才有,记住
[contentType=”mimeType[ ;charset=charachterSet]”|”text/html;charset=ISO-8859-1″]页面的类型
[pageEncoding=”charachterSet|ISO-8859-1″]:页面的编码
(6).jsp乱码问题:Jsp程序存在有与Servlet程序完全相同的中文乱码问题,输出响应正文时出现的中文乱码问题,读取浏览器传递的参数 信息时出现的中文乱码问题,Jsp引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题,jsp引擎将jsp源文件翻译成servlet 源文件默认采用UTF-8编码,而jsp开发人员可以采用各种字符集编码来编写jsp源文件,因此,jsp引擎将jsp源文件翻译成servlet源文件 时,需要进行字符编码的转换,如果jsp文件中没有说明他采用的字符集编码,jsp引擎将把它当做默认的ISO8859-1字符集编码处理,通过page 指令的contentType属性说明JSP源文件的字符集编码,page指令的pageEncoding属性说明JSP源文件的字符集编码
(7).tomcat6已经不存在乱码问题了,在jsp中是”中国”,将”中国”保存到硬盘中,默认的查本机的码表,web服务器,翻译jsp的时 候就是用iso8859-1码表,所以翻译后的servlet中的”中国”将是乱码,所以要改变服务器的编码,所以就用 pageEncoding=”gb2312″设置服务器翻译的码表,翻译到servlet后”中国”是正常的,但是此时还要设置浏览器以哪个码表打开所以 需要设置:contentType=”text/html;charset=UTF-8″,其实最后的一个设置不需要设置了,因为response是以 UTF-8编码的
-
jsp中常用标签
(1).jsp标签也称之为Jsp Action(jsp动作)元素,它用于在jsp页面中提供业务逻辑功能,避免在jsp页面中直接编写java代码,造成jsp页面难以维护.
(2).jsp:include,jsp:forward:<jsp:forwardpage=”/index.jsp”& gt;</jsp:forward>应用场景:通常为网站配置首页,首页是个servlet,显示是jsp,配置首页的时候,servlet 是无效的,但是jsp是有效的,所以可以使用这个标签从jsp跳转到servlet.<jsp:includepage=”/1.jsp”& gt;</jsp:include>是动态包含,翻译成两个servlet,在运行时进行合并,静态包含是在源代码的基础上进行合 并jsp:param标签是设置参数,<jsp:forward page=”/servelet/ServletDemo”><jsp:paramname=”username” value=”xxxx”/></jsp:forward>,跳转到servlet时带数据过去,value可以是一个脚本表达式& lt;%=x%>,x为变量.
-
div+css
(1).盒子模型:每一块数据都用div套起来,可能控制div的边框,属性border,上边框:Border-top;下边框:Border- bottom;左边框:Border-left;右边框:Border-right,Padding-top,Padding- bottom,Padding-left,Padding-right;控制数据在div盒子中的位置,Margin-top,Margin- bottom,Margin-left,Margin-right:控制一个盒子在页面的位置,
(2).div是个行级元素,默认的是div单独排在一行,有时想将两个div排成一行,这是就要用到定位技术:Float和Position两种技术
(3).\3c/p>
\3cp>body { margin: 4px 3px 2px 1px }
\3c/p>
\3ch1 id=”father”>father { }
\3c/p>
\3ch1 id=”son1floatleft”>son1 { float: left }
\3c/h2>
\3ch1 id=”son2floatleft”>son2 { float: left }
\3c/h2>
\3ch1 id=”son3floatleft”>son3 { float: left }
<body>
<divid=”son1″>aaaaaaa>
<divid=”son2″>bbbbbb
</body>
这个代码是有问题的,当添加
时,也会浮动,受到前面几个div的影响,所以要清楚浮动效果< divid=”clear”>,#clear{clear:both;}
(4).position技术就是将#son1{position:relative;left:60%}
5.jsp九大隐式对象
(1).每个jsp页面在第一次被访问时,web容器都会把请求交给JSP引擎(就是一个Java程序)去处理,JSP引擎先将JSP翻译成一个 _jspServlet(实质上也是一个servlet),然后按照servlet的调用方式进行调用,由于JSP第一次访问时会翻译成servlet, 所以第一次访问通常会比较慢,但是第二次访问,JSP引擎如果发现JSP没有变化,就不在翻译,而是直接调用,所以程序的执行效率不会受到影响,JSP引 擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用,JSP技术的设计者为便于开发人 员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用,
(2).HttpServletRequestrequest,HttpServletResponse response,ServletContextapplication,ServletConfig config JspWriter out,Exception,PageContextpageContext,Object page,Session session,具体的可以查看文档
6.jsp映射和jsp常见错误处理
在web.xml中
xxx/1.jspxxx/12.html
7.jsp语法
(1).jsp语法:jsp模板元素,jsp表达式,jsp脚本片段,jsp注释,jsp指令,jsp标签,jsp内置对象,如何查找jsp页面中的错误
(2).jsp脚本表达式(expression)用于将程序数据输出到客户端:语法:<%=变量或表达式%>举例:当前时间:& lt;%=new java.util.Date()%>;jsp引擎在翻译脚本表达式时,会将程序数据转成字符串,然后再相应位置用out.print(…)将 数据输出给客户端,jsp脚本表达式中的变量或表达式后面不能有分号(