Day01.    JSP

 

1   JSP概述

1.1 JSP介绍

JSPServlet都是SUN公司提供的两门动态Web资源开发技术

JSP看起来像一个HTML,但是和HTML不同的是,JSP中可以书写Java代码,可以通过Java代码获取动态的数据。

JSP本质上是一个Servlet。(JSP在第一次被访问时会翻译成一个Servlet.

JSP的出现是为了解决Servlet不适合向外(浏览器)输出一个完整的html网页。同时也解决了html无法展示动态数据的问题。

1.2 JSP执行过程

1html的执行过程

localhost/day11/1.jpg

localhost/day11/index.html

当浏览器访问服务器中的一个html网页文件时,服务器此时会调用一个默认的ServletDefaultServlet,tomcat提供)。

这个默认的Servlet会根据请求的路径,到web应用中(day11)去寻找指定名称的文件,如果找到就直接将这个文件的内容作为响应实体发送给浏览器,由浏览器负责解析并显示。

如果找不到,就响应一个404页面

 

2JSP的执行过程:

当浏览器发送请求访问服务器中的一个JSP文件时,根据请求的路径到Web应用中寻找指定名称的JSP文件,找到后,如果是第一次被访问,这个JSP会首先翻译为一个Servlet程序。接着服务器会执行这个Servlet程序,执行的最终结果是向浏览器响应一个html网页。

访问一个JSP后在浏览器中看到的网页,其实是JSP翻译后的Servlet通过out.write一行一行输出的结果。

1.3 修改JSP模版

修改JSP模版步骤: 点击菜单栏中的 window --> Preferences,出现如下窗口:

点击edit编辑JSP模版,修改为如下:

<%@ page language="java" pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8"/>

    <title></title>

</head>

<body>

    ${cursor}

</body>

</html>

2   JSP语法

2.1 模版元素

模板元素其实是指:写在JSP中的html内容都称之为模板元素

除了JSP特有的内容以外的其他内容都是模板元素

只要是模板元素,浏览器都可以解析,因此模板元素在翻译后的Servlet中,是被out.write()直接发送给浏览器,由浏览器负责解析并显示。

out.write("\r\n");

out.write("\r\n");

out.write("<!DOCTYPE html>\r\n");

out.write("<html>\r\n");

out.write("<head>\r\n");

out.write("<meta charset=\"UTF-8\">\r\n");

out.write("<title>Insert title here</title>\r\n");

out.write("</head>\r\n");

。。。

2.2 JSP表达式

格式: <%= 表达式内容 %>   

其中可以存放 常量、变量、表达式(不能存放语句,不能写分号)

作用:在翻译后的Servlet中,会执行(计算)表达式内容,将执行的结果再发送给浏览器,由浏览器解析并显示

JSP中的代码:

    <%= "Hello JSP" %>  

    Hello JSP

    <%= 123+345 %>

    <% String str = "Hello CGB1907..."; %>

    <%= str %>

浏览器中的结果:

2.3 JSP脚本片段

格式: <% 若干Java语句 %>

作用: 在翻译后的Servlet, 将脚本片段符号中的Java语句, 复制粘贴到对应的位置执行。

    <!-- 1~100之间所有整数的和 -->

    <%

       int sum = 0;

       for(int i=1;i<=100;i++){

           sum += i;

       }

       out.write( "1~100之间所有整数的和为:"+sum );

    %>

 

JSP文件中:

    <!-- 输出5"Hello JSP" -->

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

           Hello JSP<br/>

    <% } %>

在翻译后的Servlet中:

通过上面的示例, 可以得出结论, 在某一个脚本片段中的Java语句可以是不完整的, 但是整体的Java代码必须是完整符合Java语法的!

 

2.4 JSP注释

格式:<%-- 注释内容 --%>

作用:(1)为代码添加解释说明。

(2)将一些暂时不需要执行的代码注释

JSP注释在JSP翻译为Servlet时,直接被抛弃,不予翻译(所以在翻译后的Servlet中,以及浏览器的源码中都看不到JSP注释。)

    <% String name = "韩少云"; %>

    <% //name="马云"; %>

    <%= name %>

    <hr/>

   

    <%-- <%= "aaa" %> --%><br/>

    <!-- <%= "bbb" %> --><br/>

    <%= "ccc" %><br/>

