运行环境

系统:windows

服务器:Tomcat 8.0.50

IDEA:2021.3版本

目录

什么是jsp?

jsp页面的本质

 jsp头部page指令

jsp常用脚本

声明脚本

表达式脚本

代码脚本

jsp的常用标签

静态包含

动态包含

请求转发

EL表达式

使用EL表达式输出复杂的Bean对象

EL 表达式的 11 个隐含对象

JSTL标签库

core核心库的使用


什么是jsp?

jsp的全称是java server pages,java的服务器页面。

jsp的主要作用是代替Servlet程序回传html页面的数据。

jsp页面的本质

jsp页面的本质是一个Servlet程序。

当我们第一次访问jsp页面时,Tomcat服务器会帮我们把jsp页面翻译成为一个java源文件。并且对它进行编译成源文件。

jsp程序代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
这是一个jsp页面
</body>
</html>

通过跟踪本地编译路径发现jsp页面被编译成了java文件

有java 不能 jps java不出来_java

打开java文件,这个类继承了HttpJspBase类,而HttpJspBase类继承了HttpServlet类,所以jsp翻译出来的java类是一个Servlet程序。

有java 不能 jps java不出来_intellij-idea_02

 翻译出来的java类通过流的形式输出页面内容。

有java 不能 jps java不出来_java_03

 jsp头部page指令

1. language属性:表示jsp文件翻译后是什么语言文件,暂时只支持java。

2. contentType属性:表示jsp返回的数据类型是什么,源码当中response.setContentType()属性。

有java 不能 jps java不出来_intellij idea_04

3. pageEncoding属性: 表示当前jsp页面文件本身的字符集。

4. import属性:跟java源代码中一样,用于导包,导类。

5. autoFlush属性:设置当out输出流缓冲区满了之后,是否自动刷新缓冲区。默认值是true。

6. buffer属性:设置out缓冲区的大小,默认是8KB。

7. errorPage属性:设置当jsp页面运行时出错,自动跳转的错误页面路径。

8. isErrorPage属性:设置当前jsp页面是否是错误信息提示页面,默认是false。

9. session属性:设置访问当前jsp页面,是否会创建HttpSession对象,默认是true。

10. extends属性:设置jsp翻译出来的java类默认继承谁。(除非必须。默认不修改)

有java 不能 jps java不出来_intellij-idea_05

jsp常用脚本

声明脚本

作用:可以给jsp翻译出来的java类定义属性、方法、静态代码块、内部类等。

格式:<%!     内容     %>

jsp程序代码

<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%!
    //声明属性
    private String id;
    private String name;
    private static ArrayList<Integer> arrayList;

    //声明静态代码块
    static {
        arrayList=new ArrayList<Integer>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
    }

    //声明方法
    public int add(int a, int b) {
        return a + b;
    }

    //声明内部类
    public static class student {
        private String name;
        private String number;
    }
%>
</body>
</html>

翻译过后的java文件新增内容

有java 不能 jps java不出来_intellij idea_06

表达式脚本

作用:可以在jsp页面上输出数据。

格式:<%=     内容     %>

在声明脚本的基础上输出数据

<%--输出整数--%>
<%=10%><br>

<%--输出浮点数--%>
<%=10.1234%><br/>

<%--输出字符串--%>
<%="这是一个字符串"%><br>

<%--输出对象--%>
<%=arrayList%><br>

页面显示内容

有java 不能 jps java不出来_java_07

我们并没有写页面的代码,却在网页上显示出来了对应的数据。通过查看翻译后的java源文件代码发现,上面所写的代码在源文件的_jspService方法当中被翻译成了页面。

有java 不能 jps java不出来_intellij-idea_08

代码脚本

作用:可以在jsp页面中用java语言编写需要的功能。

格式:<%     内容     %>

特点:(1)代码脚本翻译后在_jspService方法中,所以这个方法当中的对象和属性等都可以直接使用。

           (2)可以由多个代码脚本块组合完成一个完整的java语句,因为他们都是放在_jspService方法当中。

           (3)代码脚本可以和表达式脚本组合使用,在jsp页面上输出数据。

代码脚本简单样例:求20以内的素数

<%
    for (int i = 2; i < 20; i++) {
        boolean isPrime = true;
        for (int j = 2; j <= Math.sqrt(i); j++) {
            if (i % j == 0) {
                isPrime = false;
                break;
            }
        }
        if (isPrime == true)
            System.out.println(i);
    }
%>

查看翻译后的java源代码发现上面写的代码被添加在_jspService方法当中,所以我们编写代码脚本相当于是在这个方法当中编写,既然是在这个方法当中编写,那么这个方法内的参数、对象等我们都可以在代码脚本当中使用。 

多个代码脚本块组合完成一个完整的java语句样例

