8.JSP

JSP

1.include指令标签

JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件,比如每个页面都引入一个共同的jsp页面(注意include和page import的区别)。包含的文件就好像是JSP文件的一部分,会被同时编译执行。除了include指令标签可以实现引入以外,使用jsp:include也可以实现引入。
head.jsp(被引入文件):

<%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/13
  Time: 22:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        *{
            margin:0px;
            padding:0px;
        }
    </style>
</head>
<body>
<img src="img/img.png" width="100%">
</body>
</html>

head.jsp
include.jsp(静态引入head.jsp,被引入的文件不会单独转译为java文件,而是代码内容进行嵌入):
引入的文件放哪了 等于就把这个文件的代码引入在这个位置了。事实上被引入的head.jsp并不会被单独转译成java代码(servlet),而是head.jsp的代码嵌入到了include.jsp中,include.jsp转译为java代码。

<%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/13
  Time: 22:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%@ include file="head.jsp"%>
</body>
</html>

include.jsp
include.jsp(动态引入head.jsp)
include.jsp和被引入的head.jsp都转移为了java文件,在include.jsp中通过

org.apache.jasper.runtime.JspRuntimeLibrary.include(request,response,"head.jsp",out,false)

来引入head.jsp。(其实就是include请求转发 include请求转发,目标组件servlet进行response的信息追加后再返回给源组件servlet)

<%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/13
  Time: 22:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--静态引入--%>
<%--<%@ include file="head.jsp"%>--%>
<%--动态引入--%>
<jsp:include page="head.jsp"/>
</body>
</html>

include.jsp

2.JSP九大内置对象

JSP的本质是Servlet,在JSP文件经过转译之后,生成JAVA代码,在运行时 JSP给我们准备好了九个可以直接使用而不用我们自己去new的对象,这九个对象我们称之为内置对象,内置对象完全由JSP自行维护,我们直接使用即可
九大内置对象:
九大内置对象
四个域对象(用得最多,用来数据传递):
pageContext page域 当前页面内可用(jsp中独有的域)
request request域 单次请求内
session session域 单次会话
application application域 整个web项目的生命周期

响应对象:
response http响应对象

输出流对象:
out 打印流对象

其他三个对象:
config:由于JSP本身也是一个Servlet,所以容器也会给我们准备一个ServletConfig
page:就是this对象,当前JSP对应的Servlet对象本身
exception:异常对象,在错误提示页上使用,当一个jsp文件已经声明了isErrorPage=true时,这个jsp文件才有该对象

innerObject.jsp:

<%@ page import="java.util.Date" %><%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/13
  Time: 23:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Date date = new Date();
    //1.四个域对象(用得最多,用来数据传递)
    pageContext.setAttribute("name","zhaoyu"); // page域,只在当前页面(innerObject.jsp)中有效
    request.setAttribute("age","18"); // request域对象
    session.setAttribute("gender","man"); // session域对象
    application.setAttribute("lang","chinese"); // application域对象

    //2.响应对象
    response.setHeader("key","value"); // http response

    //3.输出流对象
    out.write("hello"); // 输出流对象(JspWriter)

    //4.其他内置对象
    config.getInitParameter(""); //ServletConfig
    page.getClass(); //page就是this(innerObject_jsp.class)
    //exception内置对象是别的页面传过来的异常对象,只有我们在此jsp文件中声明了isErrorPage=true时 才能使用这个对象
    System.out.println(exception.getMessage());
%>
</body>
</html>

innerObject.jsp对应的Servlet:
可以看到在_jspService方法中创建了9个内置对象。

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.80
 * Generated at: 2023-11-13 15:19:36 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.Date;

