本文已参与「新人创作礼」活动,一起开启掘金创作之路。
4.23 第六个war包相关实验记录与相关问题的回答
依旧老动作,打开readme.jsp文件,阅读源文件和老师所给的题目要求,查看了解此war包的要求与实验内容
可以看出这次的要求是:
1.学会在读写文件之前,定位文件所在的位置
2.计数器的累加操作是如何实现的
3.注意web项目的IO操作,对其IO操作进行了解
这次Java的源文件由于太长了,截图无法展示,因此我用会直接将源码贴上来
package cn.edu.cuit.servlet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
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;
/**
* @author zhangzhilei
* <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读取文件中的信息
*/
public void init() throws ServletException{
count = 0;
System.out.println("在init中完成计数器的初始化");
sc = this.getServletContext();
path = sc.getRealPath("WEB-INF/count.txt");
try {
InputStream is = LifeServlet.class.getResourceAsStream("countinpackage.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String string;
string = br.readLine();
count = Integer.parseInt(string); //计数器完成初始化
br.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* <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 {
// 设置输出类型和编码字符集
response.setContentType("text/html;charset=utf-8");
// 获取out对象
PrintWriter out = response.getWriter();
// 计数器自增1
count++;
// 插旗
out.println("这个Servlet历史上已经被访问了"+count+"次了!");
// 写到文件的组合动作
// 1 获取输出流对象
OutputStream fw = new FileOutputStream(path);
// 2 得到写缓存
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fw));
// 3 准备好数据格式:字符串,由整数转换得到
String string = String.valueOf(count);
// 4 写回到文件
bw.write(string);
// 5 关闭文件相关资源
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方法被执行了一次");
}
}
上面是源码部分,看过我上一篇文章的同学,会发现,这边也存在path,上次我们的解决方式是,在servlet下面自己创建txt,这次,我们所需要的txt文件都给好了,并且有这一点需要注意,用class文件反射得到的是包下的路径count.txt发布以后,仍然在WEB-INF目录下countinpackage.txt发布后,跟随.java文件生成的.class文件位置,真实的项目发布时的路径,一般置于资源文件下,以后可以用maven来管理这一块的话,与我们后面要讲解的IO操作有关,我在文章后面会讲。
在看完这些之后,我们对html文件进行运行,查看页面输出和console输出结果
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个Servlet页面,注意Servlet的生命周期</title>
</head>
<body>
<form method="post" action="lifeCycle">
<input type="submit" value="激活一个Servlet" />
</form>
</body>
</html>
那么为什么明明我们第一次用Servlet运行这个项目,初始却会显示历史上已经访问了1000次呢?
这就让我们回看源码,我们在这边可以看到,开始我们InputStream is由countipackage.txt赋值,之后BufferReader br读入其is的值,然后定义为String变量,然后赋值给count,在此我们完成了count的初始化,这其实也就是运行前的准备工作
*
*
因此,我们可以通过countipackage.txt里的值来改变其初始值,如这边,我改为了500.
这方面的话,运行阶段没有什么问题了,那么现在来了解一下IO操作是什么
I:就是input 、O:就是output ;称为:输入输出流。
IO操作,就是将数据写入内存或从内存输出的过程,也指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。
常见IO流操作,一般指内存与磁盘间的输入输出流操作。
那么代入我们这次的war包呢,就是
注意web项目中的IO操作,在读写文件之前,要定位文件所在的位置。用class文件反射得到的是包下的路径,count.txt发布以后仍然在WEB-INF目录下,countinpackage.txt发布后,跟随.java文件生成的.class文件位置,真实的项目发布时的路径,一般置于资源文件下,我们以后可以用maven来管理
在tomcat下直接测试时,是一个临时目录
.metadata/.plugin/在这个目录下才看得到发布的项目D:\eclipse_workspace_20192.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
在发布以后,包名会转化为一层层的目录
cn.edu.cuit.servlet即cn/edu/cuit/servlet
如下图
就这样吧!完成第六个包的讲解啦