java中out的含义6_javaweb中的相对路径、绝对路径问题;反斜杠在不同场景含义

JavaWeb项目中用Servlet实现学生签到和下载文件功能,过程中遇到了一些路径上的问题,做个总结。最后贴有代码,用以理解问题出现的场景

目录结构:

08980278bad7cb11de81640cecb32f3d.png

学生签到实验(将从前端收到的学生签到信息记录在指定文件中,向login.txt中记录学生签到信息):1、多次试验发现,用相对路径(String path="/login.txt")可以找到文件,但是写不进去内容;2、用String path=this.getServletContext().getRealPath("/login.txt")方法获取绝对路径,可以写入,但是内容是记录在部署目录中,原因如下:

输出this.getServletContext().getRealPath("/login.txt")(或去掉斜杠)语句,得到:D:\myapps\my-ideaworksapce\JavaWebProject\out\artifacts\testServlet_war_exploded\StudentLoginServlet

可以看到,绝对路径被定位到了部署路径中。因为tomcat上运行的项目是编译、部署完成的项目

3、指定绝对路径D:\myapps\my-ideaworkspace\JavaWebProject\web\login.txt,可以在该目录下的文件中写入内容,而且部署路径out/artifacts/testServlet_war_exploded/WEB-INF/classes/login.txt会与之同步4、tomcat重启时会重新部署目录,因此之前的记录信息在tomcat重启后会不复存在

5、在web中的反斜杠/

① 和网页跳转相关的'/'代表从服务器根路径(locallost:8080/)开始定位

比如跳转

再比如重定向中的response.sendRedirect("/JavaWebProject/index.jsp");

注:之所以请求转发的跳转页面是从项目根路径开始寻找的request.getRequestDispatcher("/index.jsp").forward(request, response);因为请求转发相当于已经在当前项目中的网页,现在要跳转到该项目中的另一个网页,所以是从当前项目的根目录寻找要跳转的页面。请求转发和重定向的区别需要清楚。

② java中的'/'代表从项目部署后的项目根路径(localhost:8080//JavaWebProject)开始定位

下载文件实验:

InputStream fin=this.getServletContext().getResourceAsStream("/downloads/"+filename);//成功!

InputStream fin=new FileInputStream("/downloads/"+filename);//不起作用!

第一条语句可以将downloads中的文件作为字节流输出,并通过设置消息头提供下载功能,而二条语句却没有作用(无法在浏览器下载内容)。联系前面的实验结果“用相对路径(String path="/login.txt")可以找到文件,但是写不进去内容”。推测:Web项目无法直接通过相对路径进行流的操作

代码:

@WebServlet(urlPatterns = "/StudentLoginServlet" )

public class StudentLoginServlet extends HttpServlet {//直接继承Servlet类的话,this.getServletConfig.getServletContext.getRealPath()似乎有点问题

PrintWriter fout=null;//输出流,用于将从前端收到的学生签到信息记录在指定文件中。全局变量,供整个对象使用

ArrayList idCheck=new ArrayList<>();//记录历史签到id

ArrayList ipCheck=new ArrayList<>();//记录历史签到ip

@Override

public void init() throws ServletException {

String path="/login.txt";//文件路径

File file=new File(this.getServletContext().getRealPath(path));

try {

fout=new PrintWriter(file);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//解决乱码问题

req.setCharacterEncoding("utf-8");

resp.setContentType("text/html;charset=utf-8");

//获取表单数据

String stuId=req.getParameter("stuId");

String stuName=req.getParameter("stuName");

String stuAge=req.getParameter("stuAge");

//获取客户端的IP地址、签到时间

String IP=req.getRemoteAddr();

SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

String loginTime=format.format(new Date());

//将登陆信息记录到日志文件中

int index1=0;//判定id是否重复,0代表不重复,1代表重复

int index2=0;//判定ip是否重复,0代表不重复,1代表重复

if(fout!=null){

synchronized (this){

if(!idCheck.contains(stuId)&&!ipCheck.contains(IP)){

idCheck.add(stuId);

ipCheck.add(IP);

fout.println("学号为:"+stuId+",姓名是:"+stuName+",年龄是:"+stuAge+",IP地址为:"+IP+",签到时间为:"+loginTime);

fout.flush();

}else if(idCheck.contains((stuId))){

index1=1;

}else if(ipCheck.contains(IP)){

index2=1;

}

}

}

PrintWriter out=resp.getWriter();

if(index1==0&&index2==0){

out.println("签到成功!");

}else if(index1==1){

out.println("请勿重复签到!");

}else{

out.println("同一台机器只能签到一名同学!");

}

}

@Override

public void destroy() {

if(fout!=null){

fout.close();

}

}

}

public class ContextDownloadServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//设置相应头信息

String filename=req.getParameter("filename");//接收文件名

resp.setHeader("Content-Disposition","attachment;filename="+filename);

//获取绝对路径

String realpath=this.getServletContext().getRealPath("/downloads/" +filename);

System.out.println(realpath);

//发送文件

InputStream fin=this.getServletContext().getResourceAsStream("/downloads/" +filename);//成功!

//        InputStream fin=new FileInputStream("/downloads/"+filename);//不起作用!

OutputStream out=resp.getOutputStream();

byte[] buff=new byte[1024];

int len=-1;

while ((len=fin.read(buff))!=-1){

out.write(buff,0,len);

}

fin.close();

out.close();

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值