public final class innerObject_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 = new java.util.HashSet<>();
    _jspx_imports_classes.add("java.util.Date");
  }

  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 {
    
    //_jspservice方法中创建了9个内置对象
    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
    if (exception != null) {
      response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
    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("\n");
      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("    <title>Title</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");

    Date date = new Date();
    //1.四个域对象(用得最多,用来数据传递)
    pageContext.setAttribute("name","zhaoyu"); // page域,只在当前页面(innerObject.jsp)中有效
    request.setAttribute("age","18"); // request域对象
    session.setAttribute("gender","man"); // session域对象
    application.setAttribute("lang","chinese"); // application域对象

    //2.响应对象
    response.setHeader("key","value"); // http response

    //3.输出流对象
    out.write("hello"); // 输出流对象(JspWriter)

    //4.其他内置对象
    config.getInitParameter(""); //ServletConfig
    page.getClass(); //page就是this(innerObject_jsp.class)
    //exception内置对象是别的页面传过来的异常对象,只有我们在此jsp文件中声明了isErrorPage=true时 才能使用这个对象
    System.out.println(exception.getMessage());

      out.write("\n");
      out.write("</body>\n");
      out.write("</html>\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);
    }
  }
}

3.利用域对象传递数据

我们在Servlet1中设置User对象到各个域对象中(request,session,servletContext),然后跳转至showinfo.jsp,在showinfo.jsp中拿到各个域对象的数据。
注意各域对象的生命周期,比如如果请求转发的话,req对象中的数据就能拿到,但是如果响应重定向的话,req对象生命周期不跨请求,所以就拿不到数据了。

User类:

package com.example.demo5;/**
 * @Author:zhoayu
 * @Date:2023/11/14 22:06
 * @Description:com.example.demo5
 * @version:1.0
 */

import lombok.Data;

import java.io.Serializable;

/**
 * @ClassName User
 * @Description //TODO 
 * @Author zhaoyu
 * @Date 2023/11/14
 */
@Data
public class User implements Serializable {
    private String name;
    private String gender;
    private String password;
}

Servlet1:

package com.example.demo5;/**
 * @Author:zhoayu
 * @Date:2023/11/14 22:04
 * @Description:com.example.demo5
 * @version:1.0
 */

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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;

/**
 * @ClassName Servlet1
 * @Description //TODO 
 * @Author zhaoyu
 * @Date 2023/11/14
 */
@WebServlet(urlPatterns = "/.servlet1.do")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = new User();
        user.setName("zy");
        user.setGender("man");
        user.setPassword("12345");

        User user2 = new User();
        user2.setName("zy2");
        user2.setGender("man2");
        user2.setPassword("123452");

        User user3 = new User();
        user3.setName("zy3");
        user3.setGender("man3");
        user3.setPassword("123453");

        //在Servlet中向四个域对象放入数据
        //向request域对象中放数据(生命周期:一次请求)
        req.setAttribute("user",user);
        req.setAttribute("req",1);

        //向session域对象中放数据(生命周期:一次会话)
        HttpSession session = req.getSession();
        session.setAttribute("user2",user2);
        session.setAttribute("session",1);

        //向application域对象中放数据(生命周期:同整个web项目)
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("user3",user3);
        servletContext.setAttribute("application",1);

        //跳转至showinfo.jsp
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("showinfo.jsp");
        requestDispatcher.forward(req,resp);
    }
}

showinfo.jsp:

<%@ page import="com.example.demo5.User" %>
<%@ page import="java.io.PrintWriter" %><%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/14
  Time: 22:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--向pageContext中设置数据--%>
<%
    pageContext.setAttribute("msg","pageContext");
    pageContext.setAttribute("user4",new User());
%>

<%--从servlet1跳转过来,把域对象中的数据取出--%>
<%
    //request域对象中的数据
    PrintWriter writer = response.getWriter();
    writer.write(request.getAttribute("user").toString());

    //session域对象中的数据
    writer.write(session.getAttribute("user2").toString());

    //application域中的对象
    writer.write(application.getAttribute("user3").toString());

    //page域中的对象(PageContext生命周期:本页面)
    writer.write(pageContext.getAttribute("user4").toString());

%>

</body>
</html>

4.EL表达式-取值

EL:Expression Language。EL表达式中定义了一些可以帮助我们快捷的从域对象中取出数据的写法,基本语法为:

${域标志.数据名.属性名(可选)}

四个域标志关键字分别为:
1.requestScope request域
2.sessionScope session域
3.applicationScope application域
4.pageScope page域

Servlet向4个域对象中放数据:

