Servlet编程:Servlet的小知识点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet编程:Servlet的小知识点相关的知识,希望对你有一定的参考价值。

  1. 如何开发一个Servlet

  2. Servlet的映射路径

  3. Servlet缺省路径

  4. Sevlet的生命周期

  5. Servlet的自动加载

  6. 有参的init方法和无参的init方法

  7. Servlet的多线程并发问题

  8. ServletConfig对象

  9. ServletContext对象

5、Servlet的自动加载


默认情况下,第一次访问servlet的时候创建servlet对象。    如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么就会导致用户第一次访问sevrlet的时候比较慢。

解决方法:改变servlet创建对象的时机,即提前到加载web应用的时候!!!

在servlet的配置信息中,加上一个<load-on-startup>即可!!

  <servlet>
  	<servlet-name>LifeDemo</servlet-name>
  	<servlet-class>com.rk.http.b_lifecycle.LifeDemo</servlet-class>
  	<!-- 让servlet对象自动加载 -->
  	<load-on-startup>1</load-on-startup><!-- 注意: 整数值越大,创建优先级越低!! -->
  </servlet>  
  <servlet-mapping>
    <servlet-name>LifeDemo</servlet-name>
    <url-pattern>/life</url-pattern>
  </servlet-mapping>




6、有参数的init和无参的init方法



程序开发人员自定义的Servlet类,一般继承自javax.servlet.HttpServlet抽象类,而javax.servlet.HttpServlet类继承自javax.servlet.GenericServlet抽象类。javax.servlet.GenericServlet提供了两个init方法:

void init(ServletConfig config)

void init()

两者之间的简单关系如下:

    //有参数的init方法
    //该方法是servlet的生命周期方法,一定会被tomcat服务器调用
    //注意:如果要编写初始代码,不需要覆盖有参数的init方法
    public void init(ServletConfig config) throws ServletException {
		this.config = config;
		this.init();
    }
    
    //无参数的init方法
    //该方法是servlet的编写初始化代码的方法。
    //是Sun公司设计出来专门给开发者进行覆盖,然后在里面编写servlet的初始逻辑代码的方法。
    public void init() throws ServletException {

    }


javax.servlet.GenericServlet类的部分源码如下:

package javax.servlet;

import java.io.IOException;
import java.util.Enumeration;


public class GenericServlet implements Servlet, ServletConfig, java.io.Serializable
{
	private transient ServletConfig config;
	
	/**
	 * Does nothing. All of the servlet initialization is done by one of the <code>init</code> methods.
	 */
	public GenericServlet() { }
	
	/**
	 * Called by the servlet container to indicate that the servlet is being placed into service.
	 */
    public void init(ServletConfig config) throws ServletException {
		this.config = config;
		this.init();
    }
    
    /**
     * A convenience method which can be overridden so that there‘s no need
     * to call <code>super.init(config)</code>.
     * 
     * Instead of overriding init(ServletConfig), simply override
     * this method and it will be called by <code>GenericServlet.init(ServletConfig config)</code>.
     * The <code>ServletConfig</code> object can still be retrieved via getServletConfig. 
     */
    public void init() throws ServletException {

    }
	
    /**
     * Returns this servlet‘s ServletConfig object.
     */
    public ServletConfig getServletConfig() {
    	return config;
    }
    
    public String getServletName() {
        return config.getServletName();
    }
    
	public String getInitParameter(String name) {
		return getServletConfig().getInitParameter(name);
	}
	
    public Enumeration getInitParameterNames() {
    	return getServletConfig().getInitParameterNames();
    }   
    
    /**
     * Returns a reference to the ServletContext in which this servlet is running.
     */
    public ServletContext getServletContext() {
    	return getServletConfig().getServletContext();
    }

}



7、Servlet的多线程并发问题

servlet对象在tomcat服务器是单实例多线程的。

因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据(如成员变量),可能会引发线程安全问题。

解决办法:

1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

2)建议在servlet类中尽量不要使用成员变量。

a)如果确实要使用成员,必须同步;

b)尽量缩小同步代码块的范围,以避免因为同步而导致并发效率降低。(哪里使用到了成员变量,就同步哪里!!)


示例:记录页面访问次数

package com.rk.http.c_thread;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * servlet的多线程并发问题
 * @author RK
 *
 */
public class ThreadDemo extends HttpServlet
{
	private int count = 0;
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
//		out.write("<html><head><title>访问次数</title></head><body>这是第N次访问本页面</body></html>"); 
		out.write("<html><head><title>访问次数</title></head><body>这是第");
		synchronized (ThreadDemo.class)//锁对象必须唯一。建议使用类对象
		{
			try
			{
				Thread.sleep(3000);//这里模拟复杂的业务等待
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			count++;
			out.write("" + count);
		}
		out.write("次访问本页面</body></html>");
	}

}


以上是关于Servlet编程:Servlet的小知识点的主要内容,如果未能解决你的问题,请参考以下文章

Servlet编程

Jsp&Servlet知识点

servlet编程

Servlet基础知识

Servlet编程

Java Servlet学习笔记