自定义标签的应用
既然我们学了简单标签,我们就用简单标签来做开发吧!
防盗链
在讲解request对象的时候,我们讲解过怎么实现防盗链的功能。现在我们使用标签来进行防盗链!
模拟下场景:1.jsp页面是海贼王资源,2.jsp页面提示非法盗链,index1.jsp是我的首页。别人想要看我的海贼王资源,就必须通过我的首页点进去看,否则就是非法盗链!
- 标签处理器的代码:
@Override public void doTag() throws JspException, IOException { //如果想要做成更加灵活的,就把站点设置和资源设置成标签属性传递进来! //等会我们要获取得到request对象,需要使用到JspContext的子类PageContext PageContext pageContext = (PageContext) this.getJspContext(); //获取request对象 HttpServletRequest httpServletRequest = (HttpServletRequest) pageContext.getRequest(); //获取到referer String referer = httpServletRequest.getHeader("Referer"); //获取到response对象,等会如果是非法盗链,就重定向别的页面上 HttpServletResponse httpServletResponse = (HttpServletResponse) pageContext.getResponse(); //非法盗链! if (referer == null || !referer.startsWith("http://localhost:8080/zhongfucheng")) { //2.jsp提示了非法盗链! httpServletResponse.sendRedirect("/zhongfucheng/2.jsp"); //不执行页面下面的内容了,保护页面 throw new SkipPageException(); } }
1.jsp代码:
<zhongfucheng:Referer/> <html> <head> <title></title> </head> <body> 海贼王最新资源 </body> </html>
index1.jsp代码:
<h1>这是首页!</h1> <a href="${pageContext.request.contextPath}/1.jsp"> 海贼王最新资源</a>
2.jsp代码:
<body> 你是非法盗链的!!!!!! </body>
第一次我是直接访问1.jsp,Referer是为空的,所以是非法盗链。第二次我是通过从首页点进去看的,所以可以访问1.jsp。效果图:
if标签
在JSTL中,我们已经使用过了<c:if/>
标签了,现在我们学习了自定义标签,可以开发类似于JSTL的if标签了!
既然是if标签,那么就需要编写带属性和带标签体的标签(需要判断是true还是false呀!,通过判断是否为真值来决定是否执行标签体的内容)
- 标签处理器代码:
public class Demo1 extends SimpleTagSupport { //定义一个Boolean类型的变量 boolean test ; @Override public void doTag() throws JspException, IOException { //获取到代表标签体内容的对象 JspFragment jspFragment = this.getJspBody(); //如果为真值才执行标签体的内容 if (test == true) { jspFragment.invoke(null); } } public boolean isTest() { return test; } public void setTest(boolean test) { this.test = test; } }
tld文件的代码:
<tag> <name>if</name> <tag-class> tag.Demo1</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
本来就没有user这个域对象属性,所以user就是为null:
- 将user改成不为null,浏览器就没有输出了
forEach标签
forEach标签最基本的功能:遍历集合、数组
- 首先,我先写一个可以遍历List集合的标签,可能我们会这样设计:
public class Demo2 extends SimpleTagSupport { //遍历的是List集合,于是标签的属性就为List private List items; //遍历出来的对象就用Object存着,因为我们不知道List集合保存的是什么元素 private Object var; @Override public void doTag() throws JspException, IOException { //获取到迭代器 Iterator iterator = items.iterator(); //遍历集合 while (iterator.hasNext()) { //获取到集合的元素 var = iterator.next(); //.....var属性代表的就是集合的元素,现在问题来了,好像在标签体内无法获取到这个对象.... //做到这里完成不下去了.... } } public void setItems(List items) { this.items = items; } public void setVar(Object var) { this.var = var; } }
上面的思路是正常的,但是做不下去!我们换一个思路呗。上面的问题主要是在标签体获取不到被遍历出来的对象!
我们这样做:把var定义成String类型的,如果遍历得到对象了,就设置PageContext的属性,var为关键字,对象为值。在标签体用EL表达式搜索以var为关键字的对象!每遍历出一个对象,就执行一次标签体!
- 于是就有了以下的代码!
public class Demo1 extends SimpleTagSupport { //遍历的是List集合,定义List集合成员变量 private List items; //以var为关键字存储到PageContext private String var; @Override public void doTag() throws JspException, IOException { //获取到集合的迭代器 Iterator iterator = items.iterator(); //获取到代表标签体内容的对象 JspFragment jspFragment = this.getJspBody(); //遍历集合 while (iterator.hasNext()) { Object o = iterator.next(); //把遍历出来的对象存储到page范围中,关键字为标签的属性var(在标签体中使用EL表达式${var},就能够获取到集合的对象了!) this.getJspContext().setAttribute(var, o); //每设置了一个属性,我就执行标签体 jspFragment.invoke(null); } } public void setItems(List items) { this.items = items; } public void setVar(String var) { this.var = var; } }