<%for (int i = 0; i < 12; i++) {%>
    <%System.out.println(i);%>
<%}%>

 代码脚本可以和表达式脚本组合使用,在jsp页面上输出数据样例

<%for (int i = 0; i < 5; i++) {%>
    <%=i%>
<%}%>

页面显示内容

有java 不能 jps java不出来_jsp页面_09

 综合运用样例:输出10×10的表格

<table border="1">
    <%for (int i = 1; i <= 10; i++) {%>
    <tr>
        <%for (int j = 1; j <= 10; j++) {%>
        <td>(<%=i%>,<%=j%>)</td>
        <%}%>
    </tr>
    <%}%>
</table>

显示效果

有java 不能 jps java不出来_intellij-idea_10

 输出10组学生信息

<%--css样式--%>
<%--table {--%>
<%--border: 1px red solid;--%>
<%--width: 600px;--%>
<%--border-collapse: collapse;--%>
<%--}--%>
<%
    List<Student> students = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        students.add(new Student("name" + i, i, i + 18, "000" + i));
    }
%>
<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>编号</td>
        <td>电话号码</td>
        <td>操作</td>
    </tr>
    <% for (Student student : students) {%>
    <tr>
        <td><%=student.getName()%>
        </td>
        <td><%=student.getAge()%>
        </td>
        <td><%=student.getId()%>
        </td>
        <td><%=student.getPhone()%>
        </td>
        <td>删除、修改</td>
    </tr>
    <%}%>

显示效果

有java 不能 jps java不出来_有java 不能 jps_11

代码脚本的使用非常的灵活,通过对代码脚本和表达式脚本的灵活使用,可以实现很多功能。

jsp的常用标签

静态包含

特点:(1)静态包含不会翻译被包含的jsp页面。

           (2)静态包含是将被包含的jsp页面代码拷贝到包含的位置执行输出。

当很多网页都具有相同的内容时,如果我们要修改这一部分内容,那么修改起来就显得很麻烦。如果将这一部分内容写成jsp页面代码,然后包含到不同的网页当中。我们只需要修改这一部分对应的jsp页面代码就可以对所有使用这一部分内容的页面进行修改。

简单样例

主页代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
用户名:<input type="text">
密码:<input type="password"><br>
<%--file属性指定包含的jsp页面的路径--%>
<%@ include file="/footer.jsp" %>
</body>
</html>

包含页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
合作伙伴:A公司、B公司、C公司
</body>
</html>

页面显示内容

有java 不能 jps java不出来_jsp页面_12

动态包含

特点:(1)动态包含会将包含的jsp页面翻译成java代码。

           (2)动态包含是通过代码org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "footer.jsp", out, false)来调用被包含的jsp页面执行输出。

           (3)动态包含可以传递参数。

样例主页代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
用户名:<input type="text">
密码:<input type="password"><br>
<jsp:include page="footer.jsp">
    <jsp:param name="username" value="root"/><!--传递参数-->
    <jsp:param name="password" value="654321"/>
</jsp:include>
</body>
</html>

被包含的页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
合作伙伴:A公司、B公司、C公司<br>
用户名=<%=request.getParameter("username")%><!--获取参数-->
密码=<%=request.getParameter("password")%>
</body>
</html>

页面显示内容

有java 不能 jps java不出来_java_13

请求转发

因为jsp本质上是一个Servlet程序,所以依然可以使用Servlet的请求转发方式。

Servlet程序请求转发写法

<%
    request.getRequestDispatcher("/dtbh.jsp").forward(request,response);
%>

jsp请求转发写法

<jsp:forward page="dtbh.jsp"></jsp:forward>

实际使用方式

实际情况下在Servlet程序当中查找到了对应的数据,通过jsp页面显示出来。所以之前的示例输出10组学生信息应当这么写。

Servlet程序代码

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数
        //发送sql语句查询学生的信息,使用循环代替
        System.out.println("DoGet");
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            students.add(new Student("name" + i, i, i + 18, "000" + i));
        }
        //保存查询到的结果到request域中
        req.setAttribute("students", students);
        //请求转发到showStudent.jsp当中
        req.getRequestDispatcher("showStudent.jsp").forward(req, resp);

    }

jsp程序代码中代码脚本修改为直接获取信息即可

<%
    List<Student> students = (List<Student>) request.getAttribute("students");
%>

EL表达式

EL表达式的全称是:Ecpression Language。是表达式语言。

EL表达式的作用:EL表达式主要用来代替jsp页面的表达式脚本在jsp页面中进行数据的输出,EL表达式在输出数据的时候,要比jsp的表达式脚本要简洁。

EL表达式输出和表达式脚本输出代码对比

<%
    request.setAttribute("key", "值");
%>
表达式脚本输出key的值:<%= request.getAttribute("key1")%><br/>
EL表达式输出key的值:${key1}

可以发现EL表达式代码简洁明了得多。

