我们用之前学习的自定义标签技术,来写一些案例熟练一下。

首先我们开发一个防盗链标签。
有些同学可能不太清楚什么是防盗链,之前学习Jsp技术的时候就有提到过,这里再给不知道的同学啰嗦一下:

有的资源你点出后会有广告,广告旁边是资源连接,有些人直接把资源连接发给别人,企图不看广告直接进入链接拿资源,为了防止盗链行为的发生,我们要检测用户访问url的情况来进行一系列措施。

需要实现的功能就是,当用户想要查看"机密文档"的时候,如果是直接输入机密文档的url,而不是广告的url,我们得先让他跳转到广告页面的url,看完广告后就可以让他看“机密文档”了。

我们的机密文档页面如下所示:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/example" prefix="z" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<z:referer site="http://localhost:8081/JspTest/" page="/index.jsp"/>
<html>
  <head>
    <title>带属性的标签</title>
  </head>
  
  <body> 
      SECRET_机密文档!!!!!!
  </body>
  
</html>


其中的<z:referer/>就是防盗链标签,其中site就是放行的站点,如果不是从这个站点访问的,而是直接访问这个资源页面,那么用户就会被强制跳转至page页面。



我们创建标签处理器类:


【自定义标签开发】06-标签案例-开发防盗链标签_标签



在处理器类中编写防盗链的逻辑:


package org.zyg.web.exampleTag;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class RefererTag extends SimpleTagSupport {
	private String site;
	private String page;
	
	public void setSite(String site) {
		this.site = site;
	}
	
	public void setPage(String page) {
		this.page = page;
	}
	
	@Override
	public void doTag() throws JspException, IOException {
		
		PageContext pageContext=(PageContext)this.getJspContext();
		HttpServletRequest request=(HttpServletRequest) pageContext.getRequest();
		HttpServletResponse response=(HttpServletResponse) pageContext.getResponse();
		
		//1.得到来访者referer
		String referer=request.getHeader("referer");
		
		//2.判断来访者的页面是不是要放行的网站
		if(referer==null||!referer.startsWith(site)){//不是从site指定站点来的,都是盗链,不放行
			
			if(page.startsWith(request.getContextPath())){//是以Web应用为开头(JspTest/index.jsp)
				response.sendRedirect(page);
			}else if(page.startsWith("/")){//是以某网页资源为开头(/index.jsp)
				response.sendRedirect(request.getContextPath()+page);
			}else{//其他情况(如直接写index.jsp)
				response.sendRedirect(request.getContextPath()+"/"+page);
			}
			
			//余下的jsp代码不执行
			throw new SkipPageException();
			
		}else{//不是盗链者
			//不抛出任何异常,用户可以看到资源
		}
	}
}



倒链者如果不是在http://localhost/JspTest/站点下跳转过来的,就会之前强制跳转到主页:


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>主页</title>
  </head>
  
  <body>
  
  	嘿倒链者!这里是主页!
     	<a href="/JspTest/example/1.jsp">查看机密文档</a>
  </body>
  
</html>

通过点击超链接才能查看机密文档。



我们在之前在lib文件夹创建的的z.tld标签描述文件,然后再其中注册这个标签:


<taglib 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-jsptaglibrary_2_0.xsd"
    version="2.0">

    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>z</short-name>
    <uri>/example</uri><!-- 标签绑定的uri,用于引入 -->
    
    <!-- 案例标签 -->
    <tag>
	    <name>referer</name><!-- 标签名 -->
	    <tag-class>org.zyg.web.exampleTag.RefererTag</tag-class>
	    <body-content>empty</body-content><!-- 有无标签体(单标签还是成对标签) -->
	
		<attribute>
			<name>site</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		
		<attribute>
			<name>page</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
 
</taglib>


然后重启Web项目测试,我们首先直接去访问这个页面:


http://localhost:8081/JspTest/example/1.jsp

发现直接跳转到首页了...



我们在首页中点击“查看机密文档”的超链接,就会安全的跳转到机密文档页面,而不会被拦截,因为这不属于盗链行为:



以上就是一个防盗链的标签的开发过程。