博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5、JavaWeb学习之基础篇—标签(自定义&JSTL)
阅读量:4293 次
发布时间:2019-05-27

本文共 6242 字,大约阅读时间需要 20 分钟。

文章目录

一、相对路径和绝对路径:

  1. 为什么要解决相对路径的问题: 在有一个 Servlet 转发页面的情况下, 会导致相对路径的混乱.
    a.jsp: <a href=“ToBServlet”>To B Page2</a>
    ToBServlet: request.getRequestDispatcher("/dir/b.jsp").forward(request, response);
    注意, 此时点击 To B Page2 超链接后的浏览器的地址栏的值: http://localhost:8989/day_36/ToBServlet, 实际显示的是dir 路径下的 b.jsp
    而 b.jsp 页面有一个超链接:<a href=“c.jsp”>TO C Page</a>. 默认情况下, c.jsp 应该和 b.jsp 在同一路径下. 此时点击超链接,将在浏览器地址栏显示: http://localhost:8989/day_36/c.jsp. 但在根目录下并没有 c.jsp, 所以会出现路径混乱的问题.
  2. 使用绝对路径会解决以上的问题:
    绝对路径: 相对于当前 WEB 站点根目录的路径. http://localhost:8989/day_36/c.jsp: http://localhost:8989/ 是 WEB 站点的根目录, /day_36 是 contextPath,/c.jsp 是相对于当前 WEB 应用的一个文件路径. 我们需要在当前 WEB 应用的任何的路径下都添加上 contextPath, 即可.
    比如:
    <a href=“ToBServlet”>To B Page2</a> 需改为: <a href="<%= request.getContextPath() %>/ToBServlet">To B Page2</a>
    response.sendRedirect(“a.jsp”); 需改为: response.sendRedirect(request.getContextPath() + “/a.jsp”);
    <form action=“AddServlet”></form> 需改为:<form action="<%= request.getContextPath() %>/AddServlet"></form>
  3. 在 JavaWEB 应用中 / 代表的是: 有时代表当前 WEB 应用的根目录, 有时代表的是站点的根目录.
    / 代表的是当前 WEB 应用的根路径: 若 / 所在的命令或方法需被 WEB 服务器解析, 而不是直接打给浏览器, 则 / 代表 WEB 应用的根路径. 此时编写
    绝对路径就不需要在添加 contextPath 了.
    在 web.xml 文件中做 Serlvet 映射路径时,
    在请求转发: request.getRequestDispatcher("/dir/b.jsp").forward(request, response);
    / 代表的是站点的根目录: 若 / 直接交由浏览器解析, / 代表的就是站点的根路径, 此时必须加上 contextPath
    <form action="/AddServlet"></form>
    response.sendRedirect("/a.jsp");
  4. 如何获取 contextPath:
    ServletContext: getContextPath()
    HttpServletRequest: getContextPath()

二、自定义标签

  1. HelloWorld

    ①. 创建一个标签处理器类: 实现 SimpleTag 接口. ①. 创建一个标签处理器类: 实现 SimpleTag 接口.
    ②. 在 WEB-INF 文件夹下新建一个 .tld(标签库描述文件) 为扩展名的 xml 文件. 并拷入固定的部分: 并对 description, display-name, tlib-version, short-name, uri 做出修改

    JSTL 1.1 core library
    JSTL core
    1.1
    c
    http://java.sun.com/jsp/jstl/core

    ③. 在 tld 文件中描述自定义的标签:

    hello
    com.atguigu.javaweb.tag.HelloSimpleTag
    empty

    ④. 在 JSP 页面上使用自定义标签:

    使用 taglib 指令导入标签库描述文件: <%@taglib uri=“http://www.atguigu.com/mytag/core” prefix=“atguigu” %>

    使用自定义的标签: <atguigu:hello/>

  2. setJspContext: 一定会被 JSP 引擎所调用, 先于 doTag, 把代表 JSP 引擎的 pageContext 传给标签处理器类.

    private PageContext pageContext;	@Overridepublic void setJspContext(JspContext arg0) {
    System.out.println(arg0 instanceof PageContext); this.pageContext = (PageContext) arg0;}
  3. 带属性的自定义标签:

    ①. 先在标签处理器类中定义 setter 方法. 建议把所有的属性类型都设置为 String 类型.

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

    ②. 在 tld 描述文件中来描述属性:

    value
    true
    true

    ③. 在页面中使用属性, 属性名同 tld 文件中定义的名字.

    <atguigu:hello value="${param.name }" count=“10”/>

  4. 通常情况下开发简单标签直接继承 SimpleTagSupport 就可以了. 可以直接调用其对应的 getter 方法得到对应的 API

    public class SimpleTagSupport implements SimpleTag{
    public void doTag() throws JspException, IOException{
    } private JspTag parentTag; public void setParent( JspTag parent ) {
    this.parentTag = parent; } public JspTag getParent() {
    return this.parentTag; } private JspContext jspContext; public void setJspContext( JspContext pc ) {
    this.jspContext = pc; } protected JspContext getJspContext() {
    return this.jspContext; } private JspFragment jspBody; public void setJspBody( JspFragment jspBody ) {
    this.jspBody = jspBody; } protected JspFragment getJspBody() {
    return this.jspBody; } }

