JSP、EL表达式和JSTL标签库


一、JSP

1.1 概念:

Java Server Pages: 运行在Java服务器端的页面。

  • 可以理解为:一个特殊的页面,其中既可以指定定义HTML标签,又可以定义Java代码。
  • 本质:使用通过response对象获取打印流将页面信息打印至客户端进行网页的书写。
  • 用于简化书写!!!
  • JSP演变历史:

    1、早期只有Servlet,只能使用response输出标签数据,非常麻烦。
    2、后来有JSP,简化了Servlet的开发,如果过度使用JSP,在JSP中即写大量的Java代码,又写HTML,造成难于维护,难于分工协作。
    3、再后来,Java的Web开发,借鉴MVC开发模式,使得程序的设计更加合理性。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        System.out.println("hello,jsp!");
    %>
    <h1>hello,jsp !</h1>
</body>
</html>

1.2 JSP的原理

  • JSP本质

    就是一个Servlet。

第一次请求JSP导致加载JSP响应过慢的情况称之为第一人惩罚策略

在这里插入图片描述

  • 运行原理

    1、客户端发送请求
    2、JSP翻译成Java文件
    3、Java文件编译生成class文件
    4、运行class文件,向客户端响应内容

  • 执行流程

    当客户端请求对应的JSP时,服务器首先判断的是是否编译过,如果编译过继续判断,判断是否修改,如果修改重新编译,如果没有修改 ,则直接将之前编译的Servlet对象(JSP在执行时会翻译成Servlet)返回并进行服务处理。

1.3 JSP指令

  • 作用

    用于配置JSP页面,导入资源文件。

  • 格式
    <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>

  • 分类

    1、page
    用于配置当前JSP页面的属性,定义怎样运行JSP页面(一般不会自己特殊书写 而是通过创建自动定义)。

    • 语法:<%@ page 属性名=“值” 属性名=“值”%>
    • 属性
      • contentTypecontentType="text/html; charset=UTF-8";等同于response.setContentType()。
        • 1、设置响应体的MIME类型以及字符集。
        • 2、设置当前JSP页面的编码(只能是高级的IDE-集成开发工具才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)。
      • pageEncoding:代表的是当前页面的编码,JSP翻译成Java文件,服务器需要知道JSP文件的编码方式,一般设置为UTF-8。

      • language:定义语言。

      • import:导入Java包,可以出现多次,也可以写一个,包之间使用逗号隔开。一般直接在<% %>中书写对应类使用快捷键提示可以直接生成。

      • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面。

      • isErrorPage:标识当前也是是否是错误页面。

        • true:是,可以使用内置对象exception。
        • false:否。默认值。不可以使用内置对象exception。
      • isElIgnored:决定jsp页面是否忽略EL表达式(默认不忽略)。

        • true:是。EL表达式被忽略,使用无效。
        • false:否。默认值。可以使用EL表达式。

    2、include
    完成页面包含的、导入页面的资源文件。

    • 语法<%@include file="xxx.jsp"%>
    • 原理
      • 静态包含:把包含文件的代码复制到当前文件,一起翻译为Java文件,一起编译。
      • 该指令可以理解为将指定的JSP页面内容复制至当前指定位置。
    • 使用
      • 这个指令,经常用于重复功能的书写,将多个页面重复的功能书写在一个JSP中,其他页面通过引用的方式进行使用。例如:网站的导航栏以及尾部信息。

    3、taglib
    用于导入资源、导入其他标签库。

    • 语法<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      • prefix:用于定义前缀,是自定义的。

1.4 JSP的脚本

  • JSP定义Java代码的方式:

    1、<% Java代码 %>:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
    2、<%! 声明 %>:定义的Java代码,在JSP转换后的Java类的成员位置,书写的是方法。
    3、<%=Java表达式 %>:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。等价于write.print("");

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        System.out.println("hello,jsp!");
        int j = 5;//局部变量,在service()方法中。
    %>
    
    <%!
		//声明方法
		public int sum(int c,int d){
			return c + d;
		}
    %>
    <%
		int a = 10;
		int b = 60;
		sum(a,b);
	%>
    
    <!-- %=之间不能有空格,相对于输出语句。-->
    <%= "hello,jsp !" %>
    <h1>hello,jsp !</h1>
</body>
</html>

1.5 注释

  • HTML注释

    <!-- 代码 -->:只能注释HTML代码片段。被注释的代码依旧会被发送到客户端浏览器中,即使浏览器页面不会展示,但F12检查源码时,在源码中被注释的代码片段还能被查到。会发送至客户端,客户端可以查看。

  • Java注释

    <% //代码 %> / <% /* 代码 */ %> :注释Java代码,书写在Java小脚本中。在读取JSP后,解释Java代码、编译时忽略。

  • JSP注释

    <%-- 代码 --%> :可以注释所有。被注释的代码不会被发送到浏览器中,F12检查源码时,找不到被注释的内容(推荐以后使用这种注释方法)。在读取JSP时自动忽略。

1.6 动作标签

  • 概念

    JSP标签,但是需要放在服务器端运行,才能访问。

  • 作用

    JSP动作标签代替Java代码方式,通过标签的使用减少Java代码的书写。

  • 分类

    1、页面转发

    • 语法
      <jsp:forward page="xxx.jsp">:代表请求的转发;page代表的是转发的页面。

    • 虽然该方法可以转发页面,但是实际开发过程中我们通常使用Servlet转发JSP显示数据的形式进行操作,不会使用JSP转发到JSP,因为在书写代码时尽量减少JSP页面中Java代码的书写,防止混淆。

    2、页面引入

    • 语法
      <jsp:include page="xxx.jsp" />:代表页面的包含(动态包含,不管动态包含,静态包含,产生效果一样,但是原理不同)。

    • 与include指令一样都可以将指定页面引入到当前页面,效果也是相同,但是原理不同。

