Java web笔记
Web应用的部署方式:
1、直接把要部署的工程的web-root拷贝到tomcat的webapps文件下。a)通常采用集成开发工具进行部署。2、采用虚路径(逻辑路径)的方式部署。
a)在tomcat的server.xml文件的host标签下加入如下标签:
b)其中path表示应用的context-rootDocbase表示应用程序的实际路径。
Context-root:
是web应用程序中URI的第一级路径。
练习:编写一个index.html文件,然后在index.html中添加超链接,连接到hello.html.
配置web应用的欢迎界面
当用户请求的URI地址与context-root匹配时,web应用会转到欢迎界面。欢迎界面的配置,配置到web.xml中的welcome-file-list标签。
Servelt的使用。
一、新建一个类,该类继承httpservlet
二、重写该类中的doget或dopost方法,用来处理用户的get请求或者post请求。三、在web.xml中配置servlet,分别配置如下标签
a)1.:表示的是servlet的逻辑名
2.:表示的是servlet的实际路径名。
b)1.:表示的是servlet的逻辑名
2.:表示的是servlet截获什么样的请求。发请求的方式:
Get方式:直接在地址栏中输入URL,敲回车
中的method不写,或者method=”get”POST:中的method=”post”
Servelt:
概念:servlet是一个与平台无关的服务器组件,它的运行,方法调用、实例化、初始化、销毁都是由容器来完成的。Servelt主要负责处理客户端发送过来的请求,并给客户端做出响应。API:javax.servlet,javax.servelt.httpHTTP协议:请求与响应对象请求中的参数格式
URI?参数名=参数值&参数名=参数值
练习:做一个登录界面,在页面上输入用户名和密码,点提交,使用servlet来截获用去的请求,当用户输入的用户名和密码为admin时,在成功页面显示欢迎您XXXX,登录成功,否则显示对不起XXX,登录失败。
Get和Post请求方式的差异:
1、传送数据的大小,get方式较小,post较大。2、是否安全:get相对不安全,post相对安全
3、是否改变服务器的状态:get不改变,post改变。
4、是否是默认方式的请求:get是默认的,post不是默认的。
注意:在实际编写程序时,尽量使用post方式发送请求。
练习:做一个注册界面,在页面放置各种不同的元素,在请求对象中读取参数值,并显示在页面上。用户名:文本框
密码:密码框
性别:单选框(男,女)
爱好:复选框(游泳,足球,下棋,唱歌)用户编号:hidden个人简历:文本域
籍贯:下拉框.(辽宁、吉林、山东、河北)提交按钮、重置按钮路径问题
当前服务器路径::8088/,也就是URL的前两部分。
当前应用路径::8088/context-root,也就是URL的全部。
在FORM标签中:
如果action的路径是以/开头,那么表示请求是发送到“当前服务器路径”+action的值。
如果action的路径不以/开头,那么表示请求是从当前的URL开始发送,也就是当前的URL+action的值。
如果以./开头,也表示从当前的URL开始发送。
如果以../开头,表示从当前的URL向上退一级+action的值。
当使用超链接提交请求时,必须自己构造URL,如:Login
注意:中的路径问题和Form的action属性,所表示的含义是一样的。
如果href的路径是以/开头,那么表示请求是从“当前服务器路径”开始发送。
如果href的路径不以/开头,那么表示请求是从当前的URL开始发送。如果href的路径以./开头,也表示从当前的URL开始发送。如果href的路径以../开头,表示从当前的URL向上退一级。
Servlet对象的生存周期
1、加载
2、实例化,调用构造器3、初始化,int4、处理请求,service5、销毁:destroy
load-on-startup选项:
1、在服务器启动的时候执行servlet的实例化及初始化工作。
2、此Servlet在整个web应用中装载的次序。数值越小,越先装载。(通常是应用程序中有多个servlet的时候,servelt之间有相互调用,可以用此选项决定servlet的加载顺序)
servlet配置的参数:
1.配置:在web.xml中的servlet标签下配置子标签
2.读取:在servlet中调用this.getServletConfig.getInitParamter(String
name)JSP的生命周期
1、jsp翻译成Servlet源码2、编译成字节码文件3、加载
4、实例化:调用构造器5、初始化:调用jspInit6、处理请求:调用jspservice7、销毁:调用jspDestroy
Jsp第一次运行较慢的原因:因为第一次运行是要进行翻译和编译的。以后就直接从第三步开始了。
JPS中的静态HTML代码处理
写法:直接和在.html中一样处理:直接写到输出流中。
JSP脚本元素的处理
一、ScriptLet:定义java代码
a)写法:
b)处理:直接被翻译到jspservice方法中二、Jsp表达式:在页面输出。
a)写法:
b)处理:被翻译到jspservice方法中输出流中
练习:做一个登录页面,请求有jsp来处理,当用户和密码都为admin时,显示welcome,xxx,否则显示sorry,xxx
三、JSP声明:定义一些变量及方法。
a)写法:
b)处理:被翻译成jsp的成员变量和成员方法四、Jsp注释:
a)写法:
b)处理:在翻译的时候被忽略掉。五、HTML注释:
a)写法:
b)处理:被翻译到输出流中,客户端解析的时候忽略掉。六、Java注释:
a)写法:
b)处理:直接被翻译成jspService方法中的java注释。
练习:
1、自己写一个jsp文件,在其中包含jsp声明及注释,注意这些脚本元素的处理。
2、定义一个jsp文件,使用Jsp脚本元素,在页面上循环输出10行记录,每个记录包含两列,列名分别为姓名,年龄,数据如下:
序号12345678910姓名张三1张三2张三3张三4张三5张三6张三7张三8张三9张三10年龄21222324252627282930JSP中隐式对象(预定义变量)
事先被声明并且初始化好的对象。HttpServletRequest
二、response:表示一个响应对象,里面封装着对用户的相应信息,由容器创建,类型为:
HtttpServletResponse。三、session:表示一个用户和系统的一系列交互,里面包含很多request,由容器创建,类型
类:HttSession
练习:自己练习reqeust、response、session对象的使用。a)当重新开启一个浏览器时,是一个新的session对象。
b)当通过开始-新建一个浏览器窗口时,保持原有的session对象。
四、application:表示一个web应用,里面可以封装整个web应用都能使用的属性,由容器
创建,类型为:ServletContext五、pageContext:表示当前页面的对象,里面可以封装只能本页面使用的一些属性,由容器
创建,类型为:PageContext练习:
1、做一个jsp,分别向pageContext,request,session,application四个对象中放置一个属性,属性名为a1,属性值不同,然后再从4个对象中分别取出属性a1,观察结果。
2、做三个jsp,分别a.jsp,b.jsp,c.jspa页面上连接到b,b上连接到c,在a页面上分别向
pageContext,request,session,application四个对象中放置一个属性,属性名分别为h1,h2,h3,h4,属性值为一个包含10个String对象的List,在b页面和c页面分别从4个对象取出这个list,观察结果。
一、request:表示一个请求对象,里面封装着用户的请求信息,由容器创建,类型为:
扩展阅读:java web笔记大全
收集整理
javaweb笔记大全
Lesson1
一、eclipse工具的使用
1.java代码的位置
1)选择工作空间workspace选择一个文件夹存放程序(代码)不要用中文和空格2)新建一个java工程(Project)
3)建包建类
2.快捷键
alt+/:代码自动补齐,需要配置的打开preferences(首选项),搜keys,打开快捷键配置面板搜alt+/,取消绑定搜contentassist,取消原先的绑定,配置成alt+/
ctrl+1:错误自动修复,注意,放行的红叉是可修复的,圆形的是不可修复的导包的三种方式:
1)将类名敲完整,按下alt+/进行补齐,会自动导包2)ctrl+1,修正错误
3)ctrl+shift+o整理包,导入需要的包,去掉多余的导包语句ctrl+shift+f:代码格式化ctrl+2,L自动声明变量
shift+enter光标直接进入下一行ctrl+alt+方向键(向上向下)复制行alt+方向键(向上向下)移动当前行
3.断点调试
1)可以对程序进行调试
在行的开头双击左键打断点,用debug方式来运行程序,程序就会停留在断点位置
F5跳入(stepinto)跳入方法内部F6跳过,让当前行运行F7跳出返回上一层程序resume直接运行到下一个断点
2)查看源代码建议使用断点调试的方式,注意当前运行环境需要包含源码
4.junit单元测试
1)写一个java类,声明测试方式修饰符为publicvoid,在方法前面加注解,(@Test)此方法就可以进行测试了(交给junit运行)2)需要在测试方法前做初始化工作
写一个静态方法publicstaticvoidinit()
在方法前加注解@BeforeClass
收集整理
3)需要在测试后释放资源写一个静态方法在方法前加注解@AfterClass
二、jdk5新特性
1.静态导入
1)导入类的静态属性importstaticjava.lang.System.out;out.println("haha");2)导入类的静态方法importstaticjava.lang.Math.*;//导入Math类的所有静态成员intnum=abs(-10);2.增强for循环
1)作用:对存储对象的容器进行迭代2)jdk5以前怎么迭代3)增强for循环迭代数组
String[]arr={"a","b","c"};//传统方式for(inti=0;iIntegerbyte-->Byteshort-->Shortlong-->Longchar-->Characterdouble-->Double
收集整理
float-->Float
boolean-->Boolean
1)Integerx=1;x=x+1;经历了什么过程?装箱拆箱装箱
2)为了优化,虚拟机为包装类提供了缓冲池,Integer池的大小-128~127一个字节的大小3)String池Java为了优化字符串操作提供了一个缓冲池面试题:Strings=“abc”和Strings=newString(“abc”)的区别Strings=newString(“abc”)创建了几个对象Strings=“a”+“b”+“c”+“d”创建了几个对象Strings1=“a”Strings2=“b”Strings3=s1+s2;s3==”ab”?/*1.Strings="abc",虚拟机首先会检查String池里有没有"abc"对象(通过equals方法)
//如果有,直接返回引用,如果没有,会在池里创建一个“abc”对象,并返回引用Strings1="abc";Strings2="abc";System.out.println(s1==s2);//result:true*//*2.Stringstr=newString("abc");//此时,负责检查并维护缓冲池,其实堆内存的对象是缓冲池中"abc"对象的一个拷贝Strings1=newString("abc");Strings2=newString("abc");System.out.println(s1==s2);//result:false*//*3.Strings="a"+"b"+"c"+"d";java编译器有个合并已知量的优化功能//在编译阶段就把"a"+"b"+"c"+"d"合并为”abcd“Strings="a"+"b"+"c"+"d";System.out.println(s=="abcd");//result:true*//*4.Strings1="a";Strings2="b";Strings3=s1+s2;//String是常量,不能相加的,java如何实现的?StringBuildersb=newStringBuidler(s1);sb.append(s2);s3=sb.toString();也就是说实际上s3是方法返回的String对象凡是方法返回的字符串对象都是在堆内存的*/Strings1="a";Strings2="b";3
不管缓冲池是否有"abc",都会在堆内存创建一个"abc"对象,返回引用//Strings="abcd";收集整理Strings3=s1+s2;//堆内存的对象System.out.println(s3=="ab");//result:false4)单列集合Collection
Listlist=newArrayList();list.add("aaa");list.add("bbb");list.add("ccc");//传统方式1/*1.获得迭代器Iteratoriter=list.iterator();//2.循环判断迭代器是否有下一个while(iter.hasNext()){}*///传统方式2for(Iteratoriter=list.iterator();iter.hasNext();){}System.out.println("--------------------------------");//增强for循环,没有使用泛型的集合能不能使用增强for循环迭代?能for(Objectobj:list){}Strings=(String)obj;System.out.println(s);Strings=(String)iter.next();System.out.println(s);Stringstr=(String)iter.next();//将迭代器的指针移向下一个,并将迭代当前指向的元素返回System.out.println(str);5)双列集合Map
Mapmap=newHashMap();map.put("a","aaa");map.put("b","bbb");map.put("c","ccc");//传统方式迭代1//1.获得所有的keySetkeys=map.keySet();//2.迭代keys获得所有的keyIteratoriter=keys.iterator();while(iter.hasNext()){
Stringkey=(String)iter.next();//abc//3.根据key获得对应的value收集整理}System.out.println("---------------------------------");//传统方式2,必须掌握这种方式//1.获得所有的键值对Entry对象Setentrys=map.entrySet();//2.迭代出所有的entryiter=entrys.iterator();while(iter.hasNext()){}System.out.println("-------------------------------------");System.out.println("增强for循环迭代,");//增强for循环迭代,//原则上map集合是无法使用增强for循环来迭代的,//因为增强for循环只能针对实现了Iterable接口的集合进行迭代//Iterable是jdk5中新定义的接口,就一个方法iterator方法//只有实现了Iterable接口的类,才能保证一定有iterator方法//java有这样的限定是因为增强for循环内部还是用迭代器实现的//而实际上,我们可以通过某种方式来使用增强for循环for(Objectobj:map.entrySet()){}//obj依次表示EntryMap.Entryentry=(Entry)obj;System.out.println(entry.getKey()+"="+entry.getValue());Map.Entryentry=(Entry)iter.next();//分别获得key和valueStringkey=(String)entry.getKey();Stringvalue=(String)entry.getValue();System.out.println(key+"="+value);Stringvalue=(String)map.get(key);System.out.println(key+"="+value);6)集合迭代注意问题
//在使用迭代器迭代集合的过程中,不能对集合进行增删操作@Testpublicvoidtest4(){
Listlist=newArrayList();list.add("wangwu");list.add("zhangsan");list.add("lisi");Iteratoriter=list.iterator();while(iter.hasNext()){Stringname=(String)iter.next();if("wangwu".equals(name)){收集整理}@Testpublicvoidtest5(){}Listlist=newArrayList();list.add("aa");list.add("bb");//使用ListIterator迭代器ListIteratorlistIterator=list.listIterator();while(listIterator.hasNext()){}System.out.println(list.size());listIterator.next();//迭代过程中增加元素listIterator.add("cc");}System.out.println(list.size());//从集合中删掉//list.remove(name);//迭代过程中删除元素需要调用迭代器的方法//删除我迭代的集合被我迭代的最后一个元素iter.remove();}//1247)增强for循环注意问题
//在使用增强for循环时,不能对元素进行赋值int[]arr={1,2,3};for(intnum:arr){}System.out.println(arr[1]);num=0;
4.可变参数
1)jdk5中方法的形参可以定义为可变参数,传入实参个数可变//设计一个方法求n个数的和publicstaticintgetSum(int...arr){
//可变参数在方法中仍被看做一个数组intsum=0;for(intnum:arr)sum+=num;收集整理}returnsum;
2)Arrays.asList为例演示传入不同参数的情况//list长度为3Listlist=Arrays.asList("a","b","c");//list长度为1,因为考虑1.4语法String[]arr={"a","b","c"};Listlist=Arrays.asList(arr);//同时符合1.4和1.5的语法,此时会优先考虑1.4的语法//原因是有了新功能要保证以前的代码不出错,向后兼容//现在就需要将arr作为一个元素存入集合Objectobj=arr;Listlist2=Arrays.asList(obj);//此时只符合1.5的语法,不符合1.4的语法,没有歧义//优先考虑1.4,所以数组会拆开Listlist3=Arrays.asList(newObject[]{arr});//System.out.println(list3.size());//基本数据类型数组只符合1.5的语法int[]nums={1,2,3};list=Arrays.asList(nums);System.out.println(list.size());5.枚举
问题:对象的某个属性的值不能是任意的,必须为固定的一组取值其中的某一个解决办法:
1)在setGrade方法中做判断,不符合格式要求就抛出异常
2)直接限定用户的选择,通过自定义类模拟枚举的方式来限定用户的输入写一个Grade类,私有构造函数,对外提供5个静态的常量表示类的实例3)jdk5中新定义了枚举类型,专门用于解决此类问题
4)枚举就是一个特殊的java类,可以定义属性、方法、构造函数、实现接口、继承类//枚举类就是一个java类,也可以声明属性,方法,构造函数publicenumGrade4{}//枚举类就是一个java类,也可以继承抽象和实现接口publicenumGrade5{A("90-100"),B("80-89"),C("70-79"),D("60-69"),E("0-59");privateStringvalue;privateGrade4(Stringvalue){}publicStringgetValue(){}returnvalue;this.value=value;//抽象类不能创建实例对象A("90-100"){//new了一个Grade5的子类实例收集整理}},B("80-89"){},C("70-79"){},D("60-69"){},E("0-59"){};privateStringvalue;privateGrade5(Stringvalue){}publicStringgetValue(){}//对外提供一个方法,返回枚举的本地信息//一个方法不知道如何实现,可以定义为抽象的publicabstractStringtoLocaleString();returnvalue;this.value=value;//new了一个Grade5的子类实例publicStringtoLocaleString(){return"不及格";}//new了一个Grade5的子类实例publicStringtoLocaleString(){return"差";}//new了一个Grade5的子类实例publicStringtoLocaleString(){return"中";}//new了一个Grade5的子类实例publicStringtoLocaleString(){return"良";}publicStringtoLocaleString(){return"优";}练习:请编写一个关于星期几的枚举WeekDay,要求:
枚举值:Mon,Tue,Wed,Thu,Fri,Sat,Sun星期一。。。。星期日
收集整理
该枚举要有一个方法,调用该方法返回中文格式的星期。
6.反射
1)java代码的阶段:一段java代码在程序运行期间会经历三个阶段:source-->class-->runtime2)Class对象:在java中用一个Class对象来表示一个java类的class阶段
Class对象封装了一个java类中定义的成员变量、成员方法、构造方法、类名、包名等获得class对象的三种方式和区别://1.根据给定的类名来获得用于类加载Stringclassname="cn.itcast.reflect.Person";//来自配置文件Classclazz=Class.forName(classname);//此对象代表Person.class//2.如果拿到了对象,不知道是什么类型用于获得对象的类型Objectobj=newPerson();Classclazz1=obj.getClass();//获得对象具体的类型//3.如果是明确地获得某个类的Class对象主要用于传参Classclazz2=Person.class;//在java中所有的类型都会对应一个Class对象intIntegerClassintClazz=int.class;ClassintarrClazz=int[].class;ClassvoidClazz=void.class;3)反射
反射就是获得一个java类的各个组成部分//反射类的成员方法Classclazz=Person.class;Methodmethod=clazz.getMethod(methodName,newClass[]{paramClazz1,paramClazz2});method.invoke();//反射类的构造函数Constructorcon=clazz.getConstructor(newClass[]{paramClazz1,paramClazz2,...})con.newInstance(params...)//反射类的属性Fieldfield=clazz.getField(fieldName);field.setAccessible(true);field.setObject(value);4)反射用在哪里
到底框架是什么?框架就是将开发中大量重复的代码集中起来写个通用的程序框架就是用反射来实现的,框架需要现在的类调用将来写的类
框架是将来的程序员调用的,框架不能实现完整的功能,框架只是一些一些通用的代码;框架要依赖将来写的类来运行.
收集整理
现在写的类要调用将来写的类,我们先针对接口进行调用,将来的类需要实现接口,那么方法就固定了但是将来写的类的类名我们无法获知,这时就需要调用者通过配置文件告诉框架具体的类名
7.泛型
1)泛型是一种可变化的类型,类型不确定,需要调用者来指定
2)用途:一个类的多个成员方法用到的参数类型或返回值类型都是未知的类型,但又需要是同一个类型,就可将方法的参数类型定义为泛型,此泛型必须在类上先予以声明才能在方法中使用一个方法的多个参数和返回值需要是同一个类型,也可以用泛型来解决,在方法返回值前面声明泛型
泛型的细节:
1)泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型2)使用带泛型的类创建对象时,等式两边指定的泛型必须一致原因:编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了3)等式两边可以在任意一边使用泛型在另一边不使用(考虑向后兼容)
3.泛型的基本概念
以List为例:念着typeof例,List就是ListtypeofStringList中的E称为类型参数变量方法定义参数形式参数List中的Integer称为实际类型参数整个List称为泛型类型GenericType整个List称为参数化的泛型类型
4.泛型的使用1)使用带泛型的类时,在创建对象时可以为泛型指定实际类型参数,指定的具体类型相当于给泛型传参2)子类在继承父类的时候,可以为父类定义的泛型指定实际类型参数classBclassAextendsB通过子类A获得的父类类型就是一个参数化的类型3)调用方法时传入参数的具体类型将作为方法中泛型的实际类型
收集整理
Lesson2Servlet(超级重要)
1.javaweb学什么
用java语言开发动态的web资源,接下来就是介绍如何开发动态的web资源对于java程序员而言,所谓动态web资源就是可以运行在服务器上的java程序2.实现服务器管理java程序
开发人员写好一个java类,到底有哪些方法tomcat服务器是不可能知道的tomcat服务器欲执行我们编写的java类,就需要知道我们的java类有哪些方法,然后在适当的时间调用这些方法,所以我们在写的java程序要想运行在服务器上,就必须要实现一个特殊的接口Servlet.java
interfaceServlet{...}Servlet接口中就定义了可以被tomcat服务器调用的java方法通常来讲,我们将实现了Servlet接口的java类称之为Servlet编写好的Servlet需要在web.xml文件中做配置,才能供外界访问
3.实现第一个Servlet程序
3.1写一个java类实现Servlet接口packagecn.itcast.servlet;importjava.io.*;importjavax.servlet.*;publicclassHelloWorldServletextendsGenericServlet{//实现service方法publicvoidservice(ServletRequestrequest,ServletResponseresponse)throwsServletException,java.io.IOException{//向浏览器输出一句话PrintWriterout=response.getWriter();out.write("helloworld!!!");}publicvoidinit()throwsServletException{//初始化servlet时被调用System.out.println("init()");}publicvoiddestroy(){//摧毁servlet时被调用System.out.println("destroy()");}}收集整理
3.2.导入servletjar包
setclasspath=%classpath%;D:\\apache-tomcat-6.0.20\\lib\\servlet-api.jar3.3.编译带包的类
javac-d.HelloWorldServlet.java
3.4.将包拷贝至day05/WEB-INF/classes目录下-->发布web工程
3.5.在web.xml文件中做映射HelloWorldServletcn.itcast.servlet.HelloWorldServletHelloWorldServlet/HelloWorldServlet注意:servlet对象一旦创建就会驻留在内存中,为所有的请求服务,servlet对象什么时候销毁?直到服务器关闭时或web应用被移除才销毁
3.6.Servlet执行流程图
收集整理
:8080/day05/...ServletIE浏览器服务器Servlet1:找windows或dns解析出ip2:向服务器发送请求3:解析出主机名4:解析出虚拟目录(上下文路径)-day055:找到一个对应web应用6:解析出用户访问的资源名,找web.xml,找出对应的Servlet类名7:反射创建Servlet对象,调用init方法requesrt8:调用service方法response9:向response对象输出一句话,service方法就返回10:service方法返回11:从response中取出响应消息,发送给IE浏览器4.用eclipse工具开发Servlet
4.1.建一个webproject
4.2.在src下建包,创建一个java类实现Servlet接口4.3在Webroot\\WEB-INF\\web.xml做servlet映射4.4配置tomcat服务器window-->preferences-->tomcat6.x4.5将web工程发布至tomcat服务器发布的web应用名称可以配置:web工程右键选properties-->myeclipse-->web默认情况使用工程名作为发布后的web应用名4.6启动tomcat服务器运行程序
收集整理
5.HttpServlet对象
一般来讲我们开发一个Servlet会去继承HttpServlet
在eclipse下开发Servlet可以直接新建一个Servlet,覆写HttpServlet的doGet和doPost方法继承HttpServlet的原因是:HttpServlet实现了service方法,将ServletRequst和ServletResponse
强转为子类HttpServletRequest和HttpServletResponse,让我们用起来更加方便,同时,在service方法中,它判断了请求方式,根据请求方式来调用doGet和doPost
二、Servlet细节
1.*号统配符
一个Servlet可以映射为多个路径
在映射Servlet路径时可以使用/*‘或*.扩展名‘的形式注意:两者不能同时使用/*具有较高的优先级2.load-on-startup元素
元素下可以配置
如果一个Servlet配置了该项,web容器会在web应用被加载时就初始化该Servlet,数字越小则越先初始化3.tomcat\\conf\\web.xml
服务器下所有web应用中的web.xml都会自动继承该文件中所有的配置:8080/day05/a.htmla.html是资源名上面的url访问的url在web.xml文件中并没有配置
此时会去访问缺省的Servlet,在tomcat\\conf\\web.xml文件中就配置了一个缺省的DefaultServletDefaultServlet帮我们去web应用下读取a.html文件,并打给浏览器,如果没有发送404页面也就说,我们通过ie访问服务器访问的都是Servlet4.Servlet线程安全问题
解决Servlet线程安全问题:加上同步的锁(lock)实现SingleThreadModel接口的Servlet
服务器会做判断,当有请求过来,如果Servlet对象忙着呢,服务器会再创建一个Servlet对象为用户提供服务,如果Servlet闲置,就直接提供服务
这样的方式实际上是回避了线程安全问题,单线程访问Servlet,这样的方式不可取
Lesson3
一、WEB服务器1.基本概念
WEB在英语中即表示网页的意思,它用于表示Internet主机上供外界访问的资源以及超链接所组成的链表放在internet网上供外界访问的文件或程序被称为web资源web资源被分为:
静态web资源:html、css、jpg动态web资源:Servlet、Jsp
14收集整理
2.什么是WEB服务器?就是一台电脑,安装了一个服务器软件3.为什么需要安装WEB服务器
思考问题:从一台计算机的IE浏览器如何去访问另一台计算机中的文件3.1两台计算机是如何实现通讯的?IP地址(计算机的唯一标识)
IPV44个字节的整数,每个字节以点号隔开192.168.1.100每个字节的取值0~255在计算机中程序会绑定在某一个端口0~65535尽量用1024以上的连接一台计算机就需要输入ip地址和端口号作为接收方,应该绑定ip,监听指定的端口
3.2在本地写程序添加一个服务,供别人来访问,假设监听8888端口3.3编码实现了一个本地服务器程序作用:管理本地的资源,只要将html页面放到指定的目录下,外界就可以访问了
3.4安装服务器的目的:开发好的web资源可以发布到服务器上,这样外界就可以通过浏览器访问了
源程序:MyServer.java
//ServerSocket对象可以监听端口ServerSocketserversocket=newServerSocket(6666);while(true){Socketsocket=serversocket.accept();//等待客户端的连接请求,一旦有请求过来,就结束阻塞,返回客户端对象//一旦有客户来访问,就另开一个新线程去提供服务,main线程继续等待下一个客户的连接newThread(newMyService(socket)).start();}MyService.java//提供服务InputStreamin=socket.getInputStream();Thread.sleep(200);intlen=in.available();//估计此流不受阻塞能读取的字节数byte[]buffer=newbyte[len];in.read(buffer);Stringrequest=newString(buffer);//截取第一行StringfirstLine=request.substring(0,request.indexOf("\\n"));StringuriName=firstLine.split("")[1];OutputStreamout=socket.getOutputStream();//根据需要访问的资源创建File对象Filefile=newFile("src"+uriName);if(!file.exists()){out.write("对不起!您访问的资源不存在!别瞎搞!!".getBytes());out.close();return;}//从文件读,往浏览器写
收集整理FileInputStreamfis=newFileInputStream(file);buffer=newbyte[1024];while((len=fis.read(buffer))>0){out.write(buffer,0,len);}socket.close();二、Tomcat服务器的安装和配置
1.使用tomcat6.0.20.rar文件解压即完成安装2.tomcat就是一个java程序,一定会用到jre所以需要配置环境变量java_home配置成jdk的安装目录c:\\jdk1.6tomcat的启动是通过startup.bat文件,实际上startup.bat中是去调用catalina.bat文件,而且是通过%catalina_home%\\bin\\catalina.bat去找所以为了保证服务器启动正常,需要配置catalina_home环境变量为tomcat的安装目录3.tomcat的目录结构
bin:存放一些执行文件
conf:存放服务器的配置文件
lib:存放tomcat所依赖的jar文件logs:存放日志文件temp:存放临时文件
webapps:webapplications存放所有的web应用程序(web资源)work:tomcat的工作目录,jsp翻译成的Servlet就在这个目录下4.web应用
多个web资源存放在一个目录下即为一个web应用(web应用程序、web工程)web应用的目录结构静态web资源直接放在目录下java类放在classes目录下web.xml文件负责管理web应用下所有的web资源所有jar包放在lib目录下
三、WEB应用的映射
1.虚拟目录一个web应用(服务器上一个目录)需要供外界访问的路径,需要映射虚拟目录
在tomcat6中,放在webapps下的web应用,服务器会自动做映射(将文件夹名称作为虚拟路径)对于webapps目录外的web应用需要手动映射虚拟路径1.1.在server.xml文件可以配置
1.2.在%tomcat目录%\\conf\\catalina\\localhost下写一个xml文件
文件名就是虚拟目录
收集整理
多级目录配置aaa#bbb.xml对应/aaa/bbb如果文件名是ROOT.xml那就是配置了缺省的web应用,访问时不需要输入虚拟目录2.web.xml
Web.xml的作用:管理web应用下所有的web资源
通俗地讲,一个web应用下所有的web资源如何被外界访问都需要在此文件下做映射包括咱们后面学的Servletjsp都需要在这个文件中做映射
实验:配置web应用的首页
在web应用下新建目录WEB-INF,在此目录下新建web.xml文件itcast.html3.域名解析
一个完整url
http:\\\\:80\\itcast\\index.jsp
协议名主机名端口号资源名(uri)IE访问服务器的原理,
在IE中输入的地址中包含域名,域名就需要被翻译成服务器的IP,才能访问到服务器
收集整理
IE浏览器sina服务器看windows是否注册了该主机名DNS服务器(网络服务商)解析域名,获得一个IP4.web应用映射的练习:新建一个web应用配置成缺省的web应用配置首页
配置tomcat监听端口为80在windows中注册主机名5.虚拟主机
服务器允许在一个IP上配置多个主机,即虚拟主机:80/index.html中的起了两个作用:找DNS服务器,作为域名被解析为IP通过Host头告诉服务器访问的主机名
配置方式:在server.xml文件中配置Host元素,需要指定name(主机名)、appBase(默认web应用存放目录)appBase目录下所有的web应用,tomcat会自动映射虚拟路径
做实验:给新配置的虚拟主机配置缺省的web应用
收集整理
分析web资源访问过程
访问一个a.html静态web资源,IE做了什么事
1)将作为域名发送给DNS,解析成IP地址,访问一台服务器2)发送Host头(),告诉服务器我要访问的虚拟主机,服务器拿着Host头找匹配的Host元素3)将abc作为虚拟目录,告诉服务器我要访问的web应用,服务器拿着abc找匹配的web应用
4)将a.html作为资源名,告诉服务器我要访问的web资源,服务器拿着a.html去web.xml文件中找映射虚拟目录对应是一个web应用的目录,所以虚拟目录也被我们称作web应用路径(web应用的上下文contextpath)
三、http协议
1.tcp/ip协议:网络通信协议(连接)ip协议:127.0.0.1ip地址对应一台计算机(互联网层)tcp高级协议:三次握手,发送请求、返回响应、传输数据
2.http协议是建立在tcp协议的基础之上(应用层)
3.Http协议的版本(w3c)
Http1.0:建立连接,发送一次请求就断开Http1.1:建立连接,可以无限次发送请求
(传输层)
收集整理
四、http请求消息
http请求消息内容:包括一个请求行、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。请求行POST/itcast/HTTP/1.1消息头Accept:image/gif,image/x-xbitmap,*/*Referer::8080/itcast/Accept-Language:zh-CN,en-GB;q=0.8,ar-YE;q=0.7,ja-JP;q=0.5,de-CH;q=0.3,en-US;q=0.2Content-Type:application/x-www-form-urlencodedUA-CPU:x86Accept-Encoding:gzip,deflateUser-Agent:Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;GTB6.5;CIBA)Host:localhost:8080Content-Length:33Connection:Keep-AliveCache-Control:no-cacheCookie:JSESSIONID=B0B3FB4FFB0315B3D3C620548DD4E1EB空一行消息体username=zhangsan&password=123456
1.请求行GET/itcast/a.htmlHTTP/1.1
GET为请求方式:get方式的请求参数直接跟在url后面,例如:/itcast/a.html?username=aaa&password=111POST方式:post方式请求参数放在消息体中传输,相对安全,get大小限制1K,post无数据量限制
2.请求消息头:IE浏览器用于向服务器说明情况的(浏览器使用环境)Accept:text/html,image/*说明浏览器接受的数据类型Accept-Charset:ISO-8859-1说明浏览器使用的字符编码Accept-Encoding:gzip,compress说明浏览器支持的压缩格式Accept-Language:en-us,zh-cn说明浏览器的语言环境
Host::80说明浏览器要访问的主机名If-Modified-Since:Tue,11Jul201*18:23:51GMT文件的修改事件,用于做缓存Referer:说明请求来自哪里,防盗链(做实验)User-Agent:Mozilla/4.0(compatible;MSIE5.5;WindowsNT5.0)说明浏览器内核Cookie向服务器发送CookieConnection:close/Keep-Alive说明连接状态
Date:Tue,11Jul201*18:23:51GMT客户端计算机时间
3.实体内容(消息体)
收集整理
浏览器向服务器发送的数据,例如上传的文件、提交的表单等
五、http响应消息
http响应消息的内容包括:一个状态行(类比http请求信息的‖请求行‖)、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。HTTP/1.1200OKServer:Apache-Coyote/1.1Content-Type:text/html;charset=GB18030Content-Length:766Date:Thu,07Jul201*15:40:02GMTMyJSP"index.jsp"startingpagehello
1.状态行HTTP/1.1404NotFound
协议版本:目前普遍采用的都是http1.1响应状态码:说明服务器的响应状态
常用状态码状态码100~199200~299300~399400~499500~599含义表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程表示成功接收请求并已完成整个处理过程,常用200为完成请求,客户需进一步细化请求。例如,请求的资源已经移动一个新地址,常用302、307和304客户端的请求有错误,常用404服务器端出现错误,常用500200:一切OK
302\\307请求重定向,你访问我,我通知你访问另一个资源304通知浏览器去读缓存
404找不到资源,客户端的请求有错误
500服务器程序出错(服务器端的程序抛异常了)
收集整理
2.响应消息头服务器向浏览器说明情况(处理结果)
Location:通知浏览器去访问另一个资源Server:apachetomcat说明服务器Content-Encoding:gzip通知浏览器数据的压缩格式Content-Length:80通知浏览器发送数据的长度Content-Language:zh-cn通知浏览器语言环境Content-Type:text/html;charset=GB2312通知浏览器文件的格式和编码Last-Modified:Tue,11Jul201*18:23:51GMT告诉浏览器文件的修改时间Refresh:1;url=通知浏览器自动刷新
Content-Disposition:attachment;filename=aaa.zip通知浏览器以下载的方式打开资源Set-Cookie:SS=Q0=5Lb_nQ;path=/search发cookieExpires:-1//3种禁止缓存的头字段Cache-Control:no-cachePragma:no-cache
Connection:close/Keep-Alive连接状态Date:Tue,11Jul201*18:23:51GMT系统时间
3.实体内容(响应消息体)
一般为服务器发送给ie浏览器的页面数据
六、https协议
1.https是一种加密协议能保证数据的安全2.不对称加密对称加密3.https
1)制作数字证书
keytool-genkey-aliastomcat-keyalgRSA
2)将证书拷贝至tomcat\\conf
3)修改server.xml文件配置https连接器
收集整理
4)重启服务器打开ie访问https://localhost:84435)ie中安装证书
继续浏览
查看证书
收集整理
安装证书
删除证书:
收集整理
Lesson5
一、ServletConfig对象
作用:封装Servlet初始化参数
1.可以在web.xml文件中Servlet元素下为Servlet配置初始化参数nameaaaa2.web容器在初始化Servlet时,会将初始化参数封装到一个ServletConfig对象中,传给init方法3.我们在Servlet中覆写init方法,就可以获得ServletConfig
4.父类GenericServlet中定义了一个成员变量用于记住此对象,并提供了getServletConfig方法我们可以直接调用此方法获得config对象
5.再调用getInitParameter(name)方法获得想要配置项//指定编码//获得ServletConfig对象ServletConfigconfig=getServletConfig();Stringencoding=config.getInitParameter("encoding");
收集整理System.out.println("encoding="+encoding);二、ServletContext对象:ServletContext被称为servlet的上下文1.ServletContext对象代表整个web应用
2.ServletContext对象是一个“域”对象(即:可以存储数据的对象)
ServletContext对象的内部维护了一个map集合,key是String类型value是Object类型classServletContext{privateMapmap;}
3.ServletContext作为域对象,多个Servlet可以共享数据Servlet6//1.获得ServletContext对象ServletContextcontext=getServletContext();//2.存入域context.setAttribute(—name‖,—zhangsan‖);Servlet7//获得context域,getAttributeStringname=(String)getServletContext().getAttribute("name");4.获取web应用的初始化参数getContext().getInitParameter(—name‖);
5.统计一个web应用的访问量
在context域中维护一个count变量访问Servlet时,取出变量加1
6.实现请求转发
实现请求转发需要用到转发对象RequestDispatcher,RequestDispatcher有一个forward方法能转发请求7.如何读取工程中的文件(分两种情况)7.1.读取web工程下的资源文件//获得绝对路径StringrealPath=ServletContext.getRealPath(相对web应用的路径);注意URLurl=ServletContext.getResource();web的url//获得与文件关联的流InputStreamin=ServletContext.getResourceAsStream(—WEB-INF/classes/config.properties‖;7.2读取java工程下的文件
//不能相对虚拟机目录不能用绝对路径//只能类加载的方式读//获得流ClassLoaderclassLoader=Demo.class.getClassLoader();InputStreamin=classLoader.getResourceAsStream("a.txt");收集整理//获得绝对路径URLurl=Demo.class.getClassLoader().getResource("a.txt");Stringpath=url.getPath();
类加载方式缺点
1)不能读取类路径以外文件
2)由于需要加载到内存,不能读大文件3)web工程中如果用类加载的方式读
类加载实际上读取的是内存中加载的文件,此时将读不到硬盘上资源文件的修改解决办法:通过绝对路径去读硬盘上的文件避开内存的文件例如:Demo.Class.getClassLoader().getResource("a.txt").getPath()
三、Servlet缓存
HttpServlet的Service()方法中的代码//调用方法longlastModified=getLastModified(req);//如果为-1,就直接放行,给最新的if(lastModified==-1){doGet(req,resp);}//方法返回不是-1else{//读取IE发送的头If-Modified-SincelongifModifiedSince=req.getDateHeader(HEADER_IFMODSINCE);//拿着客户端的时间头和方法的返回值比较if(ifModifiedSince<(lastModified/1000*1000)){//Iftheservletmodtimeislater,calldoGet()//Rounddowntothenearestsecondforapropercompare//AifModifiedSinceof-1willalwaysbeless//方法的返回值大于ie发送过来的时间头//重新向浏览器发送了一个时间头maybeSetLastModified(resp,lastModified);//放行,发送页面doGet(req,resp);}else{//方法的返回值没有大于ie发送过来的时间头//发送304状态码,让用户去读缓存resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);}}
收集整理
Lesson6一、中文乱码问题
1.出现乱码的原因
1)在计算机中数据以二进制的形式进行存储的,数据的传输也是通二进制的形式2)需要存字符,会出现字符与字节之间的转换(输入字符读到的字符)3)字符和字节之间如何实现转换?都是通过查码表
4)字符到字节是编码,字节到字符是解码,编码和解码用到了不同码表就会出现乱码问题2.解决乱码
1)拿到乱码基本上都是由于解码错误导致的,解决办法,重新编码再解码2)以后将文件交给解析器,出现乱码,首先想到是否通知别人文件的编码格式
Servlet对象一旦创建就驻留在内存,
Request和response对象,web容器会针对每次用户的请求创建一个request和response请求结束,响应发给ie。Request和response对象就会立即被销毁
二、Response对象
1.responsegetWriter方法获得字符流,用于向浏览器输出字符数据","p":{"h":17.043,"w":315.406,"x":180.929,"y":729.538,"z":83},"ps":null,"s":{"lette收集整理
中文乱码问题
Response中国Tomcatweb容器中国默认编码iso-8859-16363utf-8989789IE浏览器6363>??gb2312解错码ServletgetWriter().write(—中国‖)2.文件下载
文件名中文乱码问题
由于文件名是跟着content-disposition头发送给浏览器的
凡是http头的数据都会经过url编码,编成全世界通用的符号,这样传输过程中才不会乱码3.请求重定向
发送302状态码和location头ie向浏览器发送了两次请求第一次直接请求资源,第二次重定向的页面地址栏是有变化
4.getWriter和getOutputStream不能同时使用,有冲突response的流我们不用关闭,交给web容器去管理
三、Request对象
1.request帮助我们取获取ie浏览器发送给服务器的请求消息(请求行消息头消息体)2.request获得请求参数:getParameter()和getParameterValues()
收集整理
3.request中文参数乱码问题
IE老张url编码utf-8%E8%80%81%E5%BC%A0tomcatweb容器%E8%80%81%E5%BC%A0request对象解码iso-8859-1è乱码程序setCharacterEncoding设置request编码Stringdata=getParameter()Request中文参数乱码的解决方法:1.表单提交post方式下:request.setCharacterEncoding(—utf-8‖);//指定处理消息体的解码方式2.表单提交get方式下:1)手动解决乱码问题byte[]bytes=username.getBytes("iso-8859-1");Stringstr=newString(bytes,"utf-8");2)在%tomcat%\\conf\\server.xml中找到当前连接器元素Connector配置URIEncoding属性它用于指定web容器的url解码方式3)配置useBodyEncodingForURI属性指定为true用于让tomcat按照处理消息体的编码方式处理消息头
超链接提交参数:也是使用get方式提交,(和表单的区别是,表单提交,ie会自动进行url编码)而超链接提交,ie不进行url编码,此时我们需要将超链接中的中文参数手动进行url编码.同理:在服务器端的处理方式和表单get方式的处理一样4.请求转发
Servlet负责处理用户的请求,处理完的结果交给jsp来做显示(在Servlet中不输出任何数据,所有数据的显示都交给jsp)获得RequestDispatcher对象做请求转发,1.请求转发时,需要将处理结果存入request域带给jsp2.请求转发时,web容器(如:tomcat)会清空response中的数据3.转发后,无法向response输入数据
面试题:请求转发forward和包含include的区别
收集整理
Forward的时候,web容器会清空response的数据,并且转发之后,当前Servlet就无法再写入数据了Include的时候,web容器会让两个Servlet的数据都写入response
mvc的过程
1)用户发送请求(提交表单,超链接)
2)Servlet做处理,将数据(响应结果)封装到javabean对象3)将javabean对象存入request域4)请求转发给jsp
5)jsp页面中从request域取出数据做显示
ServletIE浏览器javabeanjspWeb资源访问的流程
1.客户端(IE)发送请求给服务器2.用一个Servlet来响应客户的需求基本上分为两种:1)查看数据请求转发给jsp做显示
2)用户登陆\\购买商品完成某一个特定的功能结果都是成功或失败请求重定向到一个目标资源
面试题:请求转发和请求重定向的区别?
1)请求重定向地址栏有变化请求转发地址栏无变化
2)请求重定向客户端向服务器发送两次请求请求转发发送一次请求3)应用场景:一件事情做完了,应该做第二件事情了,就请求重定向(用户登陆、购物)Servlet处理完了,让jsp做显示,用请求转发(mvc设计模式)
收集整理
web应用中的路径怎么写?
读取web中的文件用context读取,严禁用绝对路径,通通以‖/‖开头
原则:就看路径是给浏览器用的还是给服务器用的,
给浏览器用的,要加上web应用的名称给服务器用的,斜线”/”即表示:当前web应用(/表示web应用,不用加web应用的名称)各种场景:
1)请求转发:地址是给服务器用的:/表示web应用,不用加web应用的名称/a.jspweb.xml文件中用到了路径:地址是给服务器用的,不需要加web应用/b.jsp/servlet/Servlet12)请求重定向:路径给浏览器用的,所以需要加上web应用名称/day06/a.jsp3)超链接:路径给浏览器用的,所以需要加上web应用名称/day06/a.jsp4)表单的action提交:路径给浏览器用的,/day06/a.jsp5)img标签的src属性:路径给浏览器用的,/day06/a.jpg6)scriptsrc:路径给浏览器用的/day06/js/a.js记住:路径以“/”开头,请求转发不加web应用名,其他的全部都要加Lesson7
会话技术(包括cookie和sessionCookie是客户端技术,Session是服务器端技术)1.会话,用户打开浏览器,点了一些超链接,关闭浏览器的过程
2.会话过程中会产生一些数据,这些数据是每个用户独享的,需要找个地方存起来3.会话技术就是解决上述问题的,Cookie是客户端技术,Session是服务器端技术
Cookie对象
1.Cookie对象的创建
Cookiecookie=newCookie(key,value);2.发送Cookie
Response.addCookie(cookie);3.获取指定的Cookie//获得用户发送的所有CookieCookie[]cookies=request.getCookies();//如果没发Cookie过来,为null//遍历找到lastAccessTimeStringlastAccessTime=null;for(inti=0;cookies!=null&&i收集整理
5.显示用户最近的浏览记录
两个页面
显示所有的商品(从数据库找出商品显示),显示最近的记录(读取客户发送的Cookie中存的id,找出书显示)CookieDemo2
显示商品的详细信息,并向客户端发送Cookie,难点如果产生新的Cookie
将客户端带过来的Cookie分割后存入集合,根据不同的情况将新的id加进去,迭代集合用分隔符串起来CookieDemo3
Session对象
1.session的原理
request对象有个方法是getSession()
首先看浏览器是否发送了Cookie(JSESSIONID),如果发了,拿着id去内存中找对应的session对象返回;如果没有发Cookie或者没找到对应的Session对象,创建一个新的Session对象getSession(booleancreate)
create为true的时候,如果内存有session就返回,没有就创建新的
create为false的时候,意味着只查找不创建,有就返回,没有不创建,返回null;
2.session的运行要依靠cookie来发送JSESSIONID
如果想让多个浏览器共享一个session,我们就需要人工发送Cookie,并设置Cookie的有效时间
3.如果浏览器禁用Cookie,那么Session也玩不起来了
要想让session好用,就需要在页面跳转时发送sessionid
有一个技术url重写:
重写后的地址会在原有的url地址的基础上加上JSESSIONID超链接或表单提交的地址,重写方式如下:StringnewUrl=response.encodeURL(url);请求重定向的地址,
重写方式如下:StringnewUrl=response.encodeRedirectURL(url);
3.session的应用(重点)
简单购物车的实现ListServletBuyServletListCartServlet
用户登录Login.jspLoginServletindes.jspLogoutServlet防止表单重复提交(2种方法)1.可以用js来做,但是只能增加用户的体验,不能完全防止坏人2.用session做防表单重复提交FormServletHandleFormServletTokenProcessor
Lesson13JSP入门全称:javaserverpage
1.web资源的运行原理
html:静态web资源,DefaultServlet读取html文件,通过response输出给IE浏览器
收集整理
Servlet:动态web资源,web容器(Servlet引擎)解析web.xml文件,找到url对应的java类通过反射创建Servlet对象,调用service方法Class.forName(—cn.itcast.servlet.Servlet1‖).newInstance();jsp:动态web资源jsp页面的执行过程:(重要)1.jsp页面在第一次被访问的时候,web容器(jsp引擎)会将jsp翻译成一个Servlet,然后调用servlet的service方法2.jsp翻译后的Servlet会被放到%tomcat安装目录%\\work\\Catalina\\localhost\\webcontext3.当jsp页面被再次访问的时候,web容器会去直接调用Servlet的service()方法,所以通常来讲jsp只是在第一次被访问的时候比较慢4.如果jsp页面做了修改,此时web容器会重新翻译jsp
2.jsp是什么
实际上jsp就是Servlet,只是提供了一种比较直观的书写方式,因为写jsp就像在写Htmljsp中可以写java代码,有两种jsp中写java代码的方法:1)jsp脚本表达式
内容会被放到out.print()里面,输出给浏览器格式:
2)jsp脚本片段
内容会原封不动地被翻译到Servlet的service方法中
3.jsp和Servlet的区别
1)Servlet适合写java代码,因为Servlet就是一个java类在开发中使用Servlet对用户发送的请求进行处理并做出响应2)jsp适合做数据美化,作为数据显示模板因为jsp页面直接书写HTML标签
3)项目中的web层通常使用mvc设计模式Servlet+jsp+javabean其中,Servlet做控制器,处理用户请求jsp作为显示模板javabean作为封装数据的实体4)如何养成一种良好的编码风格在Servlet中应避免做任何的数据输出在jsp中应避免去直接书写java代码,而实际上要做到这点很难,所以需要用到el和jstl
jsp语法
1.模板元素
在jsp页面中所有的html标签部分被称作模板元素,用于对整个网页进行布局
2.jsp脚本:jsp中的java代码被称作jsp脚本
jsp脚本有三种形式
收集整理
1)脚本表达式:被翻译到out.print()方法中
2)脚本片段:被翻译到service()方法中收集整理
jsp引擎iso-8859-1解码úServlet引擎response编码iso-8859-19899response.setContentType???úgb2312编码乱上加乱a.jsp中国gb2312码9899ServletúIE浏览器9899iso-8859-1???úgb2312中国jsp乱码解决告诉jsp引擎jsp页面是什么码,这样翻译才不会错;告诉response用什么码编码再发给浏览器
三、jsp九个隐式对象(笔试经常考)
1.面试题:列举出jsp页面的九个隐式对象,并加以说明
对象变量名(可直接在jsp中使用)configapplicationresponserequestsessionoutpageexceptionpageContext对象类型ServletConfigServletContextHttpServletResponseHttpServletRequestHttpSessionJspWriterthisThrowable(不是每个jsp都有)PageContext收集整理
2.out对象
JspWriter类型,带缓冲的字符流(包装流)BufferedWriter
对response.getWriter()进行了包装,提供了缓冲区,默认大小8KB
写入该流的数据最终会被刷新到response,调用response.getWriter().write()方法
Question:什么情况下JspWriter会将数据刷新?
1)缓冲区写满(默认大小为8kb,可以在page指令中通过buffer属性设置缓冲区大小)2)jsp页面结束(此流会被关闭,数据刷新到底层的流)
注意:
1)jsp中输出数据尽量使用out,不要使用response直接获得流输出
原因在于:写入out的数据会先进缓冲区,再刷新到response;如果两个都用,会导致后写的数据显示在前面2)jsp页面结束时,会自动调用response.getWriter()将数据刷新
所以在jsp中不要调用getOutputStream(),当然也不方便做文件下载结论:在jsp中用out输出数据
3.pageContext对象
主要功能:用于获得其他8大隐式对象这样做的意义:
欲移除jsp中的java代码,就需要将java代码写到一个java类的成员方法中,然后想办法在jsp页面中调用该方法,以达到代码复用的目的.
由于jsp中的java代码难免会访问8个隐式对象,因为这些对象都是和web开发相关的对象,所以要移除这部分java代码就需要‖将8个对象传递给java类‖的方法,
为了方便,我们通常的做法是:只传递一个pageContext对象过去,这样在方法中就可以通过该对象很轻松地获得其他8个对象了
pageContext也是一个域对象,但只在当前jsp页面有效重点:
1)默写9个对象,(具体描述9个对象怎么用)
2)理解pageContext对象的意义(获得其他8个对象)Btw:pageContext有个特殊的方法findAttribute()
四、web开发中的四个域(重点)
范围由小到大:page(jsp有效)request(一次请求)session(一次会话)application(当前web应用)page:PageContext对象request:request对象session:session对象
application:ServletContext对象
1.这4个对象的生命周期?
生命周期:就是指对象的创建到销毁的期间
page:jsp页面被执行,生命周期开始,jsp页面执行完毕,生命周期结束request:用户发送一个请求,开始,服务器返回响应,请求结束,生命周期结束session:用户打开浏览器访问,(getSession方法被调用来)创建session---(开始)当session超时或被声明失效,该对象生命周期结束---(结束)
收集整理
application:web应用加载的时候创建(开始),web应用被移除或服务器关闭,对象销毁(结束)
2.四个域的作用范围
2.1.什么是域?为什么把这4个对象叫做域对象呢?域:即范围的意思
web中的域对象:可以存储对象,在作用范围内都可以取到,其内部是Map集合的实现MapclassPageContext{
privateMapmap=newHashMap();privateHttpSessionsession;……}
四种域对象的作用范围(重要):
page:只在当前jsp页面有效
request:只在当前请求有效,每次请求分别对应不同的request域对象
session:只在一次会话中有效,会话结束就无法取到数据了(特殊情况,发送Cookie)//session:默认情况下,同一个浏览器来访问有效(发送同一个sessionid)
application:在一个web应用中有效(只要服务器不关,web应用不移除就可以取数据)
四个域对象的范围由小到大排列依次为:page
原则:四个域对象在选择的时候,能用范围小的绝不用范围大的
page:数据只是暂时存放在集合中,如果要在jsp页面的其他地方使用,需要用page(页面中自定义的map)ps:什么时候需要用map了,就用page
request:数据只是做显示的,看完了就没用了,就存request域ps:请求转发,Servlet产生的处理结果(数据)交给jsp显示,session:数据给用户看完了,一会还要用,会话结束了就没用了ps:用户登陆,用户信息发给客户端看,看完了,一会访问别的页面还要看用户信息ps:购物车,购物成功了,给用户看购物车,待会随时可以查看购物车ps:请求重定向,因为是两次请求,第一次请求的数据,第二次请求还要看application:数据给一个用户用完了,别人还要用ps:聊天室,聊天记录,需要给所有的用户看ps:统计网站在线人数,所有人看到的应该是一个数
总结:需要定义Map不如用page,请求转发Servlet带给jsp的数据存request请求重定向带过去的数据存Session,全局的数据存application
五、jsp细节
只有当jsp页面指定的page指令isErrorPage为true时,才有exception隐式对象Jsp注释:jsp出错:1)被翻译的Servlet不能编译,语法错,这时会报告是因为jsp中的哪行导致不能编译2)翻译的Servlet在运行期间出现异常,报告是jsp的哪行导致的异常
收集整理
此时会进一步报告导致异常的原因,在Servlet中的哪行出现异常2.jsp映射也是通过servlet元素
六、内省(introspect)
1.javabean:一种固定写法的java类,javabean必须同时具备以下三种特点:
1)必须有无参构造函数
2)属性必须私有,我们称为字段3)必须提供标准的get和set方法
例:name字段的getter:StringgetName()settter:voidsetName(Stringname)
2.什么是内省introspect?内省就是:通过反射的方式访问javabean
Jdk中的api:PropertyDescriptor类操作Bean的属性
3.BeanUtils工具包:Apache组织开发了一套用于操作JavaBean的API(内省)
核心类BeanUtilssetProperty(bean,name,value)copyProperties(target,source);BeanUtils的作用:
1.可以支持String到8种基本数据类型转换
2.其他引用数据类型都需要注册转换器ConvertUtils.register(Converter,Class)
3.WebUtils工具类:实现任何request提交的表单封装到对应的javabean
七、jsp标签
为了移除jsp页面的java代码,sun公司提供了一些内置的标签我们称为jsp标签,或jsp动作元素1.相当于RequestDispatcher对象的页面引入dispatcher.include用于实现Servlet包含dispatcher.forward用于实现servlet转发forward在转发时,web容器会清空response中的数据,转发之后就无法向response写入数据动态引入方式:在程序运行期间引入,jsp被翻译成两个servlet(check?)静态引入方式:include指令也能实现页面的引入,将两个jsp翻译成一个Servlet包含和被包含的jsp页面指令不能发生冲突(其中,import和pageEncoding可以冲突)2.实现请求转发结合标签传参,自动进行url编码,编码的方式参照request编码3.内省反射创建javabean,以id作为key存入指定的域其实在创建之前,会先去域中找,找到了则不创建4.设置属性值
批量5.获得属性值
八、web开发模式
Sun公司针对web开发提供了两种模式Model1:jsp+javabean只适合小型应用
收集整理
Model2:servlet+jsp+javabeanMVC(重要)
Lesson13:EL表达式和JSTL标签
1.el全名为ExpressionLanguage。它是一种数据访问语言(不能写if语句,for循环等逻辑语句),简称:el表达式2.EL能实现如下功能:1)使用变量访问web域中存储的对象${user}2)访问javabean的属性${user.address.city}3)执行基本的逻辑运算4)直接使用隐式对象5)调用el函数
3.el表达式用在哪里1)在jsp页面直接输出数据2)在标签中使用el直接为属性赋值
4.el表达式获取数据1.在jsp页面使用el表达式可以轻松地获得web域中的对象2.并对javabean、数组、list、map进行取值
5.el表达式不能写if,for等逻辑语句,所以需要对web域中的list和map集合进行迭代就需要结合jstl迭代标签JSTL是sun公司开发的一套标签库1.JSTL标签的作用:使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的脚本代码2.如何在页面中使用JSTL标签?在页面中使用JSTL标签需完成以下2个步骤:1)导入jstl.jar和standerd.jar这两个JSTL的jar文件。2)在JSP页面中使用元素导入标签库。
3.最常用的jstl标签为forEach和if标签
6.el表达式虽然不能进行逻辑判断和写for循环,但是el表达式中可以进行逻辑运算
40收集整理
7.el表达式中的保留关键字
二、el中的11个隐式对象
隐含对象名称描述对应于JSP页面中的pageContext对象(用于获取JSP的8个隐式对象.最主要用途:${pageContext.request.contextPath}代表page域中用于保存属性的Map对象代表request域中用于保存属性的Map对象代表session域中用于保存属性的Map对象pageContextpageScoperequestScopesessionScopeapplicationScope代表application域中用于保存属性的Map对象paramparamValuesheaderheaderValuescookieinitParam
表示一个保存了所有请求参数的Map对象(应用:表单回显)表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]表示一个保存了所有http请求头字段的Map对象同上,返回string[]数组。注意:如果头里面有—-‖,例Accept-Encoding,则要headerValues[—Accept-Encoding‖]表示一个保存了所有cookie的Map对象表示一个保存了所有web应用初始化参数的map对象el表达式的11个隐式对象的具体用途(除了pageContext,其余10个都是map类型)
1.pageContext作用:获得servlet上下文路径(web应用名称)最常用代码:${pageContext.request.contextPath}2.pageScope、requestScope、sessionScope、applicationScope
作用:分别对应每个域所对应的那个map,可以准确地获得四个域中的对象,用于取值
收集整理
3.param、paramValues作用:获得请求参数,一般用于做表单的回显4.header、headerValues作用:获得请求消息头5.cookie作用:获得浏览器发送的cookieCookie也是map集合,key是cookie的namevalue是对应的cookie对象6.initParam作用:获得web初始化参数
三、el函数
1.我们可以开发自定义函数,用于调用java类的方法案例:对页面输出的内容进行html转义实现步骤:1)编写一个java类,定义一个静态方法去tomcat的例子中拷贝一个现成的%tomcat安装目录%\\webapps\\examples\\WEB-INF\\classes2)编写标签库描述符(tld)文件,在tld文件中描述自定义函数找个现成的修改一下%tomcat安装目录%\\webapps\\examples\\WEB-INF\\jsp23)在jsp页面中导入标签库即可使用函数
帖子的内容:${myfn:transfer(requestScope.data)}
2.sun公司针对常用的字符串处理在jstl技术中提供了el函数中
Lesson17
一、自定义标签入门1.为什么引入标签
jsp页面作为显示的模板,应尽量使用页面标签来实现,避免写java代码如果在jsp页面写java代码,首先会令jsp页面难以阅读,不利于页面排版,其次,作为页面美化人员有可能会看不懂java代码,如果将java代码替换成标签,那么只要是懂html标签的人都能看得懂
2.如何实现自定义标签
移除jsp页面中的java代码其实很简单,只需要写一个java类实现Tag接口,在java类中实现jsp页面的代码,在tld标签描述文件中针对标签和java类进行映射。案例:实现标签显示来访者的ip
收集整理
实现步骤:
1)写一个类IpTag实现Tag接口
2)在WEB-INF目录下新建tld文件,对标签进行描述
3)在jsp页面进行调用
二、传统标签(已过时,但是框架中还是会有很多传统标签)
1.Tag接口执行流程:1)创建对象初始化
2)调用setPageContext方法传入表示jsp页面的pageContext3)如果有父标签调用setParent方法传入父标签4)调用setter方法为属性赋值5)调用doStartTag方法6)执行标签体可选7)调用doEndTag方法
8)调用release方法释放资源
2.方法的返回值Tag.EVAL_BODY_INCLUDE执行标签体Tag.SKIP_BODY跳过标签体
Tag.EVAL_PAGE
执行剩余页面
Tag.SKIP_PAGE
跳过剩余页面
3.Tag接口的子类1)IterationTag接口增加doAfterBody()方法,在方法体执行完毕时被调用增加返回值EVAL_BODY_AGAIN用于执行再次执行标签体实现此接口可以实现循环执行标签体
一般通过继承默认实现类BodyTagSupport来实现该标签2)BodyTag接口
增加setBodyContent(BodyContentb)方法传入标签体
我们可以通过该方法获得标签体从而对标签体进行操作
4.tld文件
tld是taglibdescriptor的缩写,tld文件为标签库描述文件通过tag元素描述一个标签OutputsHello,WorldhelloWorldcn.itcast.tag.HelloWorldTagempty其中name用于指定标签的名称(name怎么写,在jsp页面怎么写)
收集整理
tag-class用于指定标签对应的java类
body-content用于指定标签对之间可以输入的内容类型empty:表示空标签,即不能有标签体(常用)JSP:标签体不为空,可以写jsp脚本Scriptless:不能写jsp脚本,但可以写表达式和el(常用)Tagdependent:将原始内容提交忽略el表达式等运算
5.标签的属性
需要在页面标签中使用属性需完成以下步骤:1)在标签类中定义一个属性2)为属性添加setter方法3)在tld文件中对属性进行描述实现:元素的子元素用于描述自定义标签的一个属性,自定义标签所具有的每个属性都要对应一个元素。descriptionaaaatruetrueObjectTypeattribute的子元素元素名descriptionname是否必须指定否是描述用于指定属性的描述信息。用于指定属性的名称。属性名称是大小写敏感的,并且不能以jsp、_jsp、java和sun开头。用于指定在JSP页面中调用自定义标签时是否必须设置这个属性。其取值包括true和false,默认值为false,true表示必须设置,否则可以设置也可以不设置该属性。rtexprvalue是runtimeexpressionvalue(运行时表达式)的英文简写,用于指定属性值是一个静态值或动态值。其取值包括true和false,默认值为false,false表示只能为该属性指定静态文本值,例如"123";true表示可以为该属性指定一个JSP动态元素,动态元素的结果作为属性值,例如JSP表达式。用于指定属性值的Java类型。required否rtexprvalue否type否6.案例
实现将标签体循环执行指定次数的标签Loop
收集整理
三、简单标签(重点)
1.简单标签SimpleTag
由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广,SUN公司为降低标签技术的学习难度,在JSP2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能
我们可以通过继承SimpleTagSupport类来实现SimpleTag接口
方法详解:setJspContext方法用于把JSP页面的pageContext对象传递给标签处理器对象setParent方法用于把父标签处理器对象传递给当前标签处理器对象getParent方法用于获得当前标签的父标签处理器对象setJspBody方法用于把代表标签体的JspFragment对象传递给标签处理器对象doTag方法用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。Question:方法的调用顺序?
2.开发案例
开发防盗链标签
开发标签
开发标签
choosewhenotherwise
开发迭代标签Foreach
开发html转义标签
打包标签库
收集整理
Lesson9
一、jdbc基本概念
jdbc:JavaDatabaseConnectivity
sun公司为了统一对数据库的操作,定义了一套api,称之为jdbc这套api完全由接口组成,我们在编写程序的时候针对接口进行调用
这些接口交给数据库厂家去实现,不同的数据库厂商会提供不同的实现类,这些实现类被我们称作数据库的驱动
二、实现jdbc程序
步骤:1.实验环境建user表user.sqlcreatedatabaseday12charactersetutf8collateutf8_general_ci;useday12;createtableusers(idintprimarykeyauto_increment,namevarchar(40),passwordvarchar(40),emailvarchar(60),birthdaydate)charactersetutf8collateutf8_general_ci;insertintousers(name,password,email,birthday)values("zs","123456","zs@sina.com","1980-12-04");insertintousers(name,password,email,birthday)values("lisi","123456","lisi@sina.com","1981-12-04");insertintousers(name,password,email,birthday)values("wangwu","123456","wangwu@sina.com","1979-12-04");
2.导入数据库的驱动
mysql-connector-java-5.0.8-bin.jar
3.编程java程序
//1.注册数据库的驱动DriverManager.registerDriver(newcom.mysql.jdbc.Driver());//2.建立与mysql数据库的连接用到jdbcapiStringurl="jdbc:mysql://localhost:3306/day11";收集整理Stringuser="root";Stringpassword="root";Connectionconn=DriverManager.getConnection(url,user,password);//3.创建用于发送sql语句的Statement对象Statementstmt=conn.createStatement();//4.编写一句sqlStringsql="select*fromusers";//5.发送sql,获得结果集ResultSetrs=stmt.executeQuery(sql);//6.处理结果集System.out.println("id|name|password|email|birthday");while(rs.next()){//有第一行intid=rs.getInt("id");//通过列名取值比较直观Stringname=rs.getString("name");Stringpsw=rs.getString("password");Stringemail=rs.getString("email");Datebirthday=rs.getDate("birthday");System.out.println(id+"|"+name+"|"+psw+"|"+email+"|"+birthday);}//7.关闭连接释放资源rs.close();stmt.close();conn.close();三、jdbc程序详解
1.注册驱动
DriverManager.registerDriver(newcom.mysql.jdbc.Driver());上面的语句会导致注册两次驱动
原因在于,查看Driver类的源码会发现在静态代码块中完成了注册驱动的工作,也就是说注册驱动其实很简单,只需要加载驱动类即可Class.forName(—com.mysql.jdbc.Driver‖);
2.创建数据库的连接
Connectionconn=DriverManager.getConnection(url,user,password);
其中:url,相当于数据库的访问地址,程序员通过url指定需要访问的数据库
jdbc:mysql:[]//localhost:3306/test?参数名:参数值
其中jdbc为主协议,mysql为子协议,localhost为主机名,3306为端口号,test为数据库名
url的后面可以跟参数,常用的参数有:user=root&password=root&characterEncoding=UTF-8
如果url地址后面跟了user和password,创建Connection对象时将不必再次传入值
收集整理
Connectionconn=DriverManager.getConnection(url);
补充:如果访问的localhost:3306,url可省写为jdbc:mysql:///test
3.Connection对象:用于表示与某个数据库之间的连接,在程序中对数据库的所有操作都需要通过此对象来完成常用方法有:createStatement():创建向数据库发送sql的statement对象。prepareStatement(sql):创建向数据库发送预编译sql的PrepareSatement对象。prepareCall(sql):创建执行存储过程的callableStatement对象。setAutoCommit(booleanautoCommit):设置事务是否自动提交。commit():在链接上提交事务。rollback():在此链接上回滚事务。
4.Statement对象:用于向数据库发送sql语句.execute(Stringsql):用于向数据库发送任意sql语句executeQuery(Stringsql):只能向数据发送查询语句。
executeUpdate(Stringsql):只能向数据库发送insert、update或delete语句addBatch(Stringsql):把多条sql语句放到一个批处理中。executeBatch():向数据库发送一批sql语句执行。
5.ResultSet对象:专门用于封装结果集(对于查询操作特别重要)
存储的形式就是一种表格的形式,同样是列+行,说白了就和我们在dos命令行窗口查询的结果一样遍历方式:一开始游标指向结果集第一行,也就是表头通过next将游标移向下一行,如果没有下一行,该方法会返回false获得当前行的数据需要调用get方法:get(intindex)获得第几列列数从1开始get(StringcolumnName)根据列名获得值(常用)
数据库的数据类型与java中数据类型的对应关系
48收集整理
ResultSet对象的常用方法next():移动到下一行previous():移动到前一行absolute(introw):移动到指定行beforeFirst():移动resultSet的最前面。afterLast():移动到resultSet的最后面。
6.释放数据库资源
由于数据库的资源非常宝贵,所以用完了一定要记得释放资源
特别是Connection对象,因为数据允许的并发访问连接数量往往都比较有限
在java程序中,我们应该将最终必须要执行的代码放到finally当中释放资源的代码if(rs!=null){try{rs.close();}catch(SQLExceptione){e.printStackTrace();}rs=null;}if(stmt!=null){try{stmt.close();
收集整理}catch(SQLExceptione){e.printStackTrace();}stmt=null;}if(conn!=null){try{conn.close();}catch(SQLExceptione){e.printStackTrace();}conn=null;}
四、jdbc实现crud(createreadupdatedelete)
1.编写程序对User表进行增删改查操作
2.防止sql注入在service层进行逻辑判断使用PreparedStatement对象
3.编写工具类对jdbc程序进行优化将获得连接和释放资源的代码写到通用的工具类中
五、jdbc案例
实现一个简单的员工信息管理系统,练习对员工表的crud字段名idnamegenderbirthdayidcarddegreeentrydatepositiondepartment
50说明编号员工姓名性别出生日期身份证号学历入职日期部门职位类型varchar(40)varchar(20)varchar(4)datevarchar(20)varchar(20)datevarchar(40)varchar(20)
友情提示:本文中关于《Java web笔记》给出的范例仅供您参考拓展思维使用,Java web笔记:该篇文章建议您自主创作。
来源:网络整理 免责声明:本文仅限学习分享,如产生版权问题,请联系我们及时删除。