servlet学习笔记(二)

参考:http://www.cnblogs.com/xdp-gacl/p/3763559.html
http://blog.csdn.net/zhouguosen_always/article/details/10740017/

一.ServletConfig

1.配置servlet初始化参数

可以在web.xml中,使用<init-param>标签,来配置servlet的初始化参数。每对标签初始化一个参数。
如:

<servlet>
    <servlet-name>AutoServlet</servlet-name>
    <servlet-class>com.test1.AutoServlet</servlet-class>
    <init-param>
        <param-name>name</param-name>
        <param-value>TestServlet</param-value>
    </init-param>
    <init-param>
        <param-name>password</param-name>
        <param-value>123456</param-value>
    </init-param>
    <init-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

当servlet配置了初始化参数后,web容器在实例化servlet对象时,会将参数封装到ServletConfig中,并在调用servlet实例的init()方法时,将ServletConfig对象传递过去。因此,可以通过ServletConfig对象获取当前servle实例的初始化参数。

package com.test1;

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

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

import com.sun.org.apache.xml.internal.security.Init;

public class AutoServlet extends HttpServlet {

    //创建一个ServletConfig对象
    private ServletConfig config;

    //重写init()方法
    public void init(ServletConfig config) throws ServletException{
        this.config = config;
    }

    //从ServletConfig对象中获取初始化参数
    public void doGet(HttpServletRequest request,HttpServletResponse response) 
        throws ServletException, IOException{

        //根据参数名称获取参数
        String param1 = this.config.getInitParameter("name");//根据名称获取初始化信息的值
        response.getWriter().write(param1);
        response.getWriter().write("<hr/>");//打印一条分割线

        //获取所有初始化参数
        Enumeration <String> e = this.config.getInitParameterNames();//获取所有初始化信息的名称
        while(e.hasMoreElements()) {
            String name = e.nextElement();
            String value = this.config.getInitParameter(name);
            response.getWriter().print(name + "=" + value + "<br/>");
        }

    }

    public void doPost (HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException{

        this.doGet(request, response);

    }

}

在ie中打开,显示的是理想的效果:
ie显示的效果
但是,在360浏览器(IE以及Chrome双内核)中打开时,<hr><br/>标签都没有起到预期的效果,显示的结果为:
360显示的效果

二.ServletContext

这部分的详细内容,参考:
http://blog.csdn.net/lvzhiyuan/article/details/4664624
ServletContext是一个全局的存储信息的空间,用于存储一些重要的、所有用户共享的、线程安全的信息,作为Web应用程序的上下文,被所有的用户所共享,一直到服务器关闭,它才会被释放。
安装在一个服务器中的一个特定URL名字空间(比如,/myapplication)下的所有Servlet,JSP,JavaBean等Web部件的集合构成了一个Web的应用,每一个Web应用(同一JVM),容器都会有一个背景对象,而javax.servlet.ServletContext接口就提供了访问这个背景对象的途径。
也就是说,在整个web应用中,只有一个ServletContext,WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。

1.多个servlet通过ServletContext实现数据共享

如:

package com.test1;

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

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

public class Test1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        /*由于在ServletConfig中维护了对于ServletContext的引用
         * 所以,在开发过程中,可以通过config找到对应的context
         */
        ServletContext context = this.getServletConfig().getServletContext();
        //将数据写入到ServletContext对象中
        String data = "some message";
        context.setAttribute("data", data);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request,response);

    }

}


package com.test1;

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

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

public class Test2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //直接获取对应的context实例
        ServletContext context = this.getServletContext();
        //从context中取出数据
        String data = (String) context.getAttribute("data");
        response.getWriter().write("data = " + data);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request,response);

    }


}



先运行Test1,将data写入到ServletContext中,然后运行Test2,就能够将写入的data读出来。
因为Test1和Test2位于同一个web容器以及同一个JVM中,它们对应同一个上下文,所以,可以通过ServletContext实现数据的共享。

2.获取web应用的初始化参数

与配置servlet的初始化参数相类似,可以在web.xml中,使用<context-param></context-param>标签来配置web应用的初始化参数。
如:

  <context-param>
      <param-name>name</param-name>
      <param-value>webApplication</param-value>
  </context-param>

那么,可以在servlet中,通过ServletContext来获取这些初始化参数。

package com.test1;

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

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

public class Test2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //直接获取对应的context实例
        ServletContext context = this.getServletContext();
        //获取整个web应用的初始化参数
        String data = context.getInitParameter("name");
        response.getWriter().write("data = " + data);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request,response);

    }


}


3.实现请求的转发

如:

package com.test1;

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

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

public class Test1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String data = "Test-1";
        response.getWriter().write(data);;
        ServletContext context = this.getServletContext();
        //设置请求转发对象:当test1被请求时,将秦秋转发到test2
        RequestDispatcher rd = context.getRequestDispatcher("/servlet/Test2");//地址写Test2的url-pattern
        rd.forward(request, response);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request,response);

    }


}


package com.test1;

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

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

public class Test2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String data = "Test-2";
        response.getWriter().write("data = " + data);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request,response);

    }

}