使用EL表达式输出复杂的Bean对象

创建一个Person类自动生成get和set方法,有如下属性

有java 不能 jps java不出来_jsp页面_14

 代码脚本内容

<%
    Person person = new Person();
    person.setName("小红");
    person.setPhones(new String[]{"11111", "22222", "33333"});
    List<String> list = Arrays.asList(new String[]{"重庆", "西藏", "北京"});
    person.setCities(list);
    Map<String, Object> map = new HashMap<>();
    map.put("key1", "value1");
    map.put("key2", "value2");
    map.put("key3", "value3");
    person.setMap(map);
    pageContext.setAttribute("person", person);
%>

EL表达式代码

姓名:${person.name}<br/>
第二个电话:${person.phones[1]}<br/>
城市:${person.cities}<br/>
第二个城市:${person.cities[1]}<br/>
Map:${person.map}<br/>
key2的值:${person.map.key2}<br/>

显示结果

有java 不能 jps java不出来_有java 不能 jps_15

EL表达式中的运算和java中的运算大同小异,同样也支持三元运算符。

EL 表达式的 11 个隐含对象

EL表达式中的11个隐含对象,是 EL 表达式中自己定义的,可以直接使用。

有java 不能 jps java不出来_intellij idea_16

 如果有多个域当中有相同的key值,那么我们要获取特定域中的key对应的value,应当指定是从哪个域中获取,如下所示:

<%
    pageContext.setAttribute("key", "pageContext");
    request.setAttribute("key", "request");
    session.setAttribute("key", "session");
    application.setAttribute("key", "application");
%>
${requestScope.key}

JSTL标签库

JSTL标签库全称是JSP standard Tag Library。是一个不断完善的开源的JSP标签库。

JSTL标签库主要用于替代代码脚本,使得整个jsp页面变得更加简洁。

使用标签库之前要导入jar包。

core核心库的使用

 <c:set />标签:往域中保存数据

<%--scope设置保存到哪个域--%>
<c:set scope="request" var="key1" value="value1"/>
${requestScope.key1}

<c:if />标签:用作if条件判断

<c:if test="${12==12}">
    true        <%--条件为真时的逻辑--%>
</c:if>

<c:choose><c:when><c:otherwise>标签:用作多路判断,类似于swich...case...default

<%request.setAttribute("number", 200);%>

<c:choose>
    <c:when test="${requestScope.number>190}">
        <h1>大于190</h1>
    </c:when>
    <c:when test="${requestScope.number>180}">
        <h1>大于180</h1>
    </c:when>
    <c:when test="${requestScope.number>170}">
        <h1>大于170</h1>
    </c:when>
    <c:otherwise>
        <h1>小于等于170</h1>
    </c:otherwise>
</c:choose>

<c:forEach / >标签:用作遍历输出

<%--用forEach标签打印九九乘法表--%>
<table border="1">
    <c:forEach begin="1" end="9" var="i">
        <tr>
            <c:forEach begin="1" end="${i}" var="j">
                <td><c:out value="${j }*${i }=${j*i }"></c:out></td>
            </c:forEach>
        </tr>
    </c:forEach>
</table>


<%--用forEach标签遍历字符串数组--%>
<%request.setAttribute("arr", new String[]{"11111", "22222", "33333"});%>
<c:forEach items="${requestScope.arr}" var="item">
    ${item}
</c:forEach>
<br/>


<%--用forEach标签遍历Map--%>
<%
    Map<String, Object> map = new HashMap<>();
    map.put("key1", "value1");
    map.put("key2", "value2");
    map.put("key3", "value3");
    request.setAttribute("map", map);
//    原生java遍历方式
//    for (Map.Entry<String, Object> entry : map.entrySet()) {
//        System.out.println(entry.getKey() + "  " + entry.getValue());
//    }
%>
<c:forEach items="${requestScope.map}" var="entry">
    ${entry}<br/>
</c:forEach>


<%--用forEach标签遍历List集合--%>
<%
    List<Student> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(new Student("name" + i, 12 + i, "location" + i, "phone" + i, 2022 + i));
    }
    request.setAttribute("students", list);
%>
<table border="1">
    <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>地址</th>
        <th>电话</th>
        <th>编号</th>
    </tr>
    <%--
    begin   表示开始的下标,默认开头
    end     表示结束的下标,默认结尾
    step    表示步长,默认为1
    items   表示遍历的集合
    var     表示当前遍历到的数据
    --%>
    <c:forEach begin="2" end="7" step="2" items="${requestScope.students}" var="student">
        <tr>
            <th>${student.name}</th>
            <th>${student.age}</th>
            <th>${student.location}</th>
            <th>${student.phone}</th>
            <th>${student.id}</th>
        </tr>
    </c:forEach>
</table>

显示效果

有java 不能 jps java不出来_java_17