4.23 第五个war包相关实验记录与相关问题的回答
看过我另一个代码网站前几篇j2ee文章的大家应该都知道,我个人习惯为在进行实验进行之前,点开readme.jsp和其他所有源码,查看了解此war包的要求与实验内容
本次实验readme内容要求为:
1 利用上下文对象获取服务器上的文件里的数据
2 计数器的累计操作是如何实现的
3 在生命周期函数里的初始化函数中做一些Servlet的准备工作
源码运行部分
第一步,看LifeServle.java源代码以及注释,因为此次代码较长,所以将代码其中一部分进行了删减,便于大家观看和理解
/**
* <li>演示Servlet的生命周期
*/
@WebServlet("/LifeServlet")
public class LifeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 声明计数器,上下文对象,路径
int count;
ServletContext sc;
String path;
/**
* <li> 做一些准备工作
* <li> 1 获取上下文环境
* <li> 2从上下文对象获取文件路径
* <li> 3读取文件中的信息
* <li>
* <li> 注意,首次读取时,因为没有文件,可能会有异常Null
* <li> 然后用不同的浏览器来访问时,就可以看到共享的计数了
*/
public void init() throws ServletException{
//count = 0;
System.out.println("在init中完成计数器的初始化begin");
sc = this.getServletContext();
path = sc.getRealPath("WEB-INF/count.txt");
System.out.println(path);
try {
InputStream is = LifeServlet.class.getResourceAsStream("c1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String string = br.readLine();
System.out.println("读到的字符串是:"+string);
count = Integer.parseInt(string);
br.close();
is.close();
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
System.out.println("在init中完成计数器的初始化end");
}
/**
* <li> 销毁
*/
public void destroy() {
System.out.println("Servlet已经释放");
}
/**
* @see HttpServlet#HttpServlet()
*/
public LifeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* <li> 处理输出到响应中的信息
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
count++;
out.println("这个Servlet历史上已经被访问了"+count+"次了!");
OutputStream fw = new FileOutputStream(path);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fw));
String string = String.valueOf(count);
bw.write(string);
bw.close();
fw.close();
System.out.println("该Servlet的doGet方法被执行了一次");
}
/**
* @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);
System.out.println("该Servlet的doPost方法被执行了一次");
}
}
从源码中我们可以看出,这次实验前,我们需要做一些准备工作,由于笔者对于J2ee的了解较为浅薄,所以没有看懂,当时直接开始运行,想着看看效果再来进行实验,下图分别为浏览器显示与console显示
我们可以看到console中出现了null的字符显示,打开源码,查找显示出该NULL的原因,可以看到是由于首次读取时,没有文件,可能会有异常Null
可是看源代码,这边不是有一个“contect.txt”的文件地址吗,为什么会说没有文件呢
原因在于,我们在运行文件时,他所调用的txt文件,并不是我们看到的那个,结合以前的知识,就是说,当我们进行运行时,他并不是直接运行,而是通过run as on server来进行运行,我是用的tomcat,因此现在需要什么,是的,就是理解源代码,然后在真正运行的环境中,进行txt文件的增加,大家可以看到,这边我改为了C1.txt
在任意一个servlet中创建,之后会同时出现两个
此时和大家解释源码,从这边可以看到,他会对于我们刚创建的C1.txt文件进行读写,当没有读取到时,则抛出异常,输出null(这也是我们第一次直接运行时,出现NULL的原因)
try {
InputStream is = LifeServlet.class.getResourceAsStream("c1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String string = br.readLine();
System.out.println("读到的字符串是:"+string);
count = Integer.parseInt(string);
br.close();
is.close();
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
之后运行时,“这个Servlet历史上已经被访问了***次了!”的初始页面值就为我们在C1.txt文件中所定义的数字,我定义为100,给大家演示一下
这次console输出如下:可以看到,做法正确,至于触发destroy()的方法,大家可以去看我上一篇文章 destroy()调用方法
源码部分解决完毕
readme问题回答
计数器的累计操作是如何实现的:
答:其实感觉还是源码部分的更深解释,就其实只是读入c1.txt文件的数字(此文件为自定义),然后将文件中的字符转为数字,赋给count,完成计数器初始化,计数时,其实存在中间变量一直记录,然后再赋给count。
话说这次第五个war包的难度比上次大了一点