首页 > 网站 > WEB开发 > 正文

servlet学习笔记(二)

2024-04-27 15:10:54
字体:
来源:转载
供稿:网友

参考: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选项-浏览历史记录-设置”位置,找到当前浏览器的缓存存放位置,但是,本机上查看时,并未找到对应名称的缓存文件,因此,此处持保留意见,有待后续补充。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表