javaweb标签

总体来说jsp和el和jstl等都是java的标签编程,其工作原理都是一样的,使用到了反射等一些技术

jsp标签:

javabean

bean:
package senssic.demo.bean;

public class UserBean {
	private String username;
	private int age;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}
jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@page  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 使用javabean -->
<!-- 可以使用里面的scop属性更改作用范围,默认为page范围 -->
<jsp:useBean id="user" class="senssic.demo.bean.UserBean"></jsp:useBean>
<!-- 设置属性 -->
<%
user.setUsername("senssic");
%>
<jsp:setProperty property="age" name="user" value="20"/>
<!-- 获得属性 -->
用户名:<jsp:getProperty property="username" name="user"/>
年龄:${user.age}
头信息:${header}
</body>
</html>
tomcat产生的java文件,一看就明白了标签原理了
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class javabean_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("    \r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("<!-- 使用javabean -->\r\n");
      out.write("<!-- 可以使用里面的scop属性更改作用范围,默认为page范围 -->\r\n");
      senssic.demo.bean.UserBean user = null;
      synchronized (_jspx_page_context) {
        user = (senssic.demo.bean.UserBean) _jspx_page_context.getAttribute("user", PageContext.PAGE_SCOPE);
        if (user == null){
          user = new senssic.demo.bean.UserBean();
          _jspx_page_context.setAttribute("user", user, PageContext.PAGE_SCOPE);
        }
      }
      out.write("\r\n");
      out.write("<!-- 设置属性 -->\r\n");

user.setUsername("senssic");

      out.write('\r');
      out.write('\n');
      org.apache.jasper.runtime.JspRuntimeLibrary.introspecthelper(_jspx_page_context.findAttribute("user"), "age", "20", null, null, false);
      out.write("\r\n");
      out.write("<!-- 获得属性 -->\r\n");
      out.write("用户名:");
      out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString((((senssic.demo.bean.UserBean)_jspx_page_context.findAttribute("user")).getUsername())));
      out.write("\r\n");
      out.write("年龄:");
      out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${user.age}", java.lang.String.class, (PageContext)_jspx_page_context, null, false));
      out.write("\r\n");
      out.write("头信息:");
      out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${header}", java.lang.String.class, (PageContext)_jspx_page_context, null, false));
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
其中定义jsp标签的dtd文件在:
jsp-api.jar:javax.servlet.jsp.resources.jspxml.dtd

EL表达式语言

el是通过java程序对el的表达式进行解析,然后通过反射和jsp标签一起共同发生作用
el的内置对象
"applicationScope", :表示从applicationScope属性范围内查找输出属性
"cookie", :取出cookie的数据
"header",:取得一个头信息数据
 "headerValues",:取出一组头信息数据
 "initParam",:取得配置的初始化参数
 "pageContext",:表示javax.servlet.jsp.PageContext对象
 "pageScope",表示冲page属性范围查找输出属性
 "param",:接受传递到本页面的参数
 "paramValues",:接受传递到本页面的一组参数
 "requestScope", :表示从request属性范围内查找输出属性
"sessionScope":表示从session属性范围内查找输出属性
这些参数在jsp-api.jar:javax.servlet.jsp.el.ImplicitObjectElResolver

自定义el表达式语言:
直接使用el的扩展就可以自己编写了
先编写java处理代码:
package senssic.demo.el;

public class ElClass {
	public static int max(int a, int b) {//必须是静态方法
		return a > b ? a : b;
	}
}

编写tld描述文件:
<?xml version="1.0" encoding="UTF-8"?>  
<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">
<!-- 当然你也可以使用 web-jsptaglibrary_2_0.dtd-->
<tlib-version>1.0</tlib-version>
<short-name>mytag</short-name>
<function>
 <name>max</name>
 <function-class>senssic.demo.el.ElClass</function-class>
 <function-signature>
 int max(int,int)
 </function-signature>
 <example>${mytag:max(20,30)}</example>
</function>  
</taglib>