package com.example.demo5;/**
 * @Author:zhoayu
 * @Date:2023/11/14 22:04
 * @Description:com.example.demo5
 * @version:1.0
 */

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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;

/**
 * @ClassName Servlet1
 * @Description //TODO 
 * @Author zhaoyu
 * @Date 2023/11/14
 */
@WebServlet(urlPatterns = "/.servlet1.do")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = new User();
        user.setName("zy");
        user.setGender("man");
        user.setPassword("12345");

        User user2 = new User();
        user2.setName("zy2");
        user2.setGender("man2");
        user2.setPassword("123452");

        User user3 = new User();
        user3.setName("zy3");
        user3.setGender("man3");
        user3.setPassword("123453");

        //在Servlet中向四个域对象放入数据
        //向request域对象中放数据(生命周期:一次请求)
        req.setAttribute("user",user);
        req.setAttribute("req",1);

        //向session域对象中放数据(生命周期:一次会话)
        HttpSession session = req.getSession();
        session.setAttribute("user2",user2);
        session.setAttribute("session",1);

        //向application域对象中放数据(生命周期:同整个web项目)
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("user3",user3);
        servletContext.setAttribute("application",1);

        //跳转至showinfo.jsp
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("showinfo.jsp");
        requestDispatcher.forward(req,resp);
    }
}

showinfo.jsp 用el表达式获得域对象中的值:
这里的el表达式中的对象是通过反射创建的,${域标志.数据名.属性名(可选)},属性名是通过getxxx()获取的,所以我们要保证如果是域对象中存的value是对象的话,该类要有对应的getxxx()方法(如果没有还使用el表达式取属性的话,就会报错)

<%@ page import="com.example.demo5.User" %>
<%@ page import="java.io.PrintWriter" %><%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/14
  Time: 22:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--向pageContext中设置数据--%>
<%
    pageContext.setAttribute("msg","pageContext");
    pageContext.setAttribute("user4",new User());
%>

<%--从servlet1跳转过来,把域对象中的数据取出--%>
<%
    //request域对象中的数据
    PrintWriter writer = response.getWriter();
    writer.write(request.getAttribute("user").toString());

    //session域对象中的数据
    writer.write(session.getAttribute("user2").toString());

    //application域中的对象
    writer.write(application.getAttribute("user3").toString());

    //page域中的对象(PageContext生命周期:本页面)
    writer.write(pageContext.getAttribute("user4").toString());
%>
    page域中的数据:<br/>
    msg:${pageScope.msg}<br/>
    username:${pageScope.uesr4.name}

    request域中的数据:<br/>
    username:${requestScope.user.name}

    session域中的数据:<br/>
    username:${sessionScope.user2.name}

    application域中的数据:<br/>
    username:${applicationScope.user3.name}

</body>
</html>

ps:
1.el表达式在使用时不需要import其他包,比如上述el表达式 我们不导入User类也没关系;
2.如果el表达式获得的值是null,在前端页面是不展示信息的。
3.el表达式在取出数据的时候,是可以省略域标志的,此时el表达式会自动依次到4个域对象中去找对应的数据。
如果这个数据名在多个域对象中都有(eg:${msg}),取的优先顺序是Page->Request->Session->Application
eg:

username:${user2.name}

pageContext:
pagecontext
pageContext中最重要的方法:findAttribute方法,使用pageContext.findAttribute方法能从四个域(page, request, session, context)中寻找存储的数据,查找的顺序也是从小到大(page—>request—>session—>context),只要在某个域中能查到相对应的键值对,就返回,如果四个域都没有则返回null。这个方式对于EL表达式是最重要的,例如JSP页面中有一个EL表达式: ${data} 最终在Servlet中就会被翻译成 pageContext.findAttribute(“data”)。

pageContext.removeAttribute(“key值”)方法会移除四个域中的所有的同key的entry。
request/session/application的removeAttribute(“key值”)都只会移除自己下面对应的entry

pageContext的主要作用(自己理解的):利用域对象中的变量在页面中有效的特性,在jsp文件的java代码部分向pageContext域对象中设置值,在jsp文件的html代码部分通过<%=值.方法%>或者el表达式来取出值(后者使用起来更简洁)>

5.EL表达式-获取请求参数

