`
wangtong40
  • 浏览: 249723 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Servlet 基础

阅读更多

Servlet基础
2.1    HelloWorld

protected void service(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("<html>");
        out.println("<font size=30 color=red>Hello World</font><br>");
        out.println("<marquee>" + new Date() + "</marquee>");
        out.println("</html>");
    }
 

 

<servlet>
  <servlet-name>HelloServlet</servlet-name>
  <servlet-class>servlet.HelloServlet</servlet-class>
 </servlet>
 <servlet-mapping>
     <servlet-name>HelloServlet</servlet-name>
     <url-pattern>/demo/hello.html</url-pattern>
 </servlet-mapping>
 



2.2    线程安全Servlet

protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        count++;
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
out.println("<html>");
out.println("This is " + count + " times access" + "The thread name is :" +
 Thread.currentThread().getName());
out.println("</html>");
System.out.println("这是第" + count + "次访问" + "线程名称为:"
                 + Thread.currentThread().getName());
 


}
返回结果是:
This is 1times access thread name is :http-8080-1
This is 3times access thread name is :http-8080-1
This is 5times access thread name is :http-8080-2
This is 7times access thread name is :http-8080-3

由上面测试可知,在Servlet中的线程时非安全的,故可以采用以下的方式实现Servlet的线程安全。
2.2.1    继承SingleThreadModel接口
在Servlet中如果继承SingleThreadModel接口那么Servlet引擎将以单线程模式调用service方法。对于实现SingleThreadModel接口的Servlet,Servlet引擎保证其单个实例对象的service方法不会同时被两个线程调用。但是Servlet引擎仍然支持该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象并发运行,但每一个Servlet实例对象的service方法都不会被多个线程并发调用。实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为每个Servlet引擎会创建多个Servlet实例对象,多个并发的请求分别由不同的Servlet实例对象处理或者单个Servlet实例对象排队处理,而真正意义上的多线程安全问题指一个Servlet实例对象被多个线程同时调用的问题。
故在Servlet API 2.4中,SingleThreadModel已经不推荐使用。

2.2.2    编写线程安全的Servlet

注:在Servlet中除了访问成员变量是要注意线程安全问题外,访问其他共享资源是也应注意线程安全问题,如Web应用程序对象、Session对象、数据库等都可能涉及多个Servlet线程同时访问的问题。如果Servlet中没有定义成员变量和service方法中没有访问无同步访问控制的共享数据时,即使是多个线程并发调用service方法,也不会出现线程安全问题。

2.3    ServletConfig接口
Servlet引擎将代表Servlet容器的对象和Servlet的配置参数信息一并封装到一个成为ServletConfig的对象中,并在初始化Servlet实例对象时传递给该Servlet。
Servlet引擎装在并创建Servlet实例对象后,会调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet。

ServletConfig常用方法:
getInitParameterNames()用于获取初始化参数的名称返回一个Enumeration类型
getInitParameter()用于返回初始化参数
getServletName()用于获取Servlet名称
getServletContext()获取Servlet上下文

Web.xml样式:

  <servlet>
  <servlet-name>ServletConfigServlet</servlet-name>
  <servlet-class>servlet.ServletConfigServlet</servlet-class>
  <init-param>
          <param-name>firstname</param-name>
        <param-value>wang</param-value>
  </init-param>
   <init-param>
          <param-name>lastname</param-name>
        <param-value>tong</param-value>
  </init-param>
 </servlet>
  <servlet-mapping>
     <servlet-name>ServletConfigServlet</servlet-name>
     <url-pattern>/demo/servletconfig.html</url-pattern>
 </servlet-mapping>
 


Java获取ServletConfig参数:

Enumeration e = getServletConfig().getInitParameterNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = getInitParameter(key);
}
 



注:
在Servlet接口中定义了getServletConfig()方法,并在GenericServlet类中实现。用于得到ServletConfig对象。

2.4    GenericServlet&HttpServlet
HttpServlet是GenericServlet的一个提供HTTP协议处理的子类。

2.4.1    Init方法
Init方法在Servlet声明期中仅执行一次,Servlet引擎创建Servlet实例对象后立即调用该方法,通常该方法用户与构造方法类似的初始化功能。
Servlet接口定义的init方法:public void init(ServletConfig config)
GenericServlet在Servlet接口基础上添加一个无参数的init()方法
public void init()该方法没有任何语句,会在init(ServletConfig config)方法的最后一句加以调用、init()方法的目的是为编写初始化内容省去了覆盖init(ServletCOnfig config)方法时编写super.init(config)的麻烦。
2.4.2    Service方法
Service方法时Servlet的核心方法,每当servlet访问请求到达时,Servlet引擎就会调用Servlet实例对象的service方法进行相应。GenericServlet没有实现该方法,在HttpServlet中实现。

2.4.3    Destory方法
在web容器卸装Servlet之前被调用,可以覆盖destory方法完成与init方法相反的功能,释放Servlet打开的资源。
2.4.4    getServletConfig方法
返回Servletconfig对象的引用

2.4.5    doXXX方法
doGet()        处理GET请求
doPost()        处理POST请求
doHead()        处理Head请求
doPut()        处理Put请求
doDelete()    处理DELETE请求
doTrace()        处理TRACE请求
doOptions()    处理OPTIONS请求
2.4.6    浏览器缓存机制
响应信息中的Last-Modified头字段用于指定响应内容的最后更新时间,当客户机缓存此文档内容后,它在以后的请求信息中根据Last-Modified头字段指定的时间来生成If-Modified-Since请求头字段,亦指出缓存文档的最后更新时间。只有文档的更新时间比If-Modified-Since请求头指定的时间新时,服务器才返回文档内容。如果自动If-Modified-Since指定的时间以来,网页内容没有发生修改,服务器将返回一个304状态码表示浏览器缓存的版本是最新的则使用以前缓存的内容。
浏览器根据响应信息中是否包含Last-Modified字段来进行处理,如果响应信息中没有包含Last-Modified字段,将每次访问此页面时都想服务器发出访问请求,否则仅每次启动运行后第一次访问页面才向服务器发出请求,其他都从缓存中读取。
在HttpServlet类定义了一个getLastModified方法,返回值影响浏览器如何使用缓存内容。getLastModified()是一个回调方法,由HttpServlet的service方法调用。Servlet程序调用service()方法后在调用doGet()方法之前,先调用getLastModified()方法,并根据其返回值来决定是都调用doGet方法。规则如下:
1、    getLastModified返回一个负数时,service方法后调用doGet方法。
2、    getLastModified方法返回一个正数且请求中不包含If-Modified-Since,或者If-Modified-Since的时间值比getLastModified方法返回的时间旧时,调用doGet方法。
3、    getLastModified返回一个正数,且请求信息中包含的If-Modified-Since时间比getLastModified返回时间新,则调用浏览器的缓存。

2.4.7    ServletContext接口
每个Web应用程序都是一个独立的Servlet容器,每个Web应用程序分别用一个ServletContext对象。ServletContext对象包含在ServletConfig对象中,调用ServletConfig.getServletContext()方法获取ServletContext对象。
2.4.7.1    获取Web应用程序的初始化参数

    <context-param>
        <param-name>companyName</param-name>
        <param-value>ibm</param-value>
    </context-param>
    <context-param>
        <param-name>website</param-name>
        <param-value>ibm.com.cn</param-value>
    </context-param>
 

 

Enumeration<String> e = getServletContext().getInitParameterNames();
        while (e.hasMoreElements()) {
            String key = e.nextElement();
            String value = getServletContext().getInitParameter(key);
        }
 


2.4.7.2    记录日志
ServletContext定义了两个log方法用于记录日志
Public void log(String msg)
Public void log(String message,Throwable t)

2.4.7.3    Application域范围属性
一个Web应用程序中所有Servlet都共享一个ServletContext对象,所以ServletContext对象也是Application对象。
ServletContext定义了4个用于添加、删除、访问application的方法
1、    getAttributeName
2、    getAttribute
3、    removeAttribute
4、    setAttribute

2.4.7.4    访问资源文件
1、    getResourcePath    返回一个包含该目录和文件路径名称的Set集合
2、    getResource        返回映射到资源上的URL对象。
3、    getResourceAsStream 返回连接到某资源上的InputStream对象

PrintWriter out = response.getWriter();
URL url = getServletContext().getResource("/WEB-INF/common.properties");
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/common.properties");
Properties properties = new Properties();
properties.load(is);
out.println("database=" + properties.getProperty("database"));
out.println("username=" + properties.getProperty("username"));
out.println("password=" + properties.getProperty("password"));
 


2.4.7.5    获取虚拟路径所映射的本地路径
ServletContext接口定义getRealPath()方法用于返回虚拟路径锁映射的本地文件系统路径。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics