JSP

JSP的基础语法

简介

​ JSP:Java Server Page SUN 公司提供的动态网页编程技术,是 Java Web 服务器端的动态资源。

​ 它相比 html 而言,html 只能为用户提供静态数据,而 Jsp 技术允许在页面中嵌套 java 代码,为用户提供动态数据。

​ 相比 servlet 而言,servlet 很难对数据进行排版,而 jsp 除了可以用 java 代码产生动态数据的同时,也很容易对数据进行排版。

​ 不管是 JSP 还是 Servlet,虽然都可以用于开发动态 web 资源。但由于这 2 门技术各自的特点,在长期的软件实践中,人们逐渐把 servlet 作为 web 应用中的控制器组件来使用, 而把 JSP 技术作为数据显示模板来使用。

​ 其实 Jsp 就是一个 Servlet,当我们第一次访问 Jsp 的时候,Jsp 引擎都会将这个 Jsp 翻译 成一个 Servlet,这个文件存放在tomcat(源码目录) 中的 work 目录中。N2UWPs.png

准备工作

配置IDEA

​ 这一步不是必须的,当然由于 编辑器中有些默认的配置项我们觉得不是很完美,比如"编码格式"、页面模板等。我们可以在新建 JSP 页面之前就先修改为我们需要的。

1.选择"File" —> "Settings..."

N2U4x0.png

2.设置编码格式。搜索"encode",选择"File Encoding"

[N2UqIJ.png

3.设置页面模板。搜索"template",选择"File and Code Templates",选择右侧的"Other",选择下方的"Jsp File"

N2UOi9.png

新建JSP页面

N2Uba4.png

注释

​ 在 JSP 中支持两种注释的语法操作:

​ 一种是显示注释,这种注释是允许客户端看见的; 另一种是隐式注释,此种注释是客户端无法看见的

​ ① 显示注释语法:从 HTML 风格继承而来

​ ② 隐式注释语法:从 JAVA 风格继承;JSP 自己的注释

​ JSP 的三种注释方式:

1) // 注释,单行注释  /* 多行注释*/ 

2)<!--  HTML风格的注释 -->

3)<%--   JSP注释  --%>

Scriptlet

​ 在 JSP 中最重要的部分就是 Scriptlet(脚本小程序),所有嵌入在 HTML 代码中的 Java 程序

​ 在 JSP 中一共有三种 Scriptlet 代码:都必须使用 Scriptlet 标记出来

第一种:<%    %>: java 脚本段,可以定义局部变量、编写语句

第二种:<%!   %>:声明,可以定义全局(成员)变量、方法、类

第三种:<%=  %>:表达式,数据一个变量或具体内容

​ 通过观察解析为 java 文件的 jsp 代码理解三种小脚本

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE >
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Scriptlet</title>
    </head>
    <body>
        <%
            String str = "Hello JSP";
            System.out.println(str);
            response.getWriter().write(str);
        %>
        <%!
            String memberStr = "a member String";
        %>
        <%=memberStr%>
        <h1>This is a JSP page!!</h1>
    </body>
</html>

JSP的指令标签

​ 使用包含操作,可以将一些重复的代码包含进来继续使用,从正常的页面组成来看,有时可能分为几个区域。而其中的一些区域可能是一直不需要改变的,改变的就其中的一个具体内容区域。现在有两种方法可以实现上述功能。

​ 方法一:在每个 JSP 页面(HTML)都包含工具栏、头部信息、尾部信息、具体内容

​ 方法二:将工具栏、头部信息、尾部信息都分成各个独立的文件,使用的时候直接导入

​ 很明显,第二种方法比第一种更好,第一种会存在很多重复的代码,并且修改很不方便,在 JSP 中如果要想实现包含的操作,有两种做法:静态包含动态包含,静态包含使用 include 指令即可,动态包含则需要使用 include 动作标签。

include 静态包含

<%@ include file="要包含的文件路径" %>  <!-- 相对路径 -->

例如:

<%@include file="include.jsp" %>
或
<%@include file="include.html" %>

​ 静态包含就是将内容进行了直接的替换,就好比程序中定义的变量一样,是在 servlet 引擎转译时,就把此文件内容包含了进去(两个文件的源代码整合到一起, 全部放到_jspService 方法中),所以只生成了一个 servlet,所以两个页面不能有同名的变量。 运行效率高一点点。耦合性较高,不够灵活。

include 动态包含

​ 动态包含在代码的编译阶段,包含和被包含部分是两个独立的部分,只有当运行时,才会动态包含进来,好比方法的调用。

<jsp:include page="include.jsp"></jsp:include>

注意:动态包含,中间不要加任何内容,包括空格,除非确认要使用参数,否则报错!

<jsp:include page="include.html"></jsp:include>
<%
    String a = "hello.jsp";
%>
<jsp:include page="<%=a %>"></jsp:include>

​ 使用动态包含还可以通过在页面之间传参。

​ 接收参数通过 request.getParameter(name);

<jsp:include page="hello.jsp" flush="true">
    <jsp:param name="uname" value="zhangsan"/>
</jsp:include>

​ hello.jsp

<!-- 接收参数 -->
<%=request.getParameter("uname")%>

JSP的四大域对象

四种属性范围

​ 在JSP中提供了四种属性的保存范围,所谓的属性保存范围,指的就是一个设置的对象,可以再多少个页面中保存并可以继续使用

  1. page范围

    ​ pageContext : 只在一个页面中保存属性,跳转之后无效

  2. request范围

    ​ request : 只在一次请求中保存,服务器跳转后依然有效

  3. session范围

    ​ session : 在一次会话范围中,无论何种跳转都可以使用

  4. application范围

    ​ application : 在整个服务器上保存

