zoukankan      html  css  js  c++  java
  • 如果你想开发一个应用(1-3)

    前一张的结尾,我想你已经发现了现在这个应用就是个骗子,根本就不是一个todos的应用,连个列表都没有,这一章就着重解决这个问题,在解决之前,先要明白几个概念:

    Jsp的四种作用域

    作用域顾名思义,就是一个变量能够起作用的区域,具体到jsp中,扣除自定义变量之外,共存在四种作用域,分别为:

    1. pageContext 即页面级,只存在本页面中,刷新后就消失。
    2. request 请求级,存在一样请求/响应周期
    3. session 会话级,存在一个用户完整的会话周期,可以暂时简单的理解为从用户访问站点开始,到关闭浏览器为止。
    4. application 应用级,即从应用启动到应用停止,比如tomcat重启,服务器重启都在这个范围。

    page和request的区别在于,有些请求是跨页面的,比如通过forward的转发的页面,关于forward转发的内容,后面的章节会详细介绍。

    看了四种作用域的介绍,因为列表是随时打开随时看的,那么很容易就可以想到,将所有的todo项存在于application中是最适合的(此时不考虑持久化技术),那么问题来了,jsp的application内置对象该如何使用呢?

    这点,其实这四个内置变量的使用方式都是一致的,通过getAttribute(name:String)来获取在职,通过setAttribute(name:String,val:Object)来设置值。

    存储todos

    继续上一章的程序,暂时还是采取最简单的方法,仅仅是一个字符串的列表,将它通过一个List存入application中,代码如下:

    <%
        request.setCharacterEncoding("utf-8");
        List<String> todos=(List<String>) application.getAttribute("todos");
        if(todos==null){
            todos=new ArrayList<>();
            application.setAttribute("todos",todos);
        }
        if(request.getParameter("todo")!=null){
            todos.add(request.getParameter("todo"));
        }
    %>
    

    这里首先从application中获取一个List,然后判断他是否存在,如果不存在则创建一个新的ArrayList,并将其放入application中,由于list为引用类型,所以即使没用重新setAttribute,在list没有重新初始化的情况下,对list的操作也会如实的反映到application中.

    这里有一个java很重要的基础知识点,即值类型与引用类型,对于这点一定要非常清晰,否则会在编码中产生非常可怕的影响。

    显示todos

    现在todo项已经存在了一个list中,下面要做的就是输出它(整个代码块):

    <%
        request.setCharacterEncoding("utf-8");
        List<String> todos=(List<String>) application.getAttribute("todos");
        if(todos==null){
            todos=new ArrayList<>();
            application.setAttribute("todos",todos);
        }
        if(request.getParameter("todo")!=null){
            todos.add(request.getParameter("todo"));
        }
    
        out.print("<ul>");
        for (String item :todos) {
            out.print("<li>"+item+"</li>");
        }
        out.print("</ul>");
    %>
    

    查看一下效果:

    image

    不考虑美观的话,功能算是实现了,但是,这样好么?
    当然不好,尤其是输出html标签这一点,想一下,如果把ul改成table怎么办?并且标签的开闭,很容易出错,在想想如果在todo的项目中增加一些超链接之类的,那么对于这种在代码中嵌入html的方法,几乎是一场噩梦,所以一个方法是把在代码中嵌入html改为在html中嵌入代码,修改后的代码如下:

    <%
        request.setCharacterEncoding("utf-8");
        List<String> todos=(List<String>) application.getAttribute("todos");
        if(todos==null){
            todos=new ArrayList<>();
            application.setAttribute("todos",todos);
        }
        if(request.getParameter("todo")!=null){
            todos.add(request.getParameter("todo"));
        }
    %>
        <ul>
        <%
        for (String item :todos) {
            %>
           <li><%=item%></li>
    <%
        }
        %>
        </ul>
    

    这个:(貌似也没清晰多少,但是这是一个简单的例子,如果html稍微复杂点就能看出优势来,退一步说,即使只考虑使用html的高亮功能,都值得用这种代码中嵌入html的方法,但这种方法的缺点也是相当明显的,那就是他即破坏了html的结构,又破坏了代码的结构,那么有没有其他一种更加优秀的方法呢,这时候就轮到jstl出厂了.

    jstl

    jstl实际上是一套封装好的taglib组件,使用jstl首先需要加载jstl的依赖项,我们可以再maven公共库中搜索jstl,将搜索结果假如pom.xml文件的dependencies节点内中:

      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
    

    加载后点击Import Changes 带进度条走完即表示加载完成。

    然后,我使用默认模板创建的应用为2.3版本,其实现在默认即为3.*版本,即删除<!DOCTYPE声明节点即可,若需要强制声明版本,可修改web-app属性为:

    <web-app  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    

    我的web.xml:

    <web-app>
      <display-name>jTodos</display-name>
    </web-app>
    

    呃 好简单

    然后在页面声明taglib前缀:
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    然后修改输出代码为:

    <%
        request.setCharacterEncoding("utf-8");
        List<String> todos=(List<String>) application.getAttribute("todos");
        if(todos==null){
            todos=new ArrayList<>();
            application.setAttribute("todos",todos);
        }
        if(request.getParameter("todo")!=null){
            todos.add(request.getParameter("todo"));
        }
    %>
        <ul>
            <c:forEach var="item" items="${todos}">
             <li>${item}</li>
            </c:forEach>
        </ul>
    

    是不是清爽多了?运行看一下页面,和之前的一样,现在看页面的逻辑基本比较清晰了,代码和html互不干扰,同时,我们还可以为这个list假设一个编号:

     <ul>
        <c:forEach var="item" varStatus="status" items="${todos}">
         <li>${status.index+1}.${item}</li>
        </c:forEach>
    </ul>
    

    Ok很完美,这块暂时先告一段落,当然,jstl还有好多用法,以后再慢慢探索。

    感谢您的阅读

    image

  • 相关阅读:
    无限级分类表设计
    多表连接
    连接(上接子查询那一篇随笔)
    数据库中常用指令
    子查询
    mysql查询表达式解析
    mysql单表删除记录DELETE
    mysql 单表更新记录UPDATE
    七言
    时分秒计算案例
  • 原文地址:https://www.cnblogs.com/jiangchao226/p/7799640.html
Copyright © 2011-2022 走看看