我们用之前学习的自定义标签技术,来写一些案例熟练一下。
首先我们开发一个防盗链标签。
有些同学可能不太清楚什么是防盗链,之前学习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页面。
我们创建标签处理器类:
在处理器类中编写防盗链的逻辑:
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
发现直接跳转到首页了...
我们在首页中点击“查看机密文档”的超链接,就会安全的跳转到机密文档页面,而不会被拦截,因为这不属于盗链行为:
以上就是一个防盗链的标签的开发过程。