编写jsp文件并引用(当然也可以将tld文件引用写在web.xml里面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="mytag" uri="/WEB-INF/taglib/mytag.tld" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>使用自定义el表达式</h1>
${mytag:max(20,30)}
</body>
</html>
当然这个el语言的功能太弱了,但自己定义的el是不能获取到request和servlet等对象的。因为el是内层原理是使用java分解((java.lang.String) org.apache.jasper.runtime.PageContextImpl
.proprietaryEvaluate("${header}", java.lang.String.class,
_jspx_page_context, null, false))在jsp的java源码中。如果真想使用到标签得到pagecontext等属性需要使用jsp标签编程

jsp自定义标签


无标签体

java源码:
package senssic.demo.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class JspTag extends TagSupport {
	// 继承tagsupport就可使用其中的pageContext来获取各个jsp内置对象属性(通过反射实现的)
	// 各个属性可以控制标签的操作如:skip_body:跳过标签体等
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int doStartTag() throws JspException {
		JspWriter jWriter = pageContext.getOut();
		try {

			if (pageContext.getAttribute(name) != null) {
				jWriter.write(name + "的属性范围为page");
			} else if (pageContext.getServletContext().getAttribute(name) != null) {
				jWriter.write(name + "的属性范围为application");
			} else if (pageContext.getRequest().getAttribute(name) != null) {
				jWriter.write(name + "的属性范围为request");
			} else if (pageContext.getSession().getAttribute(name) != null) {
				jWriter.write(name + "的属性范围为session");
			} else {
				jWriter.write("不能找到对应的属性!");
			}
		} catch (Exception e) {
		}
		return SKIP_BODY;
	}

}

tld描述文件
<?xml version="1.0" encoding="UTF-8"?>  
<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">
<tlib-version>1.0</tlib-version>
<short-name>jsptag</short-name>
<tag>
  <name>showscope</name>
  <tag-class>senssic.demo.tag.JspTag</tag-class>
  <!-- body-content将忽视tag的标签体 -->
  <body-content>empty</body-content>
  <attribute>
    <name>name</name>
    <required>true</required>
    <!-- 支持表达式<%%> -->
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>
</taglib>
jsp文件:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="mytag" uri="jsptag"%><!--这个实在web.xml配置了,也可以直接使用uri指向-->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
pageContext.setAttribute("pagescope", "pagename");
request.setAttribute("requsetscope", "requestname");
session.setAttribute("sessionscope", "sessionname");
application.setAttribute("application", "applicationname");
%>
<mytag:showscope name="pagescope"/>
<br>
<mytag:showscope name="something"/>
</body>
</html>
web.xml--如果使用web中配置的话
 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

 <jsp-config>
   <taglib>
    <taglib-uri>jsptag</taglib-uri>
   <taglib-location>/WEB-INF/taglib/jsptag.tld</taglib-location>
  
   </taglib>
  </jsp-config>
</web-app>

有标签体

java源文件:

package senssic.demo.tag;

import java.io.IOException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class JspBodyTag extends TagSupport {
	private String value;
	private String name;
	private int i = 0;
	private Cookie[] cookie;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int doStartTag() throws JspException {
		HttpServletRequest hRequest = (HttpServletRequest) pageContext
				.getRequest();
		cookie = hRequest.getCookies();

		if (!(cookie.length < 0)) {
			pageContext.setAttribute(name, cookie[i].getName());
			pageContext.setAttribute(value, cookie[i].getValue());
			return EVAL_BODY_INCLUDE;
		} else {
			try {
				pageContext.getOut().write("没有发现有cookie");
			} catch (IOException e) {
				e.printStackTrace();
			}
			return SKIP_BODY;
		}

	}

	@Override
	public int doAfterBody() throws JspException {
		i++;
		if (i < cookie.length) {
			pageContext.setAttribute(name, cookie[i].getName());
			pageContext.setAttribute(value, cookie[i].getValue());
			return EVAL_BODY_AGAIN;

		} else {
			return SKIP_BODY;
		}
	}

}

tld描述语言
<?xml version="1.0" encoding="UTF-8"?>  
<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">
<tlib-version>1.0</tlib-version>
<short-name>JspBodyTag</short-name>
<tag>
 <name>cookieinfo</name>
 <tag-class>senssic.demo.tag.JspBodyTag</tag-class>
 <body-content>JSP</body-content><!--输出标签体内部的jsp-->
 <attribute>
 <description>return the cookie name corresponding value</description>
   <name>value</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
 <description>return the cookie name</description>
    <name>name</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
 </attribute>
</tag>


</taglib>

jsp文件:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="myjbt" uri="/WEB-INF/taglib/jspbodytag.tld"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<myjbt:cookieinfo name="name" value="value">
     cookie名字:${name}<br>
     cookie值:${value}<br>
</myjbt:cookieinfo>
</body>
</html>
注:也可以直接继承BodyTagSupport类来处理标签体(很重要),有兴趣的可以研究一下,比如更复杂的将name和value变成jsp中的变量使用需要使用(BodyIterateTagExtraInfo类支持)并需要在标签tld文件中中使用<tag><tei-class>xxx.xxx.xx</tei-class></tag>


当然也有简单的标签编程方法就是使用继承SimpleTagSupport类,这样我们设置好属性不用再每次反射调用,而是封装好了,直接使用父类的getJspBody().invoke(xxx);就能达到每次的输出。
当然还可以使用DynamicAttributes类来动态设置<attribute>的属性

jsp标准标签库jstl

原理都是一样的,封装了我们经常使用的标签下载地址: http://jstl.java.net/download.html,一般下载
  • JSTL Implementation因为jstl api是不是开发版的需要我们自己实现。
  • tld可以再web.xml <jsp-config></jsp-config>中配置也可以直接在jsp中引用





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值