自定标签----Java进阶篇

    xiaoxiao2024-10-29  73

    目录

    一.引入

    二.自定义标签

    三.自定义标签的的执行过程

    四.自定义标签处理器类的生命周期

    五.自定义标签的作用

    六.自定义标签案例

    七.javaBean

    八.web开发模式的简介


    一.引入

    当jsp内置标签不能满足开发需求时,我们需要自定义标签

     

    内置标签

    <jsp:forward/>  转发

    <jsp:forward page="/09.action2.jsp"> <jsp:param value="jacky" name="name"/> <jsp:param value="123456" name="password"/> </jsp:forward> 相当于 request.getRequesetDipsacher("/路径").foward(request,response);

    <jsp:param/> 参数标签

    <jsp:param value="jacky" name="name"/> <jsp:param value="123456" name="password"/>

    <jsp:include/>   动态包含 ,包含其他页面

    静态包含:先合并在翻译    不能传递参数

    <%@include file="common/header.jsp" %>

    动态包含:先翻译再合并,可以传递参数

    <jsp:include page="/common/header.jsp"> <jsp:param value="lucy" name="name"/> </jsp:include>

    二.自定义标签

    通过一个实例学习自定义标签  获取当前客户端浏览器的ip地址

    jsp实现

    <% //获取当前客户端的ip地址 getRemoteHost() String ip = request.getRemoteHost(); //输出到浏览器 out.write("当前客户端的ip地址是:"+ ip); %>

    自定义标签实现

    1.新建一个Java类继承SimpleTagSupport     自定义标签处理器类

    package cn.itcase.showiptag; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * 自定义 标签showiptag 的处理类 * @author Administrator * *1.定义一个普通的Java类继承 SimpleTagSupport类 * SimpleTagSupport实现SimpleTag接口 * 自定义的Java类间接实现SimpleTag接口 */ public class ShowIpTag extends SimpleTagSupport { private JspContext context; // 接收JspContext(本质是接收 PageContext) /* * 传入JspContext(本质是传入PageContext) */ @Override public void setJspContext(JspContext pc) { /* * JspContext 有一个子类是 PageContext * 此处setJspContext()方法实际传入的就是一个 PageContext */ this.context = pc; // 接收PageContext } /* * 覆盖doTag方式 * */ @Override public void doTag() throws JspException, IOException { //向浏览器输出客户端ip地址 PageContext pagecontext = (PageContext)context;// 将JspContext转换成PageContext HttpServletRequest request = (HttpServletRequest)pagecontext.getRequest();// 强制转型 复杂数据类型 String ip = request.getRemoteHost(); JspWriter out = pagecontext.getOut(); out.write("使用自定义标签输出客户的IP地址:"+ip); } }

    2.在webRoot下的WEB-INF下建立一个 .tld文件    tld文件 绑定Java类与jsp文件

    <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 标签库的版本 --> <tlib-version>1.1</tlib-version> <!-- 标签库前缀 --> <short-name>itcase</short-name> <!-- tld文件的唯一标记 --> <uri>http://cn.itcase.showiptag</uri> <!-- 一个标签的声明 --> <tag> <!-- 标签名称 --> <name>showIp</name> <!-- 标签处理器类的全名 包名+类名--> <tag-class>cn.itcase.showiptag.ShowIpTag</tag-class> <!-- 输出标签体内容格式 --> <body-content>scriptless</body-content> </tag> <tag> <name>demoTag</name> <tag-class>cn.itcase.Tag.DemoTag</tag-class> <body-content>scriptless</body-content> <!-- 属性声明 --> <attribute> <!-- 属性名称 --> <name>num</name> <!-- 是否必填 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>

    3.在jsp文件中使用自定义标签 

          3.1导入自定义标签库

               <%@taglib uri="http://gz.itcase.cn" prefix="itcaste%>

    uri=“http://gz.itcase.cn”    对应 .tld文件的 <!-- tld文件的唯一标记 --> <uri>http://gz.itcase.cn</uri> prefix="itcase"对应 .tld文件的 <!-- 标签库前缀 --> <short-name>itcase</short-name>

    3.2在jsp文件中使用自定义标签

    <itcase:showIp></itcase:showIp>

     

    优化自定义标签处理器类

    package cn.itcase.tag; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; /* * 优化自定义标签 处理器类 */ public class showTag extends SimpleTagSupport { /*覆盖doTag*/ @Override public void doTag() throws JspException, IOException { //向浏览器输出客户端的ip地址 PageContext pagecontext =(PageContext)this.getJspContext(); //通过this.getJspContext()拿数据 HttpServletRequest request = (HttpServletRequest)pagecontext.getRequest(); String ip = request.getRemoteHost(); JspWriter out = pagecontext.getOut(); out.write("使用自定义标签输出客户端ip地址" + ip); } }

    三.自定义标签的的执行过程

          访问:http://localhost:8082/project08/index.jsp 的执行过程

           前提:tomcat已经启动且项目部署成功

    1.访问index.jsp资源

    2.tomcat把index.jsp文件翻译成Java源文件文件,在把Java文件编译成class文件,class文件构造了类对象,调用jspservice()方法

    3.检查jsp文件的taglib指令,是否存在一个名为http://gz.itcase.cn的tld文件。如果没有,则报错   读取itcast.tld文件

    4.读到<itcase:showIp> 到itcase.tld文件中查询是否存在<name>为showIp的<tag>标签

    5.找到对应的<tag>标签,则读到<tag-class>内容

    6.得到 cn.itcase.cn.ShowIpTag 这个自定义标签处理器类

    构造ShowIpTag对象,然后调用ShowIpTag里面的方法

    四.自定义标签处理器类的生命周期

     生命周期的本质:就是什么时候构建对象,什么时候调用方法的问题

    SimpleTag接口 1.void   setJspContext(JspContext pc)     设置PageContext对象(上下文对象)

    设置pageContext对象,传入pageContext(一定调用) 通过getJspCotext()方法得到pageContext对象 实例:PageContext pagecontext =(PageContext)this.getJspContext();

    2.void    setParent(JspTag parent)    设置父标签对象

    设置父标签对象,传入父标签对象,如果没有父标签,则不 调用此方法。通过getParent()方法得到父标签对象

    3.void     setXXX(值)      1

    4.void      setJspBody(JspFragment jspBody)   设置标签内容

    设置标签体内容。标签体内容封装到JspFragment对象中,然后传入JspFragment对象。 通过getJspBody()方法得到标签体内容。如果没有标签体内容,则不会调用此方法

    5.void   doTag()     执行标签时调用的方法。(一定调用)

    五.自定义标签的作用

    通过一个案例展示自定义标签的作用

    自定义标签处理器类

    package cn.itcase.tag; import java.io.IOException; import java.io.StringWriter; import javax.servlet.jsp.JspException; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; /* * 自定义标签处理类 */ public class DemoTag02 extends SimpleTagSupport { // 1.声明属性的成员变量 private Integer num; // 2.关键点:必须提供公开的setter方法,用于给属性赋值 public void setNum(Integer num){ this.num = num; } @Override public void doTag() throws JspException, IOException { System.out.println("执行了标签"); /* * 2.控制标签内容是否输出 * 输出:调用jspFramet.invoke(); * 不输出:不调用jsPFrament.invoke(); */ //2.1得到标签内容 getJspBody() 设置标签内容 setJspBody() JspFragment jspBody = this.getJspBody(); /* * 执行invoke方法:把标签内容输出到指定的Writer对象中 */ //3.向浏览器输出内容,writer为null就是默认往浏览器输出内容 /*JspWriter out = this.getJspContext().getOut(); jspBody.invoke(out);*/ jspBody.invoke(null);/// 等价以上代码 /* * 控制重复输出标签体内容 * 方法:执行多次jspBody.invoke()方法 * for(int i=1;i<=num;i++){ jspBody.invoke(null); } */ /* * 4.改变标签体内容 */ //4.1创建StringWriter临时容器 StringWriter sw = new StringWriter(); //4.2把标签体拷贝到临时容器 jspBody.invoke(sw); //4.3从临时容器中得到标签体内容 String content = sw.toString(); //4.4改变标签体内容 content = content.toLowerCase(); System.out.println(content); //4.5把改变的内容输出到浏览器 /* * jspBody.invoke(null); 不能使用此方式输出,因为jspBody没用改变过 */ this.getJspContext().getOut().write(content); /* * 控制标签余下内容是否输出 * 输出:不进行任何操作 * 不输出:抛出SkipPageException异常 * */ throw new SkipPageException(); } }

    配置.tld文件

    <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 标签库的版本 --> <tlib-version>1.1</tlib-version> <!-- 标签库前缀 --> <short-name>itcase</short-name> <!-- tld文件的唯一标记 --> <uri>http://cn.itcase.tag</uri> <!-- 一个标签的声明 --> <!-- 标签名称 --> <name>demoTag</name> <!-- 标签处理器类的全名 包名+类名--> <tag-class>cn.itcase.tag.DemoTag02</tag-class> <!-- 输出标签体内容格式 --> <body-content>scriptless</body-content> <!-- 属性声明 --> <attribute> <!-- 属性名称 --> <name>num</name> <!-- 是否必填 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag>

    jsp文件中使用自定义标签

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@taglib uri="http://cn.itcase.tag" prefix="itcase"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'Demo01.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <itcase:demoTag num="2">xxx${10+1}</itcase:demoTag> </body> </html>

    总结:

    控制标签内容是否输出控制标签余下内容是否输出控制重复输出标签体内容改变标签体内容带属性的标签

     

    六.自定义标签案例

    自定义标签处理器类

    package cn.itcase.tag; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * 自定义登录页面标签处理器类 * * @author Administrator * */ public class LoginTag extends SimpleTagSupport { private String username; private String password; public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } @Override public void doTag() throws JspException, IOException { // 拿到response HttpServletResponse response = (HttpServletResponse) ((PageContext) this .getJspContext()).getResponse(); /* * PageContext context = (PageContext)this.getJspContext(); * HttpServletResponse response * =(HttpServletResponse)context.getResponse();相当于以上代码 */ // 设置输出内容和编码格式 response.setContentType("text/html;charset=utf-8"); String html = ""; html += "<center><h3>用户登录界面</h3></center>"; html += "<table border='1' align='center' width='400px'"; html += "<tr>"; html += "<th>用户名:</th>"; html += "<td><input type='text' name='" + username + "'/></td>"; html += "</tr>"; html += "<tr>"; html += "<th>密码:</th>"; html += "<td><input type='password' name='" + password + "'/></td>"; html += "</tr>"; html += " <tr>"; html += " <td colspan='2' align='center'><input type='submit' value='登陆'/> <input type='reset' value='重置'/></td>"; html += " </tr>"; html += "</table>"; JspWriter out = this.getJspContext().getOut(); out.write(html); } }

    .tld文件的配置

    <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 标签库的版本 --> <tlib-version>1.1</tlib-version> <!-- 标签库前缀 --> <short-name>itcase</short-name> <!-- tld文件的唯一标记 --> <uri>http://cn.itcase.tag</uri> <!-- 一个标签的声明 --> <tag> <name>login</name> <tag-class>cn.itcase.tag.LoginTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>username</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>password</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>

    在jsp页面中使用jsp标签

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <%@taglib uri="http://cn.itcase.tag" prefix="itcase" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="" method="POST"> <itcase:login password="pwd" username="user"></itcase:login> </form> </body> </html>

    七.javaBean

    中文名:咖啡豆   javaBean是一种开发规范,也可说是一种技术JavaBean的本质是一个特殊的类

     

    满足以下规范的类,称为JavaBean

    必须提供无参的构造方法类中的属性必须都私有化(private)该类提供公开的getter和setter方法

    JavaBean的作用:用于封装数据,保存数据。JavaBean只能通过getter和setter方法访问

     

    JavaBean的使用场合

    项目中用到实体对象(entity)EL表达式访问对象属性。${student.name}  调用getName()方法jsp标签中的属性赋值。 setNum(Integer num)jsp页面中使用javabean。

    以上应用场合用都符合JavaBean的规范

    package cn.itcase.entity; public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { super(); } }

    常见的符合JavaBean规范的方法

    getName() setName(String name)setFlag(boolean flag)isFlag()

    注意:boolean类型的get方法名称叫 isXXX()方法

    八.web开发模式的简介

    mvc开发模式

    Model - JavaBean实现。用于封装业务数据View - Jsp实现。用于显示数据Controller-  servlet实现。用于控制model和view

    三层架构

    dao层: 和数据访问相关的操作service层: 和业务逻辑相关的操作web层: 和用户直接交互相关的操作(传接参数,跳转页面)

        

    最新回复(0)