使用EL表达式获取请求中的参数,达到类似req.getParameter(“参数名”)或者req.getParameterValues(“参数名”)的效果(前者返回一个String类型的value,后者返回一个String[]的value)

<%@ page import="com.example.demo5.User" %>
<%@ page import="java.io.PrintWriter" %><%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/14
  Time: 22:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--向pageContext中设置数据--%>
<%
    pageContext.setAttribute("msg","pageContext");
    pageContext.setAttribute("user4",new User());
%>

<%--从servlet1跳转过来,把域对象中的数据取出--%>
<%
    //request域对象中的数据
    PrintWriter writer = response.getWriter();
    writer.write(request.getAttribute("user").toString());

    //session域对象中的数据
    writer.write(session.getAttribute("user2").toString());

    //application域中的对象
    writer.write(application.getAttribute("user3").toString());

    //page域中的对象(PageContext生命周期:本页面)
    writer.write(pageContext.getAttribute("user4").toString());
%>
    page域中的数据:<br/>
    msg:${pageScope.msg}<br/>
    username:${pageScope.uesr4.name}

    request域中的数据:<br/>
    username:${requestScope.user.name}

    session域中的数据:<br/>
    username:${sessionScope.user2.name}

    application域中的数据:<br/>
    username:${applicationScope.user3.name}

    <%--EL表达式获取请求中的参数--%>
    <%--eg:获取请求参数中的username参数对应的value--%>
    username:${param.username}
    <%--或者数组类型的请求参数--%>
    hobby:${paramValues.hobby}
    hobby:${paramValues.hobby[0]}
    hobby:${paramValues.hobby[1]}

</body>
</html>

6.EL表达式支持的运算符

在EL表达式中,可以使用运算符对数据进行一些简单的处理。支持的运算符有:
算数运算符:
+,-,*,/,%
关系运算符:
等于:==,eq,equals
大于:>,gt,greater than
小于:<,lt,lower than
大于等于:>=,ge,greate than or equals
小于等于:<=,le,lower than or equals
不等于:!=,ne,not equals
逻辑运算符:
||,&&
三目运算符:
${条件?表达式1:表达式2}
判空运算符:
empty

示例代码:

<%@ page import="com.example.demo5.User" %>
<%@ page import="java.io.PrintWriter" %><%--
  Created by IntelliJ IDEA.
  User: zhaoyu
  Date: 2023/11/14
  Time: 22:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--向pageContext中设置数据--%>
<%
    pageContext.setAttribute("msg","pageContext");
    pageContext.setAttribute("user4",new User());
%>

<%--从servlet1跳转过来,把域对象中的数据取出--%>
<%
    //request域对象中的数据
    PrintWriter writer = response.getWriter();
    writer.write(request.getAttribute("user").toString());

    //session域对象中的数据
    writer.write(session.getAttribute("user2").toString());

    //application域中的对象
    writer.write(application.getAttribute("user3").toString());

    //page域中的对象(PageContext生命周期:本页面)
    writer.write(pageContext.getAttribute("user4").toString());
