web后端--一个小小的下载和防盗链功能

下载功能代码:

//1获取要下载的文件名
		String filename = req.getParameter("filename");
		//如果没有文件名
		if(filename==null||"".equals(filename=filename.trim())){
			//设置响应头,防止响应乱码
			resp.setContentType("text/html;charset=UTF-8");
			resp.getWriter().write("请指定要下载的文件名");
			return;
		}
		//下载逻辑
		//2.获取要下载的MIME类型
		int lastIndexOf = filename.lastIndexOf(".");
		String mimeType=null;
		String substring =null;
		if(lastIndexOf<=0){
			// 2.1 没有后缀,MIME 类型设置为二进制文件类型
			mimeType = req.getServletContext().getMimeType(".bin");
		}else{
			// 2.2 拿到要下载的文件的后缀
			substring = filename.substring(lastIndexOf);//获取.后面的名称,比如:是soso.apk,则获取到.apk
			mimeType = req.getServletContext().getMimeType(substring);
			if(mimeType==null||"".equals(mimeType=mimeType.trim())){
				// 如果当前后缀没有查到相应的MIME 类型,同样的设置为二进制文件类型
				mimeType = req.getServletContext().getMimeType(".bin");
			}
		}
		//3.获取文件输入流
		InputStream in = req.getServletContext().getResourceAsStream("/download/"+filename);
		if(in==null){
			 // 如果没有找到要下载的文件
			resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("文件[" + filename + "]不存在,请检查文件名再试");
            return;
		}
		
		// 4. 设置响应头
        // 4.1 设置响应正文的MIME 类型
		resp.setContentType(mimeType);
        // 4.2 设置响应正文的长度,byte
        resp.setContentLength(in.available());
        // 4.3 设置下载文件的描述信息(待下载文件的文件名)
        resp.addHeader("Content-Disposition", "attachment;filename=" + filename);
        
		// 5.输出响应正文,也就是文件
		OutputStream out = resp.getOutputStream();
		byte[] buffer=new byte[1024];
		int length=0;
		while((length=in.read(buffer))!=-1){
			out.write(buffer, 0, length);
		}
		in.close();

防盗链功能:

//防盗链
	// 根据Referer 请求头,确定当前请求是否来自本网站
        // 如果不是,响应 404, 并狠狠地骂回去
		String referer = req.getHeader("Referer");
		if(referer!=null&&!"".equals(referer=referer.trim())){
			//获取请求的来路应用,http://localhost:8080/testDaoLian/ ---->这个是盗链的例子
			int index = referer.lastIndexOf("/");//最后一个‘/’
			String substring = referer.substring(0, index);//获取到http://localhost:8080/testDaoLian
			index = substring.lastIndexOf("/");
			String srcContextPath = substring.substring(index);//获取到/testDaoLian
			String contextPath = req.getContextPath();//获取到自己/download
			if(!contextPath.equals(srcContextPath=srcContextPath.trim())){
				resp.sendError(404, "你这条盗链狗!!!!");
				return;
			}
		}

源码与运行结果:

创建CommonDownloadServlet的类:

package com.lza.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CommonDownloadServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//防盗链
		// 根据Referer 请求头,确定当前请求是否来自本网站
        // 如果不是,响应 404, 并狠狠地骂回去
		String referer = req.getHeader("Referer");
		if(referer!=null&&!"".equals(referer=referer.trim())){
			//获取请求的来路应用,http://localhost:8080/testDaoLian/ ---->这个是盗链的例子
			int index = referer.lastIndexOf("/");//最后一个‘/’
			String substring = referer.substring(0, index);//获取到http://localhost:8080/testDaoLian
			index = substring.lastIndexOf("/");
			String srcContextPath = substring.substring(index);//获取到/testDaoLian
			String contextPath = req.getContextPath();//获取到自己/download
			if(!contextPath.equals(srcContextPath=srcContextPath.trim())){
				resp.sendError(404, "你这条盗链狗!!!!");
				return;
			}
		}
		
		//1获取要下载的文件名
		String filename = req.getParameter("filename");
		//如果没有文件名
		if(filename==null||"".equals(filename=filename.trim())){
			//设置响应头,防止响应乱码
			resp.setContentType("text/html;charset=UTF-8");
			resp.getWriter().write("请指定要下载的文件名");
			return;
		}
		//下载逻辑
		//2.获取要下载的MIME类型
		int lastIndexOf = filename.lastIndexOf(".");
		String mimeType=null;
		String substring =null;
		if(lastIndexOf<=0){
			// 2.1 没有后缀,MIME 类型设置为二进制文件类型
			mimeType = req.getServletContext().getMimeType(".bin");
		}else{
			// 2.2 拿到要下载的文件的后缀
			substring = filename.substring(lastIndexOf);//获取.后面的名称,比如:是soso.apk,则获取到.apk
			mimeType = req.getServletContext().getMimeType(substring);
			if(mimeType==null||"".equals(mimeType=mimeType.trim())){
				// 如果当前后缀没有查到相应的MIME 类型,同样的设置为二进制文件类型
				mimeType = req.getServletContext().getMimeType(".bin");
			}
		}
		//3.获取文件输入流
		InputStream in = req.getServletContext().getResourceAsStream("/download/"+filename);
		if(in==null){
			 // 如果没有找到要下载的文件
			resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("文件[" + filename + "]不存在,请检查文件名再试");
            return;
		}
		
		// 4. 设置响应头
        // 4.1 设置响应正文的MIME 类型
		resp.setContentType(mimeType);
        // 4.2 设置响应正文的长度,byte
        resp.setContentLength(in.available());
        // 4.3 设置下载文件的描述信息(待下载文件的文件名)
        resp.addHeader("Content-Disposition", "attachment;filename=" + filename);
        
		// 5.输出响应正文,也就是文件
		OutputStream out = resp.getOutputStream();
		byte[] buffer=new byte[1024];
		int length=0;
		while((length=in.read(buffer))!=-1){
			out.write(buffer, 0, length);
		}
		in.close();
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doGet(req, resp);
	}
}
创建downloadView.html:





下载首页



	
下载列表
文件名 操作
1.txt 下载
test 下载
timg.jpg 下载

配置文件web.xml:



  download
  
    downloadView.html
  
  
  
	imgdownload  
	com.lza.servlet.ImageDownloadServlet
  
  
  	imgdownload
  	/imgdownload
  
  
  
	commondownload  
	com.lza.servlet.CommonDownloadServlet
  
  
  	commondownload
  	/commondownload
  
    
	login  
	com.lza.servlet.LoginServlet
  
  
  	login
  	/login
  

项目图:

web后端--一个小小的下载和防盗链功能_第1张图片


盗链的测试只要重新弄个项目testDaoLian,把download项目中的downloadView.html复制过来就行了

盗链的项目图:

web后端--一个小小的下载和防盗链功能_第2张图片


不盗链的结果截图:

web后端--一个小小的下载和防盗链功能_第3张图片

下载1.txt:

web后端--一个小小的下载和防盗链功能_第4张图片

web后端--一个小小的下载和防盗链功能_第5张图片


盗链测试截图:

web后端--一个小小的下载和防盗链功能_第6张图片

点击1.TXT下载:

web后端--一个小小的下载和防盗链功能_第7张图片

你可能感兴趣的:(web后端--一个小小的下载和防盗链功能)