javaweb学习总结(一)servlet开发

一、ServletConfig详解

1.1 配置Servlet初始化参数

在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数,例如:

<servlet>
    <servlet-name>ServletConfigDemo1</servlet-name>
    <servlet-class>rain.servlet.study.ServletConfigDemo1</servlet-  
  class>
<!-- 配置ServletConfigDemo1的初始化参数 -->
<init-param>
    <param-name>name</param-name>
    <param-value>rain</param-value>
</init-param>

<init-param>
    <param-name>score</param-name>
    <param-value>140</param-value>
</init-param>

<init-param>
    <param-name>age</param-name>
    <param-value>18</param-value>
</init-param>
</servlet>
1.2 通过ServletConfig获取初始化参数

当Servlet配置了初始化参数以后,web容器在创建servlet实例对象时,会自动将这些参数封装到ServletConfig对象中去,并且在调用Servlet的init方法时会将ServletConfig传递过去。因此我们可以通过ServletConfig对象就可以得到配置的初始化参数信息了。不过现在有了servlet3.0之后,有两种写法了。例如:

package rain.servlet.study;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ServletConfigDemo1
 */
//@WebServlet(urlPatterns="/ServletConfigDemo1",initParams= {
//      @WebInitParam(name="name",value="rain"),
//      @WebInitParam(name="score",value="100"),
//      @WebInitParam(name="age",value="18")
//})
public class ServletConfigDemo1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private ServletConfig config;

/**
 * 当servlet配置了初始化参数时,web容器在创建servlet实例对象时会自动将这些初始化参数封装到servletconfig
 * 对象中,并在调用servlet的init方法时,将改对象传递给servlet
 */
@Override
public void init(ServletConfig config) throws ServletException {
    // TODO Auto-generated method stub
//      super.init(config);
    this.config = config;
}

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
//      response.getWriter().append("Served at: ").append(request.getContextPath());
    response.setContentType("text/html;charset=utf-8");
    String paramVal = this.config.getInitParameter("name");
    response.getWriter().print(paramVal);
    response.getWriter().print("<hr/>");
    
    //获取所有的初始化参数
    Enumeration<String> e = config.getInitParameterNames();
    while(e.hasMoreElements()) {
        String name = e.nextElement();
        String value = config.getInitParameter(name);
        response.getWriter().print(name + "=" + value + "<br/>");
    }
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}

上面注释掉的部分就是Servlet 3.0之后采用注解的形式,可以看到还是挺方便的。运行结果如下:


image.png

二、ServletContext对象

web容器在启动时,它会为每个web应用创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,可以通过ServletConfig.getServletContext获得。
由于一个web应用所有的servlet都共享同一个ServletContext,因此servlet对象之间可以实现通讯。ServletContext对象通常也被称之为context域对象

三、ServletContext的应用

3.1 多个servlet通过 ServletContext 来实现数据共享

下面是一个例子,两个servlet通过Servletc实现数据共享

package rain.servlet.study;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletContextDemo1
 */
@WebServlet("/RainServletContextDemo1")
public class RainServletContextDemo1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request,         HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request,   HttpServletResponse response) throws ServletException,   IOException {
        // TODO Auto-generated method stub
//      response.getWriter().append("Served at:     ").append(request.getContextPath());
        String data = "rain_sample_data";
        /**
         * ServletConfig对象中维护了ServletContext的引用,可以通过
         * getServletConfig().getServletContext()来获取到。
         */
        ServletContext context = this.getServletConfig().getServletContext();
        context.setAttribute("data", data);
}

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

下面是另外一个Servlet

package rain.servlet.study;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletContextDemo2
 */
@WebServlet("/RainServletContextDemo2")
public class RainServletContextDemo2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      response.getWriter().append("Served at: ").append(request.getContextPath());
        ServletContext context = getServletContext();
        String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据
        response.getWriter().print("data="+data);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

先运行RainServletContextDemo1,然后再运行RainServletContextDemo2,即可以实现数据的共享。运行结果如下:

image.png
3.2 用ServletContext对象实现请求转发

RainServletContextDemo3

package rain.servlet.study;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletContextDemo3
 */