三、带标签体的自定义标签:

  1. 若一个标签有标签体:

    <atguigu:testJspFragment>abcdefg</atguigu:testJspFragment>
    在自定义标签的标签处理器中使用 JspFragment 对象封装标签体信息.

  2. 若配置了标签含有标签体, 则 JSP 引擎会调用 setJspBody() 方法把 JspFragment 传递给标签处理器类,在 SimpleTagSupport 中还定义了一个 getJspBody() 方法, 用于返回 JspFragment 对象.

  3. JspFragment 的 invoke(Writer) 方法: 把标签体内容从 Writer 中输出, 若为 null,

    则等同于 invoke(getJspContext().getOut()), 即直接把标签体内容输出到页面上
    有时, 可以 借助于 StringWriter, 可以在标签处理器类中先得到标签体的内容:
    //1. 利用 StringWriter 得到标签体的内容.
    StringWriter sw = new StringWriter();
    bodyContent.invoke(sw);
    //2. 把标签体的内容都变为大写
    String content = sw.toString().toUpperCase();

  4. 在 tld 文件中, 使用 body-content 节点来描述标签体的类型:

    <body-content>: 指定标签体的类型, 大部分情况下, 取值为 scriptless。可能取值有 3 种:
    empty: 没有标签体
    scriptless: 标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
    tagdependent: 表示标签体交由标签本身去解析处理。
    若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器
    <body-content>tagdependent</body-content>

  5. 定义一个自定义标签: <atguigu:printUpper time=“10”>abcdefg</atguigu> 把标签体内容转换为大写, 并输出 time 次到浏览器上.

  6. 实现 forEach 标签:

    两个属性: items(集合类型, Collection), var(String 类型)

    doTag:

    * 遍历 items 对应的集合
    * 把正在遍历的对象放入到 pageContext 中, 键: var, 值: 正在遍历的对象.
    * 把标签体的内容直接输出到页面上.

    ${pageScope.cust2.id } -- ${cust2.name }
    abcde

四、开发有父标签的标签:

  1. 父标签无法获取子标签的引用, 父标签仅把子标签作为标签体来使用.
  2. 子标签可以通过 getParent() 方法来获取父标签的引用(需继承 SimpleTagSupport 或自实现 SimpleTag 接口的该方法):
    若子标签的确有父标签, JSP 引擎会把代表父标签的引用通过 setParent(JspTag parent) 赋给标签处理器
  3. 注意: 父标签的类型是 JspTag 类型. 该接口是一个空接口, 但是来统一 SimpleTag 和 Tag 的. 实际使用需要进行类型的强制转换.
  4. 在 tld 配置文件中, 无需为父标签有额外的配置. 但, 子标签是是以标签体的形式存在的, 所以父标签的<body-content></body-content>需设置为 scriptless
  5. 实现
    大学毕业
    高中毕业
    高中以下...

    开发 3 个标签: choose, when, otherwise

    其中 when 标签有一个 boolean 类型的属性: test
    choose 是 when 和 otherwise 的父标签
    when 在 otherwise 之前使用
    在父标签 choose 中定义一个 “全局” 的 boolean 类型的 flag: 用于判断子标签在满足条件的情况下是否执行.
    ① 若 when 的 test 为 true, 且 when 的父标签的 flag 也为 true, 则执行 when 的标签体(正常输出标签体的内容), 同时把 flag 设置为 false
    ② 若 when 的 test 为 true, 且 when 的父标签的 flag 为 false, 则不执行标签体.
    ③ 若 flag 为 true, otherwise 执行标签体.

五、JSTL:

  1. c:out 主要用于对特殊字符进行转换. 真正进行输出时, 建议使用 c:out, 而不是使用 EL
  2. c:set: 可以为域赋属性值。 而对域对象中的 JavaBean 的属性赋值用的并不多
  3. c:remove: 移除指定域对象的指定属性值(较少使用, 即便移除也是在 Servlet 中完成)
  4. c:if: 在页面上对现实的内容进行过滤, 把结果存储到域对象的属性中. 但不灵活, 会被其他的自定义标签所取代
  5. c:choose, c:when, c:otherwise: 作用同上, 但麻烦, 不灵活.
  6. c:forEach: 对集合进行遍历的. 常用
  7. c:forTokens: 处理字符串, 类似于 String 累的 split() 方法(知道即可)
  8. c:import: 导入页面到当前页面的. (了解)
  9. c:redirect: 当前页面进行重定向的. (使用较少)
  10. c:url: 产生一个 URL 的, 可以进行 URL 重写, 变量值编码, 较为常用

转载地址:http://phfws.baihongyu.com/

你可能感兴趣的文章
CTA策略如何过滤部分震荡行情?
查看>>
量化策略回测DualThrust
查看>>
量化策略回测BoolC
查看>>
量化策略回测DCCV2
查看>>
mongodb查询优化
查看>>
五步git操作搞定Github中fork的项目与原作者同步
查看>>
git 删除远程分支
查看>>
删远端分支报错remote refs do not exist或git: refusing to delete the current branch解决方法
查看>>
python multiprocessing遇到Can’t pickle instancemethod问题
查看>>
APP真机测试及发布
查看>>
iOS学习之 plist文件的读写
查看>>
通知机制 (Notifications)
查看>>
10 Things You Need To Know About Cocoa Auto Layout
查看>>
C指针声明解读之左右法则
查看>>
一个异步网络请求的坑:关于NSURLConnection和NSRunLoopCommonModes
查看>>
iOS 如何放大按钮点击热区
查看>>
ios设备唯一标识获取策略
查看>>
获取推送通知的DeviceToken
查看>>
Could not find a storyboard named 'Main' in bundle NSBundle
查看>>
CocoaPods安装和使用教程
查看>>