那么,在浏览器中访问Test1,请求将会被转发到Test2
请求转发效果

4.读取资源的配置文件

如:项目目录如下:
项目目录
要读取其中的两个资源配置文件:

package com.test1;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;

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

import com.sun.org.apache.xml.internal.security.Init;

public class AutoServlet extends HttpServlet {

    //利用ServletContext读取资源配置文件
    public void doGet(HttpServletRequest request,HttpServletResponse response) 
        throws ServletException, IOException{

        /*等价于:response.setContentType("text/html;charset=UTF-8")
         * 将内容的字符集设为UTF-8,防止出现中文乱码
         */
        response.setHeader("content-type", "text/html;charset=UTF-8");
        //读取WebRoot文件夹下的db.properties文件
        readProFile(response, "/db.properties"); //路径中,/*指的是web根目录
        //读取src.com.test1.db2.properties
        //对于一个普通web项目,properties文件可以放在src目录下,经过编译器编译之后目录变为WEB-INF/classes目录。
        readProFile(response, "/WEB-INF/classes/com/test1/db2.properties");

    }

    //读取特定目录下的资源配置文件
    private void readProFile(HttpServletResponse response, String url)
            throws IOException {

        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream(url);
        Properties prop = new Properties();
        prop.load(is);
        //根据key读出value
        String name = prop.getProperty("name");
        String user = prop.getProperty("user");
        String password = prop.getProperty("password");
        //输出
        //这里相当于直接在html页面写代码,所以使用println时不换行,需要加上<br/>
        response.getWriter().println("读取资源配置文件:" + url + "<br/>");  
        //使用MessageFormat.format方法,格式化输出
        response.getWriter().println(
            MessageFormat.format("name={0},user={1},password={2}",
                    name,user,password) 
            + "<hr/>"
        );

    } 

    public void doPost (HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException{

        this.doGet(request, response);

    }

}

那么,在浏览器中访问该servlet:
读取资源配置文件


此外,还可以使用类装载器来读取资源的配置文件

注意,这种方法不适合用来装载大文件,否则可能会造成JVM内存溢出。

例子如下(使用和上一个例子相同的目录)

package com.test1;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;

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

import com.sun.org.apache.xml.internal.security.Init;

public class AutoServlet extends HttpServlet {

    //利用类装载器读取资源配置文件
    public void doGet(HttpServletRequest request,HttpServletResponse response) 
        throws ServletException, IOException{

        /*等价于:response.setContentType("text/html;charset=UTF-8")
         * 将内容的字符集设为UTF-8,防止出现中文乱码
         */
        response.setHeader("content-type", "text/html;charset=UTF-8");
        //读取src.com.test1.db2.properties
        readProFile(response, "com/test1/db2.properties");
        //读取WebRoot文件夹下的db.properties文件
        readProFile(response, "db.properties"); 

    }

    //读取特定目录下的资源配置文件
    private void readProFile(HttpServletResponse response, String url) throws IOException
             {

        //获取类装载器
        ClassLoader loader = AutoServlet.class.getClassLoader();
        InputStream is = loader.getResourceAsStream(url);
        //按字节读出资源配置文件中的内容
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] by = new byte[1024];
        int len = 0;
        try {
            while((len = is.read(by))!= -1){ 
                baos.write(by, 0, len);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String content = new String(baos.toByteArray());
        response.getWriter().write("使用类装载器读取文件:" + url + "<br/>");
        response.getWriter().write(content + "<hr/>");

    } 

    public void doPost (HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException{

        this.doGet(request, response);

    }

}

浏览器访问的结果为:
类加载器访问资源配置文件
从图中可以看到,读取WEB-ROOT目录下的db.properties文件时,并没有成功地将内容读出来,后台报了一个空指针错误。
这是因为,类加载器是加载类路径下的文件,因此,配置的url路径与直接使用ServletContext读取配置文件时有所不同。此时,需要将配置文件放在src目录下,写路径时从包名开始写,前面不加正斜杠(/)


6.在客户端缓存servlet的输出

对于不常变化的数据,可以在servlet中设置一定缓存时间值,已避免浏览器频繁地像服务器发送请求,已提高服务器的性能。
如:

package com.test1;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;

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

import com.sun.org.apache.xml.internal.security.Init;

public class AutoServlet extends HttpServlet {

    public void doGet(HttpServletRequest request,HttpServletResponse response) 
        throws ServletException, IOException{

        /*设置合理的缓存时间,避免浏览器频繁向服务器发送请求
         * 这里将时间设为1天
         */
        String data = "This is some data";
        response.setDateHeader("expires", System.currentTimeMillis()+24*3600*1000);
        response.getOutputStream().write(data.getBytes());

    }

    public void doPost (HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException{

        this.doGet(request, response);

    }

}

从ie浏览器的“Internet选项-浏览历史记录-设置”位置,找到当前浏览器的缓存存放位置,但是,本机上查看时,并未找到对应名称的缓存文件,因此,此处持保留意见,有待后续补充。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值