<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<%-- <% request.getRequestDispatcher("look.jsp").forward(request, response); %>
 --%>
<!-- jsp提供了相应的标签 替换java代码的书写 -->
<jsp:forward page="look.jsp"/>

<%@ include file="a.jsp"%>
<hr>
<jsp:include page="a.jsp" />
  • includle动作标签与include指令的区别
    • includle动作标签是动态引入。是将指定的JSP翻译成Servelt执行后将结果引入到当前Servlet中(会将所有涉及的Servlet全部翻译执行)。
    • include指令是静态引入。是在将JSP翻译成Servlet时,将指定页面代码复制至当前页面,之后翻译成一个Servlet之后编译执行(只翻译执行一个servlet)。
    • 使用场景:如果使用的JSP中没有书写Java,只是静态页面内容可以直接使用include指令引入,如果相应的JSP中需要执行代码建议使用includle标签,如果考虑到执行效率问题,也可以使用include指令。

1.7 JSP的内置对象

  • 在JSP页面中不需要获取和创建,可以直接使用的对象。
  • JSP一共有9个内置对象

    pageContext(PageContext) 当前页面
    request(HttpServletRequest) 当前请求
    session(HttpSession) 当前会话
    application(ServletContext) 当前应用
    response(HttpServletResponse) 响应信息
    page(Object) 当前页面的Servlet对象
    out(JspWriter / printWriter) 字符输出流对象
    config(ServletConfig) Servlet配置对象
    exception(Throwable) 异常对象

变量名真实类型作用
pageContextPageContext在当前页面中共享数据;还可以获取其他八个内置对象。域对象
requestHttpServletRequest在一次请求中访问的多个资源(转发)。域对象
sessionHttpSession在一次会话多个请求之间共享数据。域对象
applicationServletContext在整个应用的所有用户之间共享数据。域对象
responseHttpServletResponse保存请求页面的响应信息对象
pageObject当前页面(Servlet)对应的对象this
outJspWriter字符输出流对象,可以将数据输出到页面上。和response.getWriter()类似
configServletConfigServlet的配置对象
exceptionThrowable异常对象。用于存储当前页面异常信息,当页面发送异常时将异常信息存储至当前对象。主要在isErrorPage = true时,exception对象才能够被使用
  • response.getWriter()和out.write()的区别:
    • 1、在Tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
    • 2、response.getWriter()数据输出永远在out.write()之前。
  • pageContext

    代表的是当前页面上下文对象,也是一个域对象,代表范围是当前页面。

    • 作用
      • 1、域对象,代表范围是当前页面。
      • 2、可以获取其他八个内置对象。
        ServletRequest request = pageContext.getRequest();//获取request对象
        HttpSession session = pageContext.getSession();//获取session对象
        ServletContext application = pageContext.getApplication();//获取application 对象
      • 3、可以向其他域对象存取值。
        pageContext.setAttribute("test", "11", PageContext.SESSION_SCOPE);//通过pageContext向session域对象存入值
        pageContext.getAttribute("test", PageContext.SESSION_SCOPE);//通过pageContext从session域对象获取值
        pageContext.findAttribute("test")//从小的范围向大的范围依次查找,直到找到为止
  • 9个内置对象的代码演示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>page</title>
</head>
<body>
page.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<% pageContext.setAttribute("pageContext", "只有当前页面生效"); %>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>
<% request.setAttribute("request", "本次请求生效"); %>
<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<% session.setAttribute("session","本次会话生效"); %>
<%=session.getAttribute("session") %>

<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<% application.setAttribute("applicaton", "当前服务器生效"); %>
<%=application.getAttribute("applicaton") %>

<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<% request.getRequestDispatcher("look.jsp").forward(request, response); %>
</body>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>look</title>
</head>
<body>
look.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>

<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<%=session.getAttribute("session") %>

<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<%=application.getAttribute("applicaton") %>
</body>

1.8 案例

1.8.1 显示最后一次访问的登录时间

<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    //设置响应的学习体的数据格式以及编码
    response.setContentType("text/html;charset=utf-8");
    //1.获取所有Cookie
    Cookie[] cookies = request.getCookies();
    boolean flag = false;//没有cookie为lastTime
    //2.遍历Cookie数组
    if (cookies != null && cookies.length > 0) {
        for (Cookie cookie : cookies) {
            //3.获取cookie的名称
            String name = cookie.getName();
            //4.判断名称是否是:lastTime
            if ("lastTime".equals(name)) {
                //有该Cookie,不是第一次访问

                flag = true;//有lastTime的cookie

                //设置Cookie的value
                //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                String str_date = sdf.format(date);
                System.out.println("编码前:" + str_date);
                //URL编码
                str_date = URLEncoder.encode(str_date, "utf-8");
                System.out.println("编码后:" + str_date);
                cookie.setValue(str_date);
                //设置cookie的存活时间
                cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
                response.addCookie(cookie);

                //响应数据
                //获取Cookie的value,时间
                String value = cookie.getValue();
                System.out.println("解码前:" + value);
                //URL解码:
                value = URLDecoder.decode(value, "utf-8");
                System.out.println("解码后:" + value);
%>
<h1>欢迎回来,您上次访问时间为:<%=value %>
</h1>
<%
                break;
            }
        }
    }
    if (cookies == null || cookies.length == 0 || flag == false) {
        //没有,第一次访问

        //设置Cookie的value
        //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String str_date = sdf.format(date);
        System.out.println("编码前:" + str_date);
        //URL编码
        str_date = URLEncoder.encode(str_date, "utf-8");
        System.out.println("编码后:" + str_date);

        Cookie cookie = new Cookie("lastTime", str_date);
        //设置cookie的存活时间
        cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
        response.addCookie(cookie);
%>
<h1>您好,欢迎您首次访问</h1>
<%
    }