2.5 JSP指令

指令:是用于指挥JSP解析引擎如何翻译一个JSP文件。

常见的指令page指令、include指令、taglib指令等。

2.5.1    page指令

page指令的作用的用于声明JSP的基本属性信息(比如JSP文件使用的编码、JSP文件使用的开发语言等)

格式:<%@ page 若干属性声明... %>

<%@ page import="java.util.Date"%>

-- import是用于导包用的

<%@ page pageEncoding="UTF-8"%>

-- 用于指定JSP文件所使用的编码, JSP解析引擎在将一个JSP翻译为Servlet, 将会使用pageEncoding所指令的编码来进行翻译

如果JSP文件另存时使用的编码和pageEncoding指定的编码不同, 就可能会出现中文乱码问题!!

<%@ page language="java"%>

-- 指定JSP默认使用的开发语言是Java

2.5.2    taglib指令

用于引入JSP的标签库技术(JSTL标签库、自定义的标签库)

在使用JSTL标签库之前,需要导入JSTL的开发包,并且需要在JSP文件中通过taglib指令引入JSTL标签库。

后面讲解。

3   JSP标签技术

JSP页面中写入大量的java代码会导致JSP页面中html代码和java代码混杂在一起,会造成页面非常的混乱,难于维护。

于是在JSP2.0版本中,sun提出了JSP标签技术,推荐使用标签来代替JSP页面中java代码,并且推荐,JSP2.0以后不要在JSP页面中出现任何一行java代码。

 

3.1 EL表达式

格式: ${ 常量/表达式/变量 }

其中的变量必须得先存入域中,才可以通过EL进行获取。

主要作用是用于从四大作用域获取数据/属性值

四大作用域(pageContextrequestsessionapplication

用法示例:

 

1、获取常量、表达式或变量的值(变量必须得先存入域中)

${ 123 } ${ "abc" }   <br/>

${ 123+123 }             <br/>

${ 23*45 > 899 ? "yes" : "no" }  <br/>

 

<% String name = "林青霞"; %>

${ name }

如果在EL中书写了一个变量,EL底层会根据变量的名字,到四大作用域中寻找该名字的属性值,找到就返回属性值并输出到当前位置,如果找不到,就什么也不输出。

从四大作用域寻找的顺序是,按照作用域的大小范围,从最小的域依次到最大的域(pageContextrequestsessionapplication

上面的代码运行结果是:什么也没有输出

 

2、获取域中的数组或集合中的元素

servlet中的代码:

//声明一个数组,并将数组存入到域中

String[] names = {"陈子枢","齐雷","王海涛","张久军"};

request.setAttribute("ns", names);

//声明一个集合,并将集合存入到域中

List list1 = new ArrayList();

list1.add("陈子枢");

list1.add("齐雷");

list1.add("王海涛");

list1.add("张久军");

request.setAttribute("list", list1);

//将请求转发到el.jsp,将集合取出显示在JSP

request.getRequestDispatcher("el.jsp")

    .forward(request, response);

jsp中的代码:

${ list[0] }

${ list[1] }

${ list[2] }

${ list[3] }

<hr/>

${ ns[0] }

${ ns[1] }

${ ns[2] }

${ ns[3] }

 

3、获取域中的map集合中的元素

servlet中的代码:

//声明一个map集合,并将map集合存入到域中

Map map = new HashMap();

map.put("name", "阿凡提");

map.put("addr", "北京");

map.put("age", "28");

request.setAttribute("map", map);

 

//将请求转发到el.jsp,将集合取出显示在JSP

request.getRequestDispatcher("el.jsp")

    .forward(request, response);

jsp中的代码:

<h2>3、获取域中的map集合中的元素</h2>

${ map.name }

${ map.addr }

${ map.age }

 

4、获取域中的pojo对象中的属性。

servlet中的代码:

//声明一个User对象(pojo)将user对象存入域中

User u1 = new User();

u1.setName("阿凡达");

u1.setAge( 30 );

u1.setAddr( "河北" );

request.setAttribute( "user", u1 );

 

//将请求转发到el.jsp,将集合取出显示在JSP

request.getRequestDispatcher("el.jsp")

    .forward(request, response);

jsp中的代码:

${ user.getName() }

${ user.getAge() }

${ user.getAddr() }

<hr/>

${ user.name }

${ user.age }

${ user.addr }

3.2 JSTL标签库

JSTL标签库是为JavaWeb开发人员提供的一套标准通用的标签库;

JSTL标签库和EL配合使用取代JSP中大部分的Java代码;

(1)导入JSTL的开发包

(2)在使用JSTLjsp中引入JSTL标签库

 

其中常用的标签如下:

1<c:set></c:set> -- 往四大作用域中添加域属性,或者修改四大作用域中已有的属性

(1) 往四大作用域中添加一个域属性

<c:set var="name"  value="张三" scope="request"/>

${ name }  <!-- 输出张三 -->

(2) 修改四大作用域中已有的属性

如果重复添加相同的属性,值会发生覆盖,相当于修改.

<c:set var="name"  value="张三丰" scope="request"/>

${ name }  <!-- 输出张三丰 -->

 

c_set标签属性总结:

(1)var -- 指定存入作用域中的属性名称

(2)value -- 指定存入作用域中属性的值

(3)scope -- 指定将属性存入哪一个作用域中

可取值: a)page表示pageContext  b)request表示request 

    c)session表示session  d)application表示ServletContext

 