@WebServlet("/RainServletContextDemo3")
public class RainServletContextDemo3 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      response.getWriter().append("Served at: ").append(request.getContextPath());
        String data = "i am servlet3";
        response.getOutputStream().write(data.getBytes());
        ServletContext context = getServletContext();
        RequestDispatcher dispatcher = context.getRequestDispatcher("/RainServletContextDemo4");
        dispatcher.forward(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

RainServletContextDemo4

package rain.servlet.study;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletContextDemo4
 */
@WebServlet("/RainServletContextDemo4")
public class RainServletContextDemo4 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getOutputStream().write("i am servlet4 hia!!!".getBytes());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
3.3 用ServletContext对象读取资源文件
项目的目录结构:
image.png
代码:使用Servlet读取资源文件
package rain.servlet.study;

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletContextDemo5
 * 使用ServletContext读取资源文件
 */
@WebServlet("/RainServletContextDemo5")
public class RainServletContextDemo5 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      response.getWriter().append("Served at: ").append(request.getContextPath());
        response.setHeader("content-type", "text/html;charset=UTF-8");
        readSrcDirFile(response);//读取src目录下面的文件
        response.getWriter().write("<hr/>");
        readWebContentFile(response);//读取webcontent目录下面的文件
        response.getWriter().write("<hr/>");
        readPackageFile(response);//读取rain.servlet.study目录下的文件
        response.getWriter().write("<hr/>");
        readDataConfigFile(response);//读取data.config下的文件 
    }

    /**
     * 读取data.config下的文件 data1.properties
     * @param response
     * @throws IOException 
     */
    private void readDataConfigFile(HttpServletResponse response) throws IOException {
        InputStream in = getServletContext().getResourceAsStream(
            "/WEB-INF/classes/data/config/data1.properties");
        Properties prop = new Properties();
        prop.load(in);
        String name = prop.getProperty("name");
        String data = prop.getProperty("data");
        String time = prop.getProperty("time");
        response.getWriter().println("读取的是data.config包下面的data2.properties:");
        response.getWriter().println(
            MessageFormat.format("name={0},data={1},time={2}", 
                    name,data,time));
}

/**
 * readPackageFile(response);//读取rain.servlet.study目录下的文件  data2.properties
 * @param response
 * @throws IOException 
 */
private void readPackageFile(HttpServletResponse response) throws IOException {
    InputStream in = getServletContext().getResourceAsStream(
            "/WEB-INF/classes/rain/servlet/study/data2.properties");
    Properties prop = new Properties();
    prop.load(in);
    String name = prop.getProperty("name");
    String data = prop.getProperty("data");
    String time = prop.getProperty("time");
    response.getWriter().println("读取的是src目录下面rain.servlet.study包下面的data2.properties:");
    response.getWriter().println(
            MessageFormat.format("name={0},data={1},time={2}", 
                    name,data,time));
}

/**
 * 读取webcontent目录下面的文件 data4.properties
 * @param response
 * @throws IOException 
 */
private void readWebContentFile(HttpServletResponse response) throws IOException {
    InputStream in = getServletContext().getResourceAsStream(
            "/data4.properties");
    Properties prop = new Properties();
    prop.load(in);
    String name = prop.getProperty("name");
    String data = prop.getProperty("data");
    String time = prop.getProperty("time");
    response.getWriter().println("读取的是webcontent目录下面的data4.properties:");
    response.getWriter().println(
            MessageFormat.format("name={0},data={1},time={2}", 
                    name,data,time));
}

/**
 * 读取src目录下面的文件 data3.properties
 * @param response
 * @throws IOException 
 */
private void readSrcDirFile(HttpServletResponse response) throws IOException {
    InputStream in = getServletContext().getResourceAsStream(
            "/WEB-INF/classes/data3.properties");
    Properties prop = new Properties();
    prop.load(in);
    String name = prop.getProperty("name");
    String data = prop.getProperty("data");
    String time = prop.getProperty("time");
    response.getWriter().println("读取的是src目录下面的data3.properties:");
    response.getWriter().println(
            MessageFormat.format("name={0},data={1},time={2}", 
                    name,data,time));
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
        doGet(request, response);
    }

}
运行结果如下:
image.png

四、在客户端缓存Servlet的输出

对于不是经常变化的数据,可以在服务器端设置一个缓存时间,以避免浏览器频繁的向服务器端发起请求,提高服务器的性能。

代码如下:
package rain.servlet.study;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RainServletDemo6
 */
@WebServlet("/RainServletDemo6")
public class RainServletDemo6 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//      response.getWriter().append("Served at: ").append(request.getContextPath());
        String data = "asdffffdsgsgsfgsgsgs";
        response.setDateHeader("expires", System.currentTimeMillis()+24*3600*1000);
        response.getWriter().println(data);
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
运行结果
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容