jsp(6)(一)servlet的生命周期,常用重写方法,模糊路径映射,线程安全,ServletConfig ,ServletContex,配置加载,非web配置加载
servlet:
是为动态web开发提供的一种技术,相当对http协议,请求的数据,响应的数据做了封装。
不属于j2SE,需要看j2EE的文档,servlet只是其中一种技术。
1.实现一个servlet的步骤:
1.实现servlet的接口(需要tomcat的lib中servlet-api.jar包的支持) 2.配置项目中web.xml的servlet的映射,部署到web服务器中
2.servlet提供一些生命周期的方法,tomcat会自动调用这些方法,去继承httpServlet实现这些方法就可以。
service():请求一个servlet,服务器会自动调用这个方法。
servlet的生命周期一般是从第一次访问开始创建到服务器关闭。
3.eclipse 部署项目:jsp(6)(二)(eclipse默认虚拟路径的问题)
4.一个简单的例子:eclipse创建一些虚拟文件夹

实际项目目录:


5.实现httpServlet的doGet和doPost方法就可以了。

6.注意:response获取输出流写数据并非就将数据写给浏览器
而是在response中,然后tomcat将response的数据写给客户端浏览器。
response.getOutputStream().write("test servlet demo".getBytes());
8.在eclipse中如果要修改类名一般用重构:
右击选择refactor->rename(或者快捷键alt+shift+r),修改变量名这可以用这个快捷键,会将关联的也会改变,但xml中关联的不会改变,比如修改
servlet的名字,web.xml中的名字需要手动去更改。
9.web项目复制的时候特别注意一个问题,
如果新的项目和已有的项目原来是重名的,只是改变项目文件夹的名字是不够的。还需要修改映射的路径。

对于test2_web项目名字确实已经改变,eclipse可以通过修改配置属性修改映射。

但是其contex即映射并没被修改还是映射原来的web项目

修改为:

10.servlet访问是通过url映射访问的,并且可以设置多个地址指向一个servlet:

而且可以泛指但只能是“*.某某”或“/*”;分别表示以某某结尾或者任何访问都执行该servlet。
10.1关于多个匹配冲突,优先选择的问题:
首先选择匹配最高的,对于直接以*开头的优先级最低(没有斜杠)。

10.2对于找不到路径的访问该执行哪个servlet的配置是“/”(一般不使用)
对于web访问,首先都是去查找servlet配置:即使是访问静态html页面
比如:1.html时候,实际是执行缺省的servlet(这个servlet指向的项目中的静态网页),只是这个被默认配置在tomcat的conf/web.xml中配置,然后它会去找同名的静态页面。

如果在项目WEB-INF/web.xml配置这个缺省的“/”路径,那么就只会执行自己配置的servlet。并且项目下的那些静态页面都不能访问到了。(因此一般不会在项目中再如此配置)
11.修改web.xml配置不需要重启服务器,会自动从新加载web.xml。因为conf/Contex.xml的配置:

12.修改项目文件内容不需要重启服务器是因为为conf/server.xml的配置:

13.servet是由servlet引擎(可看成是由tomcat服务器)来调度控制的。
14.默认servlet对象只会创建一个对象实例,在第一次访问的时候创建,在服务器关闭时候才销毁。
servlet的init方法只执行一次,
每次访问,service方法执行一次,
并且每次生成新的request和response对象(只是这两个对象生命周期极短,不用考虑多个对象占用系统空间)。
15.servlet可以配置参数使得servlet在服务器启动时候创建。
多个这样servlet配置,load-on-startup的参数正数,数值越小优先级越高,即创建在前。(struts框架就是一个服务器启动创建的特殊servlet)
在servlet的配置当中,<load-on-startup>5</load-on-startup>的含义是:标记容器是否在启动的时候就加载这个servlet。当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。

16.servlet线程安全问题:
(补充:对于共享对象方法内部的局部变量是线程安全。
16.1.当需要保证i的数据线程安全问题:如下

缺点:虽然数据安全了,但是其他访问都将被阻塞。
servlet曾提供实现singleThreadModel(servlet2.4过时)标记接口(接口里没有任何东西。如:序列号接口,克隆接口)的方式,
原理是:当原来的servlet响应没有完成,又有新的访问,tomcat会创建一个新的servlet来处理,这会存在一个问题,就是两次的结果会是一样。
17.将初始化数据封装成servletConfig对象:


单个参数获取

多个参数获取:

17.1.应用场景:初始化参数可以有如下作用:(struts使用这种方式获得其指定文件的配置)
1.字符集类型 2.连接数据库类型 3.数据库密码 4.指定配置文件。
18.代表web应用的对象servletContex。在tomcat启动时候就创建了。

获取servletContex的方式:从类中获取,或者从config获取

18.1.servletContex可以servlet之间共享数据。范围是整个应用程序,都可以访问。

不同servlet读写的例子:
写入contex:

读:

18.2.还可以用配置xml的方式为所有servlet配置共享参数(同样也可以是多个参数)

获取:

可以用于配置共享的数据连接需要的参数,适用于多个servlet来访问。
18.3.转发:请求服务器,服务器会将另一个页面转发给客户(重定向是要浏览器去再请求一个页面)
常用于将servlet处理的结果转发给jsp做好布局后返回浏览器。

18.4.用来获取配置,
(补充:常用的配置有xml和properties。对于存在关系配置用xml,如父子或兄弟关系)
利用读取资源文件的方式加载配置:

注意两个东西:
1.放在src(src目录只是eclipse为显示而存在的,项目文件并不会存在)目录中的db.properties,eclipse会自动复制放在WEB-INF/classes/中,获取路径注意! (放在eclipse的webContent目录中的db.properties实际就是项目的目录下即:/db.properties) 2.对于properties文件流,有专门的properties对象来加载和获取配置。
特别注意一个问题:
1.如果用文件流读取:new file("/WEB-INF")的/代表的路径并不是项目的根目录!而是启动该项目应用程序的路径,可以是eclipse也可能是tomcat的安装路径
File file = new File(""); System.out.println(file.getAbsolutePath());//路径是相对eclipse安装路径的(绝对路径:F:\eclipse-jee-juno-win32\eclipse)
new Properties().load(new FileInputStream(file));
并且java项目和web通过文件流读取的相对路径也是不同的!
2.如果要用文件流的方式读取:可以通过下面方法获得项目的绝对路径再用:
String realPath = getServletContext().getRealPath("WEB-INF/classes/db.proterties"); System.out.println(realPath);//E:\apache-tomcat-6.0.48-windows-x86\apache-tomcat-6.0.48\webapps\test_web new Properties().load(new FileInputStream(realPath));
这种方式一个好处是能够直接获得文件所在的具体路径,如果要做上传下载很有用。前面那种方式只能读取配置中的信息。
1.补充:非web项目读取配置:
(db.properties在src目录下)
从java项目中获取配置文件的方式:(通过类加载器的方式)
void f(){
InputStream resource = TestOut.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties2 = new Properties();
properties2.load(resource);
}
(服务器不重启)这种方式的一个弊端是资源文件只会加载一次(加载器加载文件首先判断文件名字是否已经加载),那么修改配置文件调用上面的代码读取到的还是原来的配置内容。
可以先通过加载器获得具体的路径,然后通过文件读取获得:
void getProperties() throws IOException, FileNotFoundException { String path = TestOut.class.getClassLoader().getResource("db.properties").getPath();//得到文件路径 Properties properties2 = new Properties(); properties2.load(new FileInputStream(path)); }
2.补充: 配置读取乱码的问题。java流读取properties输出乱码的问题
主要是因为程序默认流读取是用iso-8859-1

浙公网安备 33010602011771号