%>
    page域中的数据:<br/>
    msg:${pageScope.msg}<br/>
    username:${pageScope.uesr4.name}

    request域中的数据:<br/>
    username:${requestScope.user.name}

    session域中的数据:<br/>
    username:${sessionScope.user2.name}

    application域中的数据:<br/>
    username:${applicationScope.user3.name}

    <%--EL表达式获取请求中的参数--%>
    <%--eg:获取请求参数中的username参数对应的value--%>
    username:${param.username}
    <%--或者数组类型的请求参数--%>
    hobby:${paramValues.hobby}
    hobby:${paramValues.hobby[0]}
    hobby:${paramValues.hobby[1]}

    <%--EL表达式中的运算符--%>
    <%--1.算数运算符--%>
    <%--el运算式中,会尝试把字符串转成数字进行运算 eg:"10"+"10"=20,如果字符串不能转成数字 eg:10/"10a" 就报NumberFormatException--%>
    加法:${"10"+"10"}<br/>
    <%--除法如果分母为0 结果为infinity 而不是抛异常--%>
    除法:${10/"10"}<br/>
    <%--如果和0取余数,则抛异常--%>
    取模:${10%10}<br/>

    <%--2.关系运算符--%>
    ${10==10}<br/>
    <%--EL表达式中,推荐使用字符形式的运算符而不是 == >= <= > <等,这是为了避免< >破坏html结构的风险--%>
    ${10 eq 10}<br/>
    ${10 gt 10}<br/>
    ${10 lt 10}<br/>
    ${10 ge 10}<br/>
    ${10 le 10}<br/>
    ${10 ne 10}<br/>

    <%--3.逻辑运算符--%>
    ${true || false}
    ${true && false}
    ${true or false}
    ${true and false}

    <%--4.三目运算符--%>
    ${true ? 10+1 : 10-1}
    ${100<200 ? true : false}
    ${100 % 200 ne 0 ? 1 : 0}

    <%--5.判空运算符 如果empty判断后面的元素为空 则返回true 否则返回false--%>
    <%--判断请求参数中的username对应的value是否为空--%>
    <%--ps:如果这里的字符串长度为0,也会被empty判断为空 它类似StringUtils.isBlank();
    如果一个数组长度为0,empty认为不是空;
    如果一个集合(list等)长度为空,empty认为是空--%>
    ${empty param.username}
    <%--判断request域对象中的user对象是否为空--%>
    ${empty requestScope.user}


</body>
</html>

7.JSTL介绍和导入

目前我们的jsp文件上还是会有java代码,如果想要避免jsp文件上出现java代码,就要学习JSTL技术
认识JSTL
为什么需要学习JSTL?
通过之前的学习我们发现,就算在JSP中可以使用EL表达式取出域对象中的数据,但是仍然避免不了要在jsp页面中写一些java代码,这种嵌入JAVA代码的处理比较繁琐,容易出错,并且代码不容易维护。
什么是JSTL?
JSTL(Java server pages standard tag library,JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。
使用JSTL的好处:
开发人员可以利用JSTL和EL来开发Web程序,取代传统直接在页面上嵌入Java程序的做法,以提高程序的阅读性、维护性和方便性。在jstl中,提供了多套标签库,用于在jsp中完成相关操作。
JSTL标签库的组成部分:
1.核心标签库:core 简称c
2.格式化标签库:format 简称fmt
3.函数标签库:function 简称fn
JSTL的使用前提
1.需要在项目中导入jstl-1.2.jar,jstl在后台由java代码编写,jsp页面中通过标签进行使用,使用标签时,会自动调用后台的java方法
2.标签和方法之间的映射文件在对应的tld文件中进行描述,需要在页面中通过taglib指令引入对应的标签库,uri可以在对应的tld文件中找到

简而言之一句话就是用标签替换java代码

8.MVC模式概念引入

什么是MVC?
MVC是一种项目架构模式,它本身并不引入新的功能,只是用来指导我们改善应用程序的架构,使得应用的模型和视图相分离,从而得到更好的开发和维护效率。
在MVC模式中,应用程序被划分成了模型层(Model)、视图层(View)和控制器(Controller)三个部分。其中,模型部分包含了应用程序的业务逻辑和业务数据;视图部分封装了应用程序的输出形式,也就是通常所说的页面或者是界面;而控制器层负责协调模型和视图,根据用户请求来选择要调用哪个模型来处理业务,以及最终由哪个视图为用户做出应答。
MVC模式的这三个部分的指责非常明确,并且相互分离,因此每个部分都可以独立的改变而不影响其他部分,从而大大提高了应用的灵活性和重用性。
MVC模式的优势:
1.耦合性低
视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。
2.重用性高
MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型,它包括任何WEB(HTTP)浏览器或者无线浏览器(wap)。比如,用户可以通过电脑或者手机来订购某样产品,虽然订购的方式不一样,但是处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。
MVC使开发和维护用户接口的技术含量降低。
3.开发效率提高,人员职责明确
使用MVC模式使开发时间得到较大的缩减,它使程序员集中精力于业务逻辑,前端程序员集中精力于表现形式上。
4.耦合度低,可维护性高

MVC分层结构:
MVC项目分层结构1
MVC项目分层结构2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值