第五个war包源码解释和操作方法以及解释计数器累加操作如何实现(学j2ee的第九天)

275 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

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显示

image.png

image.png 我们可以看到console中出现了null的字符显示,打开源码,查找显示出该NULL的原因,可以看到是由于首次读取时,没有文件,可能会有异常Null

image.png

可是看源代码,这边不是有一个“contect.txt”的文件地址吗,为什么会说没有文件呢

image.png

原因在于,我们在运行文件时,他所调用的txt文件,并不是我们看到的那个,结合以前的知识,就是说,当我们进行运行时,他并不是直接运行,而是通过run as on server来进行运行,我是用的tomcat,因此现在需要什么,是的,就是理解源代码,然后在真正运行的环境中,进行txt文件的增加,大家可以看到,这边我改为了C1.txt

image.png 在任意一个servlet中创建,之后会同时出现两个

image.png

此时和大家解释源码,从这边可以看到,他会对于我们刚创建的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,给大家演示一下

image.png

image.png

这次console输出如下:可以看到,做法正确,至于触发destroy()的方法,大家可以去看我上一篇(第四个war包实验记录之destroy()的调用方法、运用插旗观察程序运行(第八次j2ee学习) - 掘金 (juejin.cn))

image.png

源码部分解决完毕


readme问题回答 计数器的累计操作是如何实现的: 答:其实感觉还是源码部分的更深解释,就其实只是读入c1.txt文件的数字(此文件为自定义),然后将文件中的字符转为数字,赋给count,完成计数器初始化,计数时,其实存在中间变量一直记录,然后再赋给count。

话说这次第五个war包的难度比上次大了一点