jsp和EL表达式以及JSTL表达式

1、什么是JSP

​ Java server page(java服务器页面). JSP本质就是Servlet

​ 它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。

​ JSP=html(js,css)+java+jsp特有的内容

2、JSP产生的原因

需求: 我们要向页面动态输出一个表格. 发现特别的繁琐

servlet在展示页面的时候,相当的繁琐。sun公司为了解决这个问题,参照asp开发了一套动态网页技术jsp。

也就是说jsp就是为了解决servlet展示前端信息太过于麻烦的问题的。

3、执行原理

JSP会翻译(通过默认的JspServlet,JSP引擎)成Servlet(.java),Servlet编译成class文件

JSP执行流程

​ 1、第一次访问的xxx.jsp时候,服务器收到请求,JspServlet会去查找对应的jsp文件

​ 2、找到之后,服务器会将这个jsp文件转换成java文件(Servlet)

​ 3、服务器编译java文件,生成class文件

​ 4、服务器运行class文件,生成动态的内容

​ 5、服务器收到内容之后,返回给浏览器

jsp本质上就是servlet

对应的原理图如下所示:

这里可以在idea中看一下

首先先写一个jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/DotFogetServlet" method="post">
    用户名:<input type="text" name="username" value="${cookie.username.value}"/><br/>
    密  码:<input type="password" name="password"/><br/>
    <%--<input type="checkbox" name="remember" onclick="" /> 记住用户名<br/>--%>
    <input type="checkbox" value="uncheck" name="check" onclick="this.value=((this.value=='uncheck')?'checked':'uncheck')"/> 记住用户名<br/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

启动项目之后,会在控制台显示出来:

Using CATALINA_BASE:   "C:\Users\liguang\AppData\Local\JetBrains\IntelliJIdea2020.3\tomcat\90d7a63c-992b-42e2-a921-c2e974066439"

那么jsp生成的java文件会在这个目录下面显示

如果没有访问,那么这个目录下是找不到对应的文件的,只有在访问的时候,才会生成。这也就对应了上面的原理图

那么第一次访问之后,会产生如下文件:

package org.apache.jsp;

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

public final class login_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

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

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.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("<html>\r\n");
      out.write("<head>\r\n");
      out.write("    <title>Title</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\r\n");
      out.write("<form action=\"");
      out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
      out.write("/DotFogetServlet\" method=\"post\">\r\n");
      out.write("    用户名:<input type=\"text\" name=\"username\" value=\"");
      out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${cookie.username.value}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
      out.write("\"/><br/>\r\n");
      out.write("    密  码:<input type=\"password\" name=\"password\"/><br/>\r\n");
      out.write("    ");
      out.write("\r\n");
      out.write("    <input type=\"checkbox\" value=\"uncheck\" name=\"check\" onclick=\"this.value=((this.value=='uncheck')?'checked':'uncheck')\"/> 记住用户名<br/>\r\n");
      out.write("    <input type=\"submit\" value=\"登录\"/>\r\n");
      out.write("</form>\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

既然说jsp是servlet,那么jsp的类也一定会继承servlet类,并且一定会有service方法!我们发现,jsp继承了org.apache.jasper.runtime.HttpJspBase,查阅这个类的源码可以发现这样一行代码:

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage

由此我们得知,jsp通过继承httpServlet,然后继承了servlet类。

所以说jsp本质上就是servlet

我们可以看到上面的jsp在进行输出的时候,是利用流对象在进行写出,这跟利用servlet写出数据是一样的操作。

4、jsp语法

既然说jsp是代替servlet来对数据进行输出的,那么看看jsp中的语法

我们可以通过JSP脚本在JSP页面上编写Java代码. 一共有三种方式:

类型 翻译成Servlet对应的部分 注意
<%...%>:Java程序片段 翻译成Service()方法里面的内容, 局部的
<%=...%>:输出表达式 翻译成Service()方法里面的内容,相当于调用out.print() 输出表达式不能以;结尾
<%!...%>:声明成员变量 翻译成Servlet类里面的内容

总结起来就是:

  • <%....%> 翻译成了service()方法里面的局部内容
  • <%=....%> 输出, 翻译成了service()方法里面的out.print()
  • <%!...%> 翻译成了servlet类里面的全局内容

分别写三个例子来进行说明:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>demo1</title>
</head>
<body>
<%--局部变量--%>
<% int a = 3; %>

<%--打印java的变量值到网页上--%>
<%=a %>

<%--全局变量--%>
<%! int b = 33; %>

<%--如果写大段的代码怎么做--%>

<%
    for(int i = 0 ; i < 10 ; i++){
%>
<%=i%><br/>
<h2><font color="red">aaaaaaaaaaaaaa</font></h2><br/>
<%
    }
%>
</body>
</html>

那么访问一下,看一下对应的jsp页面对应的java文件

public final class jspdemo1_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

 int b = 33; 
  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

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

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.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("<html>\r\n");
      out.write("<head>\r\n");
      out.write("    <title>demo1</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write('\r');
      out.write('\n');
 int a = 3; 
      out.write("\r\n");
      out.write("\r\n");
      out.write('\r');
      out.write('\n');
      out.print(a );
      out.write("\r\n");
      out.write("\r\n");
      out.write('\r');
      out.write('\n');
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");

    for (int i = 0; i < 10; i++) {

      out.write('\r');
      out.write('\n');
      out.print(i);
      out.write("<br/>\r\n");
      out.write("<h2><font color=\"red\">aaaaaaaaaaaaaa</font></h2><br/>\r\n");

    }

      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

可以看到

<% int a = 3; %>

定义的位置是在方法位置内

<%! int b = 33; %>

这个是属于servlet中的成员变量类

而对应的java片段,在servlet中显示的是:

    for (int i = 0; i < 10; i++) {
      out.write('\r');
      out.write('\n');
      out.print(i);
      out.write("<br/>\r\n");
      out.write("<h2><font color=\"red\">aaaaaaaaaaaaaa</font></h2><br/>\r\n");
    }

再写一个jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>demo1</title>
</head>
<body>
    <%! int count = 250;%>
    <%= "count对应的值是:"+count %>
    <br>
    <br>
    <% String hello = "hello,world"; %>
    <%= "hello对应的值是:"+hello %>
</body>
</html>

查看页面输出:

count对应的值是:250

hello对应的值是:hello,world

写一个循环看看

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>demo1</title>
</head>
<body>
    <%
        List<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        for (Integer integer : integers) {
    %>
        <%="循环遍历对应的值是:"+integer%>
        <br/>
    <%
        }
    %>
</body>
</html>

查看页面对应的输出:

循环遍历对应的值是:1
循环遍历对应的值是:2
循环遍历对应的值是:3

4、EL表达式

4.1、什么是EL表达式

​ Expression Language:表达式语言, jsp2.0之后内置在jsp里面

​ 目的:为了使JSP写起来更加简单, 取值(取的域对象里面存的值)更加简单。(代替脚本 <% %>)

4.3、EL用途

语法:

${el表达式}

​ 1.获取数据. 获取的是域(request,session,ServletContext)对象中存储的数据

​ 2.EL执行运算

所以下面将会一个一个的来对其做执行操作

4.4、使用EL表达式获取得到数据

4.4.1、获取得到数据的几种形式

  • 获取简单数据类型数据(基本类型,字符串)
  • 获取数组
  • 获取list
  • 获取Map
  • 获取bean
1、获取简单数据类型数据

​ 语法:

${requestScope|sessionScope|applicationScope.属性名}; 

​ 快捷写法:

${属性名}

属性名就是存在域对象里面的key

来一个对应的例子来进行说明:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>获取得到简单数据</title>
</head>
<body>
<body>
<%
    //request存数据
    request.setAttribute("rkey","rrr");
    //session存数据
    session.setAttribute("skey","sss");
    //ServletContext存数据,jsp里面叫application
    application.setAttribute("akey","aaa");

    request.setAttribute("key","request");
    session.setAttribute("key","session");
%>

取出request域里面存的数据:<br/>
老方式:<%=request.getAttribute("rkey") %>  <br/>
El方式:${requestScope.rkey}         <br/>
简单方式El方式:${rkey}         <br/>
<hr/>

取出session域里面存的数据:<br/>
老方式:<%=session.getAttribute("skey") %>  <br/>
El方式:${sessionScope.skey}        <br/>
简单El方式:${skey}        <br/>
<hr/>

取出ServletContext域里面存的数据:<br/>
老方式:<%=application.getAttribute("akey") %>  <br/>
El方式:${applicationScope.akey}        <br/>
简单El方式:${akey}        <br/>
<hr/>
<hr/>
<%--直接写域里面的key原理: 从最小的往最大的找,, request-->session--->application--%>
简单的方式(直接写域里面的key):<br/>
${rkey}<br/>
${skey}<br/>
${akey}<br/>
${key}

</body>
</body>
</html>

打开浏览器去访问,查看浏览器结果:

取出request域里面存的数据:
老方式:rrr
El方式:rrr
简单方式El方式:rrr
取出session域里面存的数据:
老方式:sss
El方式:sss
简单El方式:sss
取出ServletContext域里面存的数据:
老方式:aaa
El方式:aaa
简单El方式:aaa
简单的方式(直接写域里面的key):
rrr
sss
aaa
request

最后一个获取的是request,同时验证了上面中的,如果使用EL表达式简单的写法,那么会首先从

request----->session------>servletcontext域对象中来获取得到数据。

2、获取数组

语法: ${key[下标]} key就是域对象里面存的key

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>数组操作jsp</title>
</head>
<body>
    <%
        Integer[] integersArray = new Integer[]{1,2,3,4,5};
        request.setAttribute("array",integersArray);
    %>
    ${array[2]}
</body>
</html>
3、获取得到list

语法:${list属性名[index]}或者${list属性名.get(index)};list属性名就是存入域对象里面的key

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>数组操作jsp</title>
</head>
<body>
    <%
        List<String> stringList = new ArrayList<>();
        stringList.add("hello");
        stringList.add("world");
        stringList.add("helloworld");
        request.setAttribute("list",stringList);
    %>
    ${list[2]}
</body>
</html>

浏览器输出:

helloworld
4、获取得到map

语法:${map属性名.键}或者${map属性名.get("键")},map属性名就是存入域对象里面的key

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>map操作jsp</title>
</head>
<body>
    <%
        Map<String,Integer> map = new HashMap<>();
        map.put("hello",1);
        map.put("world",2);
        map.put("helloworld",3);
        request.setAttribute("map",map);
    %>
    ${map.hello}
</body>
</html>
5、获取得到Bean

语法:${key.javabean属性}

依赖getxxx()方法; eg: getPassword()---去掉get-->Password()----首字母小写--->password

<%@ page import="com.guang.bean.User" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>bean操作jsp</title>
</head>
<body>
    <%
        User user = new User();
        user.setAge(22);
        user.setId(33L);
        user.setName("lig");
        request.setAttribute("user",user);
    %>
    ${user.age}<br>
    ${user.id}<br>
    ${user.name}<br>
</body>
</html>

浏览器输出:

22
33
lig

4.4.2、EL运算

上面介绍了EL表达式的数据的存取,下面介绍一个EL的运算

4.1算数运算

​ +,-,*,/

  • +不能拼接字符串.

4.2逻辑运算

​ < >= <= != ==

4.3关系运算

​ && || !

4.4非空判断【重点】

​ empty,1. 判断一个对象是否为null, 2. 判断集合长度是否为0, 3. 判断一个字符串是否为 ""

​ not empty

​ 语法: ${empyt 属性名};属性名 就是域对象里面的key值

例子:

<body>
    <%
        //request.setAttribute("a",10);
        User user = null;
        request.setAttribute("u",user);

        User user1 = new User();
        request.setAttribute("u1",user1);

        List list = new ArrayList();
        request.setAttribute("l",list);

        List list02 = null;
        request.setAttribute("l2",list02);

    %>

    <%--a就是从域里面获得的a
        ${a+19}
        ${a>20}
    --%>
    <%--1.判断对象(user是)否为null--%>
    ${empty u} <%--true--%>
    ${empty u1} <%--false--%>

    ${not empty u}<%--false--%>
    <hr/>
    <%--2.判断一个集合的长度是否为0--%>
    ${empty l} <%--true--%>
    ${empty l2} <%--true--%>


</body>

5、JSTL表达式

5.1、上面是JSTL表达式

JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。这个JSTL标签库没有集成到JSP的, 要使用的话, 需要导jar包.

5.2、JSTL表达式作用

为了简化在jsp页面上操作数据; eg: 遍历数据 判断数据等

能够使用el表达式域里面的数据(先要把数据存到域对象里面)

1、导入核心jar包

jstl.jar
standard.jar    

2、在JSP页面上导入核心标签库<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

if标签

语法:

<c:if test="el表达式${..}" [var="给之前的表达式的结果起个名字"] [scope="将结果保存在那个域中 默认page"]>
</c:if>

对应的例子:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>使用jstl表达式</title>
</head>
<body>
    <%request.setAttribute("hello","world");%>
    <c:if test="${hello.equals('world')}" var="flag" scope="request">
        在request域对象中存入的是数据是world
    </c:if>
    <c:if test="${hello.equals('hello')}" var="hello" scope="request">
        在request域对象中存入的数据是hello
    </c:if>
    <br>
    ${flag}
    <br>
    ${hello}
</body>
</html>

浏览器端输出:

在request域对象中存入的是数据是world
true
false

特点

  • 如果test里面的是true, if标签体里面的就会执行
  • 如果test里面的是false, if标签体里面的就不会执行
  • 没有else的

利用上面的例子来使用java代码来进行表示:

if(i>1){
    user.setFlag = true;
}
System.out.println(user.getFlag);

choose标签

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>choose</title>
</head>
<body>
<%
    request.setAttribute("a", "前端");
%>

<c:choose>
    <c:when test="${a == 'java' }">
        java
    </c:when>

    <c:when test="${a == 'Android' }">
        Android
    </c:when>


    <c:when test="${a == 'IOS' }">
        IOS
    </c:when>

    <c:otherwise>
        其它
    </c:otherwise>
</c:choose>
</body>
</html>

浏览器输出:

其他

foreach标签

foreach标签是最重要的标签,使用这种来进行遍历。

其中:

c:forEach中的varStatus属性。 指向一个字符串,该字符串引用一个对象。  map.put("vs",一个对象);

这个对象记录着当前遍历的元素的一些信息:

     index:返回索引。从0开始

     count:返回计数。从1开始

     last:是否是最后一个元素

     first:是否是第一个元素

上案例来进行演示:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--只要使用了jstl标签,都必须导入这个--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>jstl的 foreach标签</title>
</head>
<body>
<%--

for(int i = 0 ; i < 10 ; i++){

}--%>

<%--如果设置了var属性,那么把遍历得到的结果,赋值给这个变量 ,然后把这个变量
存储到一个page作用域去

    begin: 从什么开始
    end: 到什么结束
    var :遍历出来的每一次结果,都赋值给这个变量 i  还要存储这个变量到page作用域
    step : 步长,每次遍历的步长。如果现在打印1, 那么下一次就打印3.

--%>
<c:forEach begin="1"  end="10" var="i" step="2">
    ${i}<br/>
</c:forEach>
</body>
</html>

第二个案例:

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--只要使用了jstl标签,都必须导入这个--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>jstl的 foreach标签</title>
</head>
<body>

<%

    List<String> list = new ArrayList();

    list.add("aa");
    list.add("bb");
    list.add("cc");
    list.add("dd");
    list.add("ee");

    pageContext.setAttribute("list", list);
%>


${list[0]}<br/>

<%--

    items : 遍历的集合

    现在知道了,遍历的集合是list集合,但是我们想输出每一次遍历的结果,这时候,需要搭配一个属性??
--%>
<c:forEach items="${list}" var="name">
    ${name} <br/>
</c:forEach>

</body>
</html>

第三个案例:

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--只要使用了jstl标签,都必须导入这个--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>jstl的 foreach标签</title>
</head>
<body>

<%!
    /*这段代码会放在jsp翻译的那个java文件的全局位置, 这就相当于有了内部类*/
    public class User{
        public String name;
        public int age;

        public User() {
        }

        public User(String name, int age) {
            this.name = name;
            this.age = 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;
        }
    }
%>

<%

    List<User> list = new ArrayList();

    list.add(new User("张三1" ,8));
    list.add(new User("张三2" ,18));
    list.add(new User("张三3" ,28));
    list.add(new User("张三4" ,38));

    pageContext.setAttribute("list", list);
%>


<c:forEach items="${list}" var="u">
    ${u.name} , ${u.age} <br/>
</c:forEach>


</body>
</html>

6、项目

下面介绍一下开发思想,以转账案例来进行说明:

首先介绍一下在servlet的开发流程

上面的是原生servlet的开发模式,但是这种模式存在着很大的问题。有着很大的耦合性,而且无法造成代码的复用。

所以提出来的是对应的三层架构模式

软件中分层:按照不同功能分为不同层,通常分为三层:表现层(web层),业务层,持久(数据库)层。

分层的意义:

  1. 解耦:降低层与层之间的耦合性。
  2. 可维护性:提高软件的可维护性,对现有的功能进行修改和更新时不会影响原有的功能。
  3. 可扩展性:提升软件的可扩展性,添加新的功能的时候不会影响到现有的功能。
  4. 可重用性:不同层之间进行功能调用时,相同的功能可以重复使用。

上面的几点需要好好去理解和体会

接着看一下分析图

M:model,数据层,我们可以通俗的理解为,只要是能够产生的数据和输出数据的地方,都有model的影子;

V:视图层,功能比较简单,就是用来展示数据和发送数据到servlet的,两个功能;

C:controller,控制层,主要思想:1、从request对象中获取得到数据;2、将参数进行传递,然后调用业务逻辑;3、将业务逻辑返回的值进行页面展示(本质上就是模型数据展示到前端页面上);

转账案例代码:

Connection工具类:

public class ConnectionUtil {


    private static final ThreadLocal<Connection> CONNECTION_THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 设置线程
     */
    public static void setConnection() {
        CONNECTION_THREAD_LOCAL.set(C3P0Util.getConn());
    }

    /**
     * 获取得到线程对象
     *
     * @return
     */
    public static Connection getConnection() {
        Connection connection = CONNECTION_THREAD_LOCAL.get();
        if (Objects.isNull(connection)){
            connection = C3P0Util.getConn();
            CONNECTION_THREAD_LOCAL.set(connection);
        }
        return connection;
    }

    /**
     * 将线程回归到线程池中去
     */
    public static void revomeConneciton() {
        CONNECTION_THREAD_LOCAL.remove();
    }
}

连接池工具类:

public class C3P0Util {

    static ComboPooledDataSource ds;
    static {

         ds = new ComboPooledDataSource();
    }

    public static DataSource getDataSource(){
        return ds;
    }

    //提供获取连接
    public static Connection getConn(){
        try {
            return ds.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }

    }


    //关闭释放资源
    //重载!!!!!
    public static void  closeAll( Statement st , Connection conn){
        closeAll(null , st ,conn);
    }

    //真正这个st和 conn 是
    public static void  closeAll(ResultSet rs , Statement st , Connection conn){

        try {
            if(rs!=null)
                rs.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        try {
            if(st!=null)
                st.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        try {
            if(conn !=null)
                conn.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

}

serlvet层

@WebServlet(name = "UserServlet", value = "/UserServlet")
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            //1.获得请求参数(付款人 pay,收款人 payee,金额)
            String fukuan = request.getParameter("from");
            String shoukuan = request.getParameter("to");
            double money = Double.parseDouble(request.getParameter("money"));
            UserService userService = new UserService();
            //2.处理业务(判断付款人是否存在,收款人是否存在,判断金额是否有问题,判断钱是否够,进行转账(使用DBUtils操作数据库))
            boolean flag = userService.transfer(fukuan,shoukuan,money);
            //3.判断是否转账成功,响应
            if (flag){
                response.getWriter().print("转成成功");
            }else{
                response.getWriter().print("转成失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("转成失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

service层

public class UserService {
    public boolean transfer(String fukuan, String shoukuan, double money) throws Exception {
        Connection connection = null;
        try {
            connection = ConnectionUtil.getConnection();
            connection.setAutoCommit(false);
            UserDao userDao = new UserDao();
            boolean flag = userDao.transfer(fukuan,shoukuan,money);
            connection.commit();
            return flag;
        } catch (SQLException throwables) {
            try {
                connection.rollback();
            } catch (SQLException e) {
                throw new Exception("转账失败");
            }
        }
        return false;
    }
}

dao层

public class UserDao {

    /**
     * 转账案例
     * @param fukuan
     * @param shoukuan
     * @param money
     * @return
     * @throws SQLException
     */
    public boolean transfer(String fukuan, String shoukuan, double money) throws SQLException {
        QueryRunner queryRunner = new QueryRunner();
        Connection connection = ConnectionUtil.getConnection();
        String sql01 = "UPDATE account SET money = money-? WHERE name = ?";
        int rows01 = queryRunner.update(connection,sql01, money, fukuan);
        int i = 1/0;
        String sql02 = "UPDATE account SET money = money+? WHERE name = ?";
        int rows02 = queryRunner.update(connection,sql02,money,shoukuan);
        ConnectionUtil.revomeConneciton();
        if (rows01>0&&rows02>0){
            return true;
        }
        return false;
    }
}

不过我们也很容易看到这里的特点:有以下几个问题

1、繁琐。写代码起来,需要考虑到很多问题;

2、我们为了保证数据库中事务的完整性,我们需要拿到相同的连接来进行传递,需要关闭自动提交,在程序正确执行之后提交事务;在程序执行失败之后,需要将事务进行回滚,保证数据的完整性。在后期,我们要对这里的操作来进行改进。

正确的操作应该是我们只需要来关注我们的逻辑操作,类似这种事务的操作(小细节)不需要写大量的代码来进行实现。

3、SQL语句,这样子来写就会存在着硬编码问题,而且还不是特别通用,如果后期需要添加的话,还需要修改代码,这种方式比较麻烦

6.1、自己的一点想法

但是上面的原生方式开发我觉得有一个优点,就是没有大量的封装,性能上更快;运用这种方式来编写的代码会更具有效率,但同时在开发中,我们也需要考虑更多的问题以及自己来对问题来进行解决;

可能我更喜欢这种以原生代码的方式来运行代码,很多东西都是自己来做。但是我觉得更多的应该是让自己的代码变得通用

但是更多的是先写简单的代码,然后看更多的源码设计,理解别人为什么要这么设计,学习别人的设计思想,然后学以致用,运用到自己的代码开发中;

7、总结

posted @ 2022-02-13 23:12  写的代码很烂  阅读(97)  评论(0编辑  收藏  举报