2<c:if></c:if> -- 构造if…else…语句

<c:set var="score"  value="89"/>

<c:if test="${ score >= 80 }">优秀!</c:if>

<c:if test="${ score <80 and score >=60 }">中等!</c:if>

<c:if test="${ score < 60 }">不及格!</c:if>

test属性用于指定判断的条件,注意:JSTL中没有提供else对应的标签

 

3<c:forEach></c:forEach> -- 对集合或数组等中元素进行循环遍历或者是执行指定次数的循环.

(1) 遍历域中数组或集合中的元素

servlet中代码:

//声明一个集合,并将集合存入到域中

List<User> uList = new ArrayList();

uList.add( new User("张三", 20, "北京") );

uList.add( new User("李四", 24, "天津") );

uList.add( new User("王五", 26, "河北") );

uList.add( new User("赵六", 25, "上海") );

request.setAttribute( "list" ,  uList );

 

//通过转发将集合带到JSP, 取出并遍历集合中的元素

request.getRequestDispatcher("jstl.jsp")

           .forward(request, response);

jsp中代码:

<c:forEach items="${ list }"  var="user">

    ${ user }  <br/>

</c:forEach>

 

<table border="2" cellspacing="0" cellpadding="5">

    <c:forEach items="${ list }" var="user"

                      varStatus="status">

       <tr>

           <td>${ status.count }</td>

           <td>${ user.name }</td>

           <td>${ user.age  }</td>

           <td>${ user.addr }</td>

       </tr>

    </c:forEach>

</table>

(2) 遍历域中map集合中的元素

servlet中代码:

//声明一个map集合,并将map集合存入到域中

Map map = new HashMap();

map.put("name", "阿凡提");

map.put("addr", "北京");

map.put("age", "28");

request.setAttribute("map", map);

 

//通过转发将集合带到JSP, 取出并遍历集合中的元素

request.getRequestDispatcher("jstl.jsp").forward(request, response);

jsp中代码:

<c:forEach items="${ map }"  var="entry">

    ${ entry.key } : ${ entry.value } <br/>

</c:forEach>

(3) 遍历0~100之间的整数,将是7的倍数的数值输出到浏览器中

jsp中代码:

<%--

    varStatus: 表示循环遍历信息的对象, 具有的属性有:

       first: boolean, 表示当前遍历的是否是第一个元素

       last: boolean, 表示当前遍历的是否是最后一个元素

       count: int, 表示当前遍历的是第几个元素

 --%>

<c:forEach begin="0"  end="100"  var="i"

                            step="1"  varStatus="status">

    <c:if test="${ i%7 == 0 }">

       <c:if test="${ !status.first }">,</c:if>

       ${ i }

    </c:if>

</c:forEach>

c_forEach标签属性总结:

(1)items: 指定需要遍历的集合或数组

(2)var: 指定用于接收遍历过程中的元素

(3)begin: 指定循环从哪儿开始

(4)end: 指定循环到哪儿结束

(5)step: 指定循环时的步长, 默认值是1