HackPig520's Blog
你好啊朋友~

转载自:https://blog.csdn.net/yuchencn/article/details/83809791

郭靖所供职的公司是一家网络公司,这天中午和拖雷一起吃饭,两人聊起了公司遇到的一个问题,

公司的问题:
  由于公司是做网站的,因此会有素材服务器,以前在网站中所有用到素材的地方都直接写的素材文件的绝对下载地址,因此素材的目录部署结构都被暴露在网络中,这样就出现了两个问题:

1,素材服务器的目录结构部署很容易被人了解到.

2,素材没有签权,容易被盗链

郭靖听到这个两个问题,下午没事就试着实现了防盗链,以下是郭靖的解决方案:

郭靖利用了urlrewriter和文件流输出解决了这个问题,

urlrewriter是url重新定向,把原有的符合某些规则的url定向到一个jsp,然后在这个jsp里实现签权 ,下面郭靖将带您一步一步实现这个防盗链

第一步:新建工程,引入依赖包,在本例子中需要引用urlrewrite-3.0.4.jar包

下图是我的目录结构图

第二步:在web.xml中配置urlrewriter的过滤器,配置如下:

Web.xml代码

<?xml version="1.0" encoding="UTF-8"?>   
<web-app version="2.4"    
    xmlns="http://java.sun.com/xml/ns/j2ee"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">   
&lt;filter&gt;&lt;!-- 配置urlRewriter过滤器 --&gt;   
&lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;   
&lt;filter-class&gt;org.tuckey.web.filters.urlrewrite.UrlRewriteFilter&lt;/filter-class&gt;   
&lt;init-param&gt;   
  &lt;description&gt;是否可以重新载入&lt;/description&gt;   
  &lt;param-name&gt;confReloadCheckEnabled&lt;/param-name&gt;   
  &lt;param-value&gt;true&lt;/param-value&gt;   
&lt;/init-param&gt;   
&lt;init-param&gt;   
  &lt;description&gt;重新载入时间&lt;/description&gt;   
  &lt;param-name&gt;confReloadCheckInterval&lt;/param-name&gt;   
  &lt;param-value&gt;1800&lt;/param-value&gt;   
&lt;/init-param&gt;   

</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

&lt;filter&gt;&lt;!-- 配置urlRewriter过滤器 --&gt;
&lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.tuckey.web.filters.urlrewrite.UrlRewriteFilter&lt;/filter-class&gt;
&lt;init-param&gt;
  &lt;description&gt;是否可以重新载入&lt;/description&gt;
  &lt;param-name&gt;confReloadCheckEnabled&lt;/param-name&gt;
  &lt;param-value&gt;true&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
  &lt;description&gt;重新载入时间&lt;/description&gt;
  &lt;param-name&gt;confReloadCheckInterval&lt;/param-name&gt;
  &lt;param-value&gt;1800&lt;/param-value&gt;
&lt;/init-param&gt;

</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

</web-app>

第三步:配置urlrewrite.xml,设置url转化规则

Urlrewrite.xml代码

<?xml version="1.0" encoding="utf-8"?>   
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN" "http://tuckey.org/res/dtds/urlrewrite2.6.dtd">   
<!--   
    Configuration file for UrlRewriteFilter   
    http://tuckey.org/urlrewrite/   
-->   
<urlrewrite>   
    <!-- 编写url转换规则,把所有mp3的访问全部都转移到downloadmp3.jsp进行处理 -->   
    <rule enabled="true">   
        <from>/mp3file/(.+)</from>   
        <to>/mp3/downloadmp3.jsp?file=$1</to>   
    </rule>   

</urlrewrite>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN" "http://tuckey.org/res/dtds/urlrewrite2.6.dtd">
<!--
Configuration file for UrlRewriteFilter
http://tuckey.org/urlrewrite/
-->
<urlrewrite>
<!-- 编写url转换规则,把所有mp3的访问全部都转移到downloadmp3.jsp进行处理 -->
<rule enabled="true">
<from>/mp3file/(.+)</from>
<to>/mp3/downloadmp3.jsp?file=$1</to>
</rule>

</urlrewrite>

第四步:编写文件下载签权使用的downloadmp3.jsp,代码如下

Downloadmp3.jsp代码

<%@page language="java"  pageEncoding="gb2312"%>      
<%@page import="java.io.FileInputStream"%>   
<%      
  //可以在这里先完成签权,检查该用户是否有资格进行mp3文件下载   
  //采用文件流输出的方式处理mp3下载:      
  String filename=request.getParameter("file");   
  response.reset();//可以加也可以不加      
  response.setContentType("audio/mpeg");   //设置返回头类型   

//设置下载时显示的文件名
response.addHeader("Content-Disposition","attachment;filename="+filename );

java.io.OutputStream outp = null;
java.io.FileInputStream in = null;

//文件所在的真实路径
String realfilepath="D:\y\testdownload\WebRoot\mp3\download\";

try
{
outp = response.getOutputStream();
in = new FileInputStream(realfilepath+filename);

byte[] b = new byte[1024];
int i = 0;

while((i = in.read(b)) > 0)
{
outp.write(b, 0, i);
}

outp.flush();
out.clear();
out = pageContext.pushBody();
}
catch(Exception e)
{
System.out.println("Error!");
e.printStackTrace();
}
finally
{
if(in != null)
{
in.close();
in = null;

}

}
%>
<%@page language="java" pageEncoding="gb2312"%>
<%@page import="java.io.FileInputStream"%>
<%
//可以在这里先完成签权,检查该用户是否有资格进行mp3文件下载
//采用文件流输出的方式处理mp3下载:
String filename=request.getParameter("file");
response.reset();//可以加也可以不加
response.setContentType("audio/mpeg"); //设置返回头类型

//设置下载时显示的文件名
response.addHeader("Content-Disposition","attachment;filename="+filename );

java.io.OutputStream outp = null;
java.io.FileInputStream in = null;

//文件所在的真实路径
String realfilepath="D:\y\testdownload\WebRoot\mp3\download\";

try
{
outp = response.getOutputStream();
in = new FileInputStream(realfilepath+filename);

byte[] b = new byte[1024];
int i = 0;

while((i = in.read(b)) > 0)
{
outp.write(b, 0, i);
}

outp.flush();
out.clear();
out = pageContext.pushBody();
}
catch(Exception e)
{
System.out.println("Error!");
e.printStackTrace();
}
finally
{
if(in != null)
{
in.close();
in = null;

}

}
%>

OK,到此我们的文件防盗链功能也就完成了,你现在可以实现一下,在浏览器地址栏输入出mp3地址,就会被跳到filedown.jsp,你可以在downloadmp3.jsp中完成签权以及其它需要的工作,而且从用户体验来讲,他根本感觉不到这是在访问一个jsp,用户看到的还是在下功一个普通的mp3文件而已

posted on 2022-06-12 19:54  HackPig520  阅读(124)  评论(0编辑  收藏  举报