方法 类型 描述
public void setAttribute(String name, Object o) 普通 设置属性的名称及内容
public Object getAttribute(String name) 普通 根据属性名称取属性
public void removeAttribute(String name) 普通 删除指定的属性

验证属性范围的特点

  1. page

​ 本页面取得,服务器端跳转(<jsp :forward>)后无效

  1. request

    服务器跳转有效,客户端跳转无效

    如果是客户端跳转,则相当于发出了两次请求,那么第一次的请求将不存在了;如果希望不管是客户端还是服务器跳转,都能保存的话,就需要继续扩大范围。

  2. session

    无论客户端还是服务器端都可以取得,但是现在重新开启一个新的浏览器,则无法取得之前设置的session了,因为每一个session只保存在当前的浏览器当中,并在相关的页面取得。

    对于服务器而言,每一个连接到它的客户端都是一个session

    如果想要让属性设置一次之后,不管是否是新的浏览器打开都能取得则可以使用application

  3. application

    所有的application属性直接保存在服务器上,所有的用户(每一个session)都可以直接访问取得

    只要是通过application设置的属性,则所有的session都可以取得,表示公共的内容,但是如果此时服务器重启了,则无法取得了,因为关闭服务器后,所有的属性都消失了,所以需要重新设置。

问:使用哪个范围呢?

​ 答:<font color="red">在合理范围尽可能小</font>

EL表达式的使用

EL表达式的语法

​ EL(Expression Language) 是为了使 JSP 写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让 Jsp 的代码更加简化。

语法结构非常简单: ${expression}

​ EL 表达式一般操作的都是<font color="red">域对象中的数据</font>,操作不了局部变量。

​ 域对象的概念在 JSP 中一共有四个:pageContext, request, session, application;范围依次是,本页面一次请求一次会话整个应用程序

​ 当需要指定从某个特定的域对象中查找数据时可以使用四个域对象对应的空间对象,分别是:pageScope, requestScope, sessionScope, applicationScope。

​ 而 EL 默认的查找方式为从小到大查找,找到即可。当域对象全找完了还未找到则返回空字符串""。

EL表达式的使用

获取数据

设置域对象中的数据

<%
    pageContext.setAttribute("uname","zhangsan"); // page作用域
    request.setAttribute("uname","lisi"); // request作用域
    session.setAttribute("uname","wangwu"); // session作用域
    application.setAttribute("uname","zaholiu"); // application
%>

获取域对象的值

<%-- 获取域对象中的数据:默认查找方式为从小到大,找到即止。若四个范围都未找到,则返回空字符串。--%>
${uname} <!-- 输出结果为:zhangsan -->

获取指定域对象的值

${pageScope.uname}          <!-- page作用域 -->
${requestScope.uname}       <!-- request作用域 -->
${sessionScope.uname}       <!-- session作用域 -->
${applicationScope.uname}   <!-- application作用域 -->

获取List

<%
    List<String> list = new ArrayList<String>();
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    request.setAttribute("list", list);
%>
<%--
    获取List中指定下标的数据
        ${list[下标] }
    获取集合的长度
        ${list.size()}
    注:
       list代表的是存在域对象中的变量名(限域变量名)
--%>
${list[1] }  

获取Map

<%
    Map map = new HashMap();
    map.put("aaa", "111");
    map.put("bbb", 2222);
    map.put("ccc-a", 333);
    request.setAttribute("map", map);
%>
<%--
    获取Map中指定值
       ${map["key"] } 或 ${map.key }
    注:
        map代表的是存在域对象中的变量名(限域变量名)
--%>
${map.aaa }
${map["bbb"]}

获取JavaBean对象

User.java

public class User {

    private Integer userId;
    private String uname;
    private String upwd;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpwd() {
        return upwd;
    }

    public void setUpwd(String upwd) {
        this.upwd = upwd;
    }
}
<%
    User user = new User();
    user.setUserId(1);
    user.setUname("zhangsan");
    user.setUpwd("123456");
    request.setAttribute("user",user);
%>
<%-- JavBean中的属性字段需要提供get方法 --%>
${user} <%-- 获取对象 --%>
${user.uname} <%--获取对象中的属性--%>
empty
<%--
    empty
        判断域对象是否为空。为空,返回true;不为空返回false;
            ${empty 限域变量名 }
        判断对象是否不为空。
            ${!empty 限域变量名 }
--%>
${empty uname}
${empty list}
${empty map}
${empty user}
EL运算
<%
    request.setAttribute("a", 10);
    request.setAttribute("b", 2);
    request.setAttribute("c", "aa");
    request.setAttribute("d", "bb");
%>

等值判断

<%--
    比较两个值是否相等,返回true或false
        ==  或  eq
--%>
${a == b }
${c == d }
${c eq d }
${a == 5 }
${c == 'aa' }

算术运算

<%--
    加法: +
    减法: -
    乘法: *
    除法: / 或 div
--%>
${a + b }
${a / b } 或 ${a div b }

大小比较

<%--
    大于:>
    小于:<
    大于等于:>=
    小于等于:<=
--%>
${a > b}
${a + 1 > 10 }
${a + b >= 10 }
${a > b && b > 5 }
${a + b > 10 || a - b > 5 }

想要更多Java,前端,大数据,微服务等资料<a href="https://i.loli.net/2020/06/22/zbPOtKIqDjo45Mw.png">点我扫码领取</a>;