%>
</body>
</html>

1.8.2 用户登录并保存登录信息

  • 需求

    1、使用request域对象完成,登录失败后页面信息的显示登录成功,进入登录成功页面,登录失败返回登录页面,并在页面打印登录失败相应信息。

    2、使用session域对象完成免密登录操作。当请求/login url时,如果没有登录成功过则跳转登录页面,如果已经登录成功过,那么直接跳转至成功页面,无需再次登录。

  • 代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=ISO-8859-1">
<title>login</title>
</head>
<body>
<form action="login" method="post">
    账号:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录"><br/>
</form>
	<font style="red"><%=request.getAttribute("error") %></font>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=ISO-8859-1">
<title>success</title>
</head>
<body>
<%=request.getSession().getAttribute("username")%>,欢迎您
</body>
</html>
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//当请求/login  url时  如果没有登录成功过则跳转登录页面,如果已经登录成功过 那么直接跳转至成功页面 无需再次登录
        HttpSession session = request.getSession();
        Object u1 = session.getAttribute("username");
        Object p1 = session.getAttribute("password");
        if(u1!=null&&p1!=null){
            request.getRequestDispatcher("/success.jsp").forward(request, response);
        }else{
            request.setAttribute("error", "");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if ("admin".equals(username) && "admin".equals(password)) {
            //登录成功后将数据存储在session中
            HttpSession session = request.getSession();
            session.setAttribute("username",username);
            session.setAttribute("password",password);
            request.getRequestDispatcher("/success.jsp").forward(request, response);
        } else {
            request.setAttribute("error", "账号或密码错误!");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
	}
}

二、EL表达式

2.1概念

Expression Language:表达式语言。

  • 原理:EL表达式的出现目的是替换JSP中的Java的脚本中的<%= %>。并且内部进行了null值判断,如果为null则不会输出 ,不为null输出对应数据。
  • 使用场景

    1、获取域对象中的值(重要)。
    2、执行运算符号。
    3、调用Java中方法(了解)。
    4、EL表达式内置常用对象(重要)。

2.2 作用

可以替换和简化JSP页面中Java代码的编写。

2.3 语法

  • 语法

    ${表达式}

  • 注意

    JSP默认支持EL表达式的。
    如果要忽略EL表达式:

    • 1、设置JSP中page指令中:isELIgnored="true"; 忽略当前JSP页面中所有的EL表达式。
    • 2、\${表达式}:忽略当前这个EL表达式。
  • 代码演示

<%@ page contentType="text/html;charset=UTF-8" isELIgnored="true" language="java" %>
<%-- isELIgnored="true"; 忽略当前jsp页面中所有的EL表达式 --%>
<html>
<head>
    <title>Title</title>
</head>
<body>
${3 > 4}

<%--        
	<%= request.getAttribute("msg")%>
--%>
<!-- 等价于<%=  %>输出内容 会自动获取域中数据 并进行null值判断 -->
${msg}
        

<%-- \${表达式}:忽略当前这个el表达式  --%>
\${3 + 4}
</body>
</html>

2.4 EL表达式的使用

2.4.1 运算

基础运算加减乘除取模备注
关系运算== eq
> gt
< lt
>= ge
<= le
!= ne
等于
大于
小于
大于等于
小于等于
不等于
逻辑运算&& and
! not
|| or



