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的优先级越高。
View Code

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

posted @ 2017-01-31 02:23  假程序猿  阅读(272)  评论(0)    收藏  举报