empty运算符empty判断对象是否存在,或者集合的长度是否为0。
${empty list}:判断字符串、集合、数组对象是否为null或者长度为0。
${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0。
  • 运算符

    1、算数运算符: +、-、*、/(div)、%(mod)
    2、比较运算符: >(gt)、<(lt)、>=(ge)、<=(le)、==(eq)、!=(ne)
    3、逻辑运算符: &&(and)、||(or)、!(not)
    4、空运算符: empty

    • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0。返回值为true / false。
      • ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0。
      • ${not empty str}:表示判断字符串、集合、数组对象是否不为null,并且长度>0。
<h3>算数运算符</h3>
${3 + 4}<br/>
${3 - 4}<br/>
${3 * 4}<br/>
${3 / 4}<br/>
${3 div 4}<br/>
${3 % 4}<br/>
${3 mod 4}<br/>

<h3>比较运算符</h3>
${3 > 4}<br/>
${3 gt 4}<br/>
${3 < 4}<br/>
${3 lt 4}<br/>
${3 == 4}<br/>
${3 eq 4}<br/>
${3 != 4}<br/>
${3 ne 4}<br/>
${3 >= 4}<br/>
${3 ge 4}<br/>
${3 <= 4}<br/>
${3 le 4}<br/>

<h3>逻辑运算符</h3>
${3 > 4 && 3 < 4}<br/>
${3 > 4 and 3 < 4}<br/>
${3 > 4 || 3 < 4}<br/>
${3 > 4 or 3 < 4}<br/>
${!3 < 4}<br/>
${not 3 < 4}<br/>

<h3>空运算符</h3>
<%
	String str = "";
	requset.setAttribute("str",str);
%>
${empty str}	//false,判断域对象中a是否为空或者长度为0
${not empty str}	//false,判断域对象中a是否不为空,并且长度 > 0

2.4.2 获取值

  • EL表达式只能从域对象中获取值。

  • 语法

    1、${域名称.键名}

    • 从指定域中获取指定键的值。
    • 域名称:
    1. pageScope --> pageContext
    2. requestScope --> request
    3. sessionScope --> session
    4. applicationScope --> application(ServletContext)
      • 举例:在request域中存储了name=张三
      • 获取:${requestScope.name}

    2、${键名}

    • 表示依次从最小的域中查找是否有该键对应的值,直到找到为止。如果使用自动查找,建议多个域中不要存储相同的key。${key}

    3、获取对象、数组、List集合、Map集合的值

    • 对象${域名称.键名.属性名}
      • 本质上会去调用对象的getter方法
    • 数组${域名城.键名[索引]}
    • List集合${域名称.键名[索引]}
    • Map集合
      ${域名称.键名.key名称}
      ${域名称.键名["key名称"]}
  • 代码演示

<%-- 向不同域存值 --%>
<%
    /*分别为不同域设置相应key 不同值的数据*/
    pageContext.setAttribute("key","pageValue");
    request.setAttribute("key","requestValue");
    session.setAttribute("key","sessionValue");
    application.setAttribute("key","applicationValue");
%>

<%-- 从不同域中取值 --%>
<%-- 1.指定取值的域  从中取值 --%>
当前页面:${pageScope.key}<br>
当前请求:${requestScope.key}<br>
当前会话:${sessionScope.key}<br>
当前应用:${applicationScope.key}<br>

<%-- 2.自动查找域中的值 从作用域小的向上查找--%>
<%-- 自动查找会由下向上查找第一个指定的key并返回 如果使用自动查找 建议多个域中不要存储相同的key--%>
自动查找:${key} ——> 查找到的key是pageScope.key
<%-- 获取对象、数组、List集合、Map集合的值 --%>

<h3>从Java的对象中获取值</h3>
<% 
	User user = new User();
	user.setUsername("aaa");
	user.setPassword("123");
	pageContext.setAttribute("user", user);
%>
${ user.username }
${ user.password }

<h3>从数组中获取值</h3>
<%
	String [] arr = {"美美","小风","小花"};
	// EL表达式获取的是域对象中的值
	pageContext.setAttribute("arr", arr);
%>
${ pageScope.arr[0] }
${ pageScope.arr[1] }
${ arr[2] }

<h3>从Map集合获取值</h3>
<% 
	Map<String,String> map = new HashMap<String,String>();
	map.put("aaa", "美美");
	map.put("bbb", "小风");
	map.put("ccc", "小花");
	pageContext.setAttribute("map", map);
%>
${ map.aaa }
${ map.ccc }

<h3>从List集合中获取Java的对象的值</h3>
<% 
	List<User> list = new ArrayList<User>();
	list.add(new User("aaa","123"));
	list.add(new User("bbb","456"));
	list.add(new User("ccc","789"));
	pageContext.setAttribute("list", list);
%>
${ list[0].username }
<body>
<%-- 从域中取值(数组 list集合  map集合)并打印获取 --%>
<%
    //分别创建数组 list集合 map集合 对象 存储至域中
    String [] arr={"张三","李四","王五"};
    ArrayList<String> arrayList=new ArrayList<>();
    Collections.addAll(arrayList,"二狗子","猪蹄子");
    HashMap<String,String> hashMap=new HashMap<>();
    hashMap.put("username","zhangsan");
    hashMap.put("password","123456");

    Student student=new Student("lisi","abcddef");
    //存到域中
    pageContext.setAttribute("arr",arr);
    pageContext.setAttribute("arrayList",arrayList);
    pageContext.setAttribute("hashMap",hashMap);
    pageContext.setAttribute("student",student);
%>
获取数组数据
<%-- 可以直接通过  域key值[索引]  的形式获取数组中对应的数据 --%>
${arr[0]}
${arr[1]}
${arr[2]}
<hr>
获取list集合数据
<%-- 可以直接通过  域key值[索引]  的形式获取数组中对应的数据 --%>
${arrayList[0]}
${arrayList[1]}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${arrayList.get(0)}
${arrayList.get(1)}
<hr>
获取map集合数据
<%-- 可以直接通过 域key值.map的key 形式获取对应的value--%>
${hashMap.username}
${hashMap.password}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${hashMap.get("username")}
${hashMap.get("password")}

<hr>
获取对象中的属性值
<%-- 可以直接通过 域key值.属性 形式获取对应的value --%>
${student.username}
${student.password}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${student.getUsername()}

<%-- 注意 在获取自定义对象属性时 如果使用.属性的形式进行获取 那么必须书写公开的的get方法 --%>
</body>

2.4.3 隐式对象

  • EL表达式中有11个隐式对象。
对象含义
pageScope
requestScope
sessionScope
applicationScope
代表当前页面 page
代表当前请求 request
代表当前会话 session
代表当前应用 application
param返回客户端请求参数字符串值,相当于request.getParameter(String name)
initParam保存环境参数,相对于application.getInitParameter(String name)
paramValues返回客户端请求参数字符串值,相当于request.getParameterValues(String name)
pageContext可以获取其他八个内置对象,还可以获取虚拟目录
header保存用户浏览器和服务端用来沟通的数据,相对于request.getHeader(String name)
headerValues代表请求头,相对于request.getHeaders(String name)
cookie代表客户端发送请求中的所有cookie,相对于request.getCookies()
  • pageContext

    1、获取JSP其他八个内置对象。
    2、${pageContext.request.contextPath}:动态获取虚拟目录。

<h3>pageContext获取JSP其他八个内置对象。</h3>
${pageContext.request}
${pageContext.session}
${pageContext.servletContext}
${pageContext.response}
${pageContext.page}
${pageContext.out}
${pageContext.servletConfig}
${pageContext.exception}

<h3>pageContext动态获取虚拟目录</h3>
${pageContext.request.contextPath}
<h3>获取请求参数</h3>
<%= request.getParameter("username") %>

<h3>EL的方式</h3>
${ param.username }
${ paramValues.username[0] }

<h3>获取到请求头的信息</h3>
<%= request.getHeader("user-agent") %>

<h3>EL的方式</h3>
${ header["user-agent"] }

三、JSTL标签库

3.2 概念

JavaServer Pages Tag Library:JSP标准标签库。

  • 是由Apache组织提供的开源的免费的JSP标签<标签>。
  • JSTL依赖EL表达式,获取值是由EL表达式来获取的。
  • 使用场景

    1、向域对象存取值。
    2、判断域对象中的值。
    3、循环域对象中的值。

<%-- 书写存储对象的集合 并存储至域中在jsp页面打印 --%>
<%

    ArrayList<Student> list = new ArrayList<>();
    list.add(new Student("zhangsan", "123456"));
    list.add(new Student("wangwu", "456788"));
    list.add(new Student("lisi", "987654"));
    pageContext.setAttribute("list",list);
    pageContext.setAttribute("s",new Student("lisi", "987654"));
%>
<%-- jsp el表达式只是替代获取与输出脚本 不能进行额外的操作 所以在获取集合时 只能依次取出 --%>
<table border="1">
    <thead><tr><td>序号</td><td>账号</td><td>密码</td></tr></thead>
    <tbody>
    <tr><td>1</td><td>${list[0].username}</td><td>${list[0].password}</td></tr>
    <tr><td>2</td><td>${list[1].username}</td><td>${list[1].password}</td></tr>
    <tr><td>3</td><td>${list[2].username}</td><td>${list[2].password}</td></tr>
    <tr><td>4</td><td>${list[3].username}</td><td>${list[3].password}</td></tr>
    </tbody>
</table>
<%-- 但是一般数据由后台(servlet)从数据库中取出 不一定有多少条 虽然越界不会显示数据 --%>
<%-- 但是html对应的还是会显示 这个时候就需要使用jstl帮我们进行一些特殊的书写 --%>

3.2 作用

用于简化和替换JSP页面上的Java代码。

3.3 使用步骤

1. 导入JSTL相关jar包

  • javax.servlet.jsp.jstl.jar
  • jstl-impl.jar

2. 引入标签库

  • taglib指令<%@ taglib prefix=" " uri=" " %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

3. 使用标签

//out:输出内容(域对象,常量)
//value:输出的内容   default:代表默认值 escapeXml:是否转义(如果value又特殊字符,不转义)
<c:out value="${requestScope.username}" default="name"></c:out>
<c:out value="<a href='http://www.baidu.com'>点击</a>" escapeXml="false"></c:out>

//set 向域对象中存入值
//var:变量名 value:变量的值   scope:域范围
<c:set var="password" value="12345" scope="request"></j:set>

//remove:从域对象中删除值 var:要移除的key值
<c:remove var="password"></c:remove>

3.4 JSTL标签库的使用

<%-- JSTL功能--%>
<%-- 1.对域对象进行赋值--%>
<%-- (1)c:set var声明变量(存储在域中的key)  value值(存储在域中的值)  scope选择域(存储在那个域中)--%>
<c:set var="aaa" value="bbb"  scope="session"/>
${aaa}
<%-- (2)c:set target对象名(要修改属性的对象) property要修改的属性  value要修改的值  --%>
<c:set target="${s}"  property="username"  value="sssss"/>
${s}

<%-- 2.将指定数据输出 并进行设置 --%>
<%-- value输出的数据  default当数据为null时替代输出的数据 默认为""空字符串  escapeXml是否转义 --%>
<c:out value="${null}" default="默认值" escapeXml="false"/>

<%-- 3.移除域中指定数据 --%>
<%-- var移除的key  scope移除数据的作用域 如果没有会自动查找 --%>
<c:remove var="s" scope="page"/>
<c:out value="${s}" default="没有数据" escapeXml="false"/>

3.5 常用标签

3.5.1 if标签

if:对语句进行判断;相当于Java代码的if语句。

  • 语法

    <c:if test="判断的条件(boolean表达式)" var="条件的结果" scope="作用域"></if>

  • 属性

    • test:判断的条件,必须属性,接受boolean表达式。
      • 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容。
      • 一般情况下,test属性值会结合EL表达式一起使用。
    • var:把判断的条件的结果(true或者false)保存到var中。
    • scope:作用域(将var值存放的作用域)。
  • 注意

    c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签。

  • 代码演示

<%-- 对域中数据进行判断操作  --%>
<%-- 根据结果对页面内容进行书写 --%>
<%-- c:if 根据test返回的结果执行对应代码块  将结果保存到var定义的变量并存储到scope设置的作用域中 --%>
<c:if test="${s.username eq 'lisi'}" var="jg" scope="page">
    你叫李四
</c:if>
<c:if test="${s.username ne 'lisi'}">
    你不叫李四
</c:if>

3.5.2 choose标签

choose:用来进行判断,但是重合的标签;相当于Java代码的switch语句。

  1. 使用choose标签声明 相当于switch声明
  2. 使用when标签做判断 相当于case
  3. 使用otherwise标签做其他情况的声明 相当于default
  • 语法
<c:choose>
<c:when></c:when>
<c:otherwise></c:otherwise>
</choose>
  • 代码演示
<%-- 当判断的条件存在多个并可能取反的时候 需要使用c:choose标签 --%>
<%-- 可以看做 if esle if  else --%>
<c:choose>
    <c:when test="${s.username eq 'zhangsan'}">你是张三</c:when>
    <c:when test="${s.username eq 'lisi'}">你是李四</c:when>
    <c:otherwise>我不认识你</c:otherwise>
</c:choose>

3.5.3 foreach标签

foreach:用来迭代数据;相当于Java代码的for语句。

  • 语法

    <c:forEach var=" " begin=" " end=" " step=" " varStatus=" " ></c:forEach>

  • 属性

    • var:声明临时变量。
    • begin:从那开始。
    • end:结束。
    • step:步长。
    • varStatus:变量的状态。
      • index:当前这次迭代从 0 开始的迭代索引。
      • count:当前这次迭代从 1 开始的迭代计数。
      • current:当前这次迭代的(集合中的)项。
      • first:用来表明当前这轮迭代是否为第一次迭代的标志。
      • last:用来表明当前这轮迭代是否为最后一次迭代的标志。
    • items:需要遍历的集合。
  • 代码演示

<h3>模拟普通的for循环</h3>
<c:forEach var="i" begin="1" end="10" step="2" varStatus="vs">
	${ i }	
	${ vs.count }
</c:forEach>

<h3>模拟增强for循环的效果</h3>
<!--  
	for(String s : list){}
-->
<% 
	List<String> list = new ArrayList<String>();
	list.add("美美");
	list.add("小风");
	list.add("小花");
	pageContext.setAttribute("list", list);
%>
<c:forEach var="s" items="${ list }">
	${ s }
</c:forEach>

<h3>map集合</h3>
<% 
	Map<String,String> map = new HashMap<String,String>();
	map.put("aaa", "美美");
	map.put("bbb", "小风");
	map.put("ccc", "小花");
	pageContext.setAttribute("map", map);
%>
<c:forEach var="entry" items="${ map }">
	${ entry.key }  -- ${ entry.value }
</c:forEach>

<h3>List集合中存入对象</h3>
<% 
	List<User> ulist = new ArrayList<User>();
	ulist.add(new User("aaa","123"));
	ulist.add(new User("bbb","456"));
	ulist.add(new User("ccc","789"));
	pageContext.setAttribute("ulist", ulist);
%>
<c:forEach var="user" items="${ ulist }">
	${ user.username } -- ${ user.password }
</c:forEach>



<%-- 当需要对域中存储的集合数据进行操作时 需要根据数据的实际数量进行页面的书写 --%>
<%-- 这个时候就需要使用c:foreach标签 --%>
<%-- 1.普通的循环操作 将内容重复指定次数输出 --%>
<%-- var声明保存数据的变量(初始化语句)  begin初始化变量的初始值  end结束值  step步长(迭代语句)     --%>
<%-- varStatus保存当前变量数据的信息对象 通过设置的对象名.属性名获取对应的信息 --%>
<c:forEach var="i" begin="0" end="10" step="2" varStatus="status">
    ${i} /${status.end}   <br>
</c:forEach>

<%-- 2.遍历域中集合数据 --%>
<%-- 只需要var 以及items  也可以携带 varstatus --%>
<%-- var 每次取出的数据遍历   items域中存储的遍历的集合  --%>
<c:forEach var="student"  items="${list}" varStatus="status">
${student}<br>
</c:forEach>

<%-- 通常使用表格以及c:foreach进行数据的展示 --%>
<table border="1">
    <thead>
    <tr>
        <td>序号</td>
        <td>账号</td>
        <td>密码</td>
    </tr>
    </thead>
    <tbody>
    <c:forEach var="student" items="${list}" varStatus="status">
        <c:if test="${status.count%2==0}">
             <tr style="background-color: red"><td>${status.count}</td><td>${student.username}</td><td>${student.password}</td></tr>
        </c:if>
        <c:if test="${status.count%2!=0}">
              <tr style="background-color: green"><td>${status.count}</td><td>${student.username}</td><td>${student.password}</td></tr>
        </c:if>
    </c:forEach>
    </tbody>
</table>

3.6 案例

  • 需求

    在request域中有一个存有User对象的List集合。需要使用JSTL+EL将List集合数据展示到JSP页面的表格table中。

  • 代码实现

导包
druid.jar
mysql-connector-java.jar
jstl.jar
standard.jar

sql语句

CREATE TABLE `student` (
  `studentid` int(20) NOT NULL,
  `studentname` varchar(20) DEFAULT NULL,
  `studentage` int(11) DEFAULT NULL,
  `studentsex` char(10) DEFAULT NULL,
  `studentaddress` varchar(50) DEFAULT NULL,
  `classid` int(11) DEFAULT NULL,
  PRIMARY KEY (`studentid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `student` VALUES ('2010001', 'Jack', '16', '男', '湖北襄樊', '1');
INSERT INTO `student` VALUES ('2010002', 'Scott', '20', '男', '湖北武汉', '2');
INSERT INTO `student` VALUES ('2010003', 'Lucy', '20', '女', '湖北武汉', '3');
INSERT INTO `student` VALUES ('2010004', 'Alan', '20', '女', '湖北襄樊', '4');
INSERT INTO `student` VALUES ('2010005', 'Bill', '20', '男', '湖北襄樊', '5');
INSERT INTO `student` VALUES ('2010006', 'Bob', '20', '男', '湖北宜昌', '6');
INSERT INTO `student` VALUES ('2010007', 'Colin', '20', '女', '湖北襄樊', '6');
INSERT INTO `student` VALUES ('2010008', 'Fred', '20', '男', '湖北宜昌', '5');
INSERT INTO `student` VALUES ('2010009', 'Hunk', '20', '男', '湖北武汉', '4');
INSERT INTO `student` VALUES ('2010010', 'Jim', '20', '男', '湖北襄樊', '3');
INSERT INTO `student` VALUES ('2010011', 'Jvm', '24', '男', '湖北武汉', '1');
INSERT INTO `student` VALUES ('2010012', 'jxm', '20', '男', '湖北武汉', '2');

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES ('1', 'zhangsan', '123');
INSERT INTO `user` VALUES ('2', 'lisi', '234');
INSERT INTO `user` VALUES ('3', 'wangwu', '123');
INSERT INTO `user` VALUES ('4', 'wangwu', '123');
INSERT INTO `user` VALUES ('5', 'wangwu', '123');
INSERT INTO `user` VALUES ('6', 'zhang', '123456');
INSERT INTO `user` VALUES ('7', 'zhang', '123456');
INSERT INTO `user` VALUES ('8', 'zhang', '123456');
INSERT INTO `user` VALUES ('9', '张三', '123456');

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=ISO-8859-1">
<title>login</title>
</head>
<body>
<form action="login" method="post">
    账号:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录"><br/>
</form>
	<font color="red">${error}</font>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="com.ys.servlet.User"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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=ISO-8859-1">
<title>success</title>
</head>
<body>
	<table border="1" cellpadding="0" cellspacing="0" align="center"
		width="700px">
		<thead>
			<tr>
				<td>序号</td>
				<td>账号</td>
				<td>密码</td>
			</tr>
		</thead>
		<tbody>
			<c:forEach var="user" items="${user}" varStatus="status">
				<tr>
					<td>${status.count}</td>
					<td>${user.username}</td>
					<td>${user.password}</td>
				</tr>
			</c:forEach>
		</tbody>
	</table>
</body>
</html>

LoginServlet.java

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 书写学生类以及对应数据库信息,查询数据库完成登录操作,
 * 登录成功后在登录成功页面打印数据库中学生表所有数据
 *
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        if(user != null){
            request.getRequestDispatcher("/success.jsp").forward(request, response);
        }else{
            request.setAttribute("error", "");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");

		String name = request.getParameter("username");
		String pwd = request.getParameter("password");
		User loginUser = new User();
		loginUser.setUsername(name);
		loginUser.setPassword(pwd);

		HttpSession session = request.getSession();

		String sql1 = "select * from user where username = ? and password = ?";
		ArrayList<User> user = AJDBCUtil.query(sql1, User.class, loginUser.getUsername(), loginUser.getPassword());

		if (user.size() == 0) {
			request.setAttribute("error", "用户名或密码错误");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
		} else {
			session.setAttribute("user", user);
			request.getRequestDispatcher("success.jsp").forward(request, response);
		}
	}
}

AJDBCUtil.java

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Properties;

public class AJDBCUtil {

	private static DataSource druidDataSource = null;// 连接池对象

	private AJDBCUtil() {
	}

	// 获取连接
	// 使用Druid连接池加载配置获取连接
	// 加载配置在静态代码块中进行执行
	static {
		try {

			Properties p = new Properties();
			InputStream is = AJDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
			p.load(is);
			// 创建连接池对象
			druidDataSource = DruidDataSourceFactory.createDataSource(p);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 获取连接的方法本质就是使用连接池工厂对象获取连接池对象 之后获取连接
	public static Connection getCon() {
		Connection con = null;
		try {
			con = druidDataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return con;
	}

	// 更新操作方法
	// 使用不确定参数的形式进行参数的输出
	public static int update(String sql, Object... obj) {
		// 获取连接
		Connection con = getCon();
		int count = 0;
		try {
			// 创建预编译声明对�? 将sql进行预编写
			PreparedStatement ps = con.prepareStatement(sql);
			// 将占位符数据填入
			for (int i = 0; i < obj.length; i++) {
				ps.setObject(i + 1, obj[i]);
			}
			// 执行sql
			count = ps.executeUpdate();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return count;
	}

	// 满足事务操作的方式
	public static int update(Connection con, String sql, Object... obj) throws SQLException {
		int count = 0;
		// 关闭事务的自动提交
		con.setAutoCommit(false);
		// 创建预编译声明对象 将sql进行预编译
		PreparedStatement ps = con.prepareStatement(sql);
		// 将占位符数据填入
		for (int i = 0; i < obj.length; i++) {
			ps.setObject(i + 1, obj[i]);
		}
		// 执行sql
		count = ps.executeUpdate();
		return count;
	}

	// 查询操作方法
	// 传入sql 传入保存数据的类的class类型 传入sql参数
	public static <E> ArrayList<E> query(String sql, Class<E> c, Object... obj) {
		ArrayList<E> list = new ArrayList<>();

		// 获取连接
		Connection con = getCon();
		try {
			// 创建预编译对象
			PreparedStatement ps = con.prepareStatement(sql);
			// 将数据加载
			for (int i = 0; i < obj.length; i++) {
				ps.setObject(i + 1, obj[i]);
			}

			// 获取元数据
			ResultSetMetaData metaData = ps.getMetaData();
			// 获取查询结果列数
			int columnCount = metaData.getColumnCount();

			// 创建集合保存结果列名
			ArrayList<String> columnName = new ArrayList<>();
			for (int i = 1; i <= columnCount; i++) {
				String cName = metaData.getColumnName(i);
				columnName.add(cName);
			}
			// 执行sql
			ResultSet rs = ps.executeQuery();
			// 处理结果集
			while (rs.next()) {
				// 创建对象
				E e = c.newInstance();

				// 遍历列名 分别进行操作
				for (String name : columnName) {
					// 通过列名获取数据
					Object value = rs.getObject(name);
					// 通过反射获取当前类指定属性对象
					Field nameField = c.getDeclaredField(name);
					nameField.setAccessible(true);
					// 将数据添加
					nameField.set(e, value);
				}
				// 将对象存入集合
				list.add(e);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
}

Student.java

public class Student {
	private int studentid;
	private String studentname;
	private int studentage;
	private String studentsex;
	private String studentaddress;
	private int classid;
	public Student() {
		super();
	}
	public Student(int studentid, String studentname, int studentage, String studentsex, String studentaddress,
			int classid) {
		super();
		this.studentid = studentid;
		this.studentname = studentname;
		this.studentage = studentage;
		this.studentsex = studentsex;
		this.studentaddress = studentaddress;
		this.classid = classid;
	}
	public int getStudentid() {
		return studentid;
	}
	public void setStudentid(int studentid) {
		this.studentid = studentid;
	}
	public String getStudentname() {
		return studentname;
	}
	public void setStudentname(String studentname) {
		this.studentname = studentname;
	}
	public int getStudentage() {
		return studentage;
	}
	public void setStudentage(int studentage) {
		this.studentage = studentage;
	}
	public String getStudentsex() {
		return studentsex;
	}
	public void setStudentsex(String studentsex) {
		this.studentsex = studentsex;
	}
	public String getStudentaddress() {
		return studentaddress;
	}
	public void setStudentaddress(String studentaddress) {
		this.studentaddress = studentaddress;
	}
	public int getClassid() {
		return classid;
	}
	public void setClassid(int classid) {
		this.classid = classid;
	}
	@Override
	public String toString() {
		return "Student [studentid=" + studentid + ", studentname=" + studentname + ", studentage=" + studentage
				+ ", studentsex=" + studentsex + ", studentaddress=" + studentaddress + ", classid=" + classid + "]";
	}
}

User.class

public class User {
	private int id;
	private String username;
	private String password;
	public User() {
		super();
	}
	
	public User(int id, String username, String password) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
	}
}

druid.properties

url=jdbc:mysql://localhost:3306/db
#这个可以缺省的,会根据url自动识别
driverClassName=com.mysql.jdbc.Driver
username=root
password=root

##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20

四、MVC和三层架构

4.1 MVC开发模式

4.1.1 组成

在这里插入图片描述

  • MVC框架

    1、M:Model,模型。 JavaBean

    • 完成具体的业务操作,如:查询数据库,封装对象。

    2、V:View,视图。 JSP

    • 展示数据。

    3、C:Controller,控制器。 Servlet

    • 获取用户的输入。
    • 调用模型。
    • 将数据交给视图进行展示。

3.1.2 优缺点

  • 优点

    1、耦合性低,方便维护,可以利于分工协作。
    2、重用性高。

  • 缺点

    使得项目架构变得复杂,对开发人员要求高。

4.2 三层架构

4.2.1 组成

在这里插入图片描述

  • 三层架构(软件设计架构)

    1、界面层(表示层)

    • 用户看的得界面。用户可以通过界面上的组件和服务器进行交互

    2、业务逻辑层

    • 处理业务逻辑的。

    3、数据访问层

    • 操作数据存储文件。

4.2.2 案例:用户信息列表展示

4.2.2.1 需求

用户信息的增删改查操作。

4.2.2.2 设计
  • 技术选型

    Servlet + JSP + MySQL + JDBCTemplate + Duird + BeanUtils + Tomcat

  • 数据库设计

		create database day17; -- 创建数据库
		use day17; 			   -- 使用数据库
		create table user(   -- 创建表
			id int primary key auto_increment,
			name varchar(20) not null,
			gender varchar(5),
			age int,
			address varchar(32),
			qq	varchar(20),
			email varchar(50)
		);
		insert  into `user`(`id`,`name`,`gender`,`age`,`address`,`qq`,`email`) values (1,'张三','男',13,'陕西','12345','zhangsan@itcast.cn');
		insert  into `user`(`id`,`name`,`gender`,`age`,`address`,`qq`,`email`) values (2,'李四','女',15,'北京','88888','ls@itcast.cn');
4.2.2.3 开发
  • 环境搭建

    • 创建数据库环境(建库、建表、导入数据)
    • 创建项目,导入需要的jar包
    • 把前端开发人员设计好的html页面、js、css、image等导入
  • 编码

总体功能流程分析
在这里插入图片描述

  • 单个页面功能分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2.2.4 测试
4.2.2.5 部署运维

每日一点点进步
不进则退

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

璃尔 °

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值