JSP 技术知识点总结

目录

一.什么是 JSP

二.JSP 调用和运行原理(简略版)

三.JSP语法

四.JSP 指令-Page指令

五.JSP 指令-Include指令

六.JSP 指令-taglib指令

七.JSP 动作

八.JSP九大内置对象

九.JSP九大内置对象-PageContext对象

十.JSTL标签

1、什么是JSTL?

2、JSTL标签库:

3、使用taglib指令导入标签库:

4、core标签库常用标签:

(1)out和set标签

(2)remove标签

(3)url标签:该标签会在需要重写URL时添加。

(4)if标签:

(5)choose标签:

(6)forEach标签:

5、fmt标签库常用标签:

十一.EL表达式介绍

1.EL表达式查找顺序

2.EL表达式的隐性变量

3.EL常用操作

十二.表单提交使用的编码

十三.JSP 调用和运行原理(详细版)


一.什么是 JSP

JSP全称是 java servlet pages,它和 servlet 技术一样,都是Sun公司定义的一种用于开发动态web页面的技术

  • 为什么jsp也是一种动态web资源的开发技术呢?

       写jsp,虽然就像是在写HTML,但是jsp允许在页面中编写java代码,并且允许开发人员在页面中获取requestresponse等               web 开发常用对象,实现与浏览器的交互,所以jsp也是一种动态web资源的开发技术;

       例子:输出当前时间

Date date = new Date();
//这个out对象是可以直接使用的,它是JspWriter的实例
out.write(date.toLocaleString());

二.JSP 调用和运行原理(简略版)

浏览器访问 jsp 页面时,Web 服务器是如何调用并执行一个jsp页面的? 

首先知道,我们访问服务器的资源时,无论访问的是什么?比如访问的是HTML、jsp,其实我们访问的都是一个servlet,而不是真正的jsp、html ,因此,我们访问 jsp 其实就是去访问 servlet ;

Jsp在被访问的时候,服务器会将它 翻译为 servlet,转换后的servlet,被保存在服务器目录下的work/项目名/apache/…

提问:

  • web 服务器在执行jsp页面时,是如何把jsp页面中的HTML排版标签输出给浏览器的?

     这里其实是 jsp 对应的 servlet 的功劳,我们知道服务器会将jsp转为一个servlet 对象,我们去访问jsp的时候,实际访问到的也         是这个servlet对象;

    在这个servlet对象对应的类中。它是通过out.writer()语句将 jsp 中的 HTML 语句,原封不动的打给浏览器;遇到<%java代                码%>,就直接执行;

  • jsp页面中的java代码,服务器是如何执行的?

      是原封不动的,代码最后都在在servlet类中执行了;

  • Web服务器在调用jsp时,会给jsp提供一些什么java对象?

      会提供许多对象;request、response、out、application、session等这些对象,在jsp中是直接可以使用的,因为在jsp对应的          servlet类中已经提供好了; 
      如果想要获得jsp对应的servlet类的对象的自身,使用page,也是它内置提供的;

上面的几个问题,其实都可以翻看对应的 servlet 类的源码,,找到答案;

三.JSP语法

JSP模板元素

Jsp 页面中的 HTML 内容称之为 jsp 模板元素。Jsp的模板元素定义了网页的基本骨架,即定义了页面的结构和外观;

JSP脚本表达式

语法:<%= xxxx %> 输出代码块,用于向JSP页面输出内容,只能写在一行;用out.print(...),将数据输出给客户端。

Jsp脚本片段

语法: <%多行java代码%>
java代码块,可以在其中编写任何java代码,该代码块最终被原封不动的放到 servlet 的 _jspService 方法中。

Jsp声明

语法:<%! java代码 %>  声明代码块,用于声明全局变量或方法,但是一般没啥人使用这个技术;

Jsp注释

格式:<%-- 注释信息 --%>

Jsp指令

jsp指令 是为 jsp引擎 而设计的。它们并不直接产生任何可见输出,而只是告诉引擎如何处理jsp页面中的其余部分。 
在jsp2.0规范中共定义3个指令:
page指令   Include指令   taglib指令


四.JSP 指令-Page指令

page指令用于定义jsp页面的各种属性,无论page指令出现在jsp页面中的什么地方,它作用的都是整个jsp页面;

为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个jsp页面的初始位置。

Jsp2.0规范中定义的 page指令 的完整语法:

五.JSP 指令-Include指令

include 指令用于引入 jsp 页面,如果使用 include 引入其他 jsp 页面,那么 jsp 引擎将把这两个jsp翻译为一个servlet,所以,include指令引入通常也称为 静态导入

<%@include file="footer.jsp"%>
被导入的页面,不要包含HTML语句了,否则页面将不是一个完成的页面,会出现两个 <head> 这样的标签;

动态包含

语法: request.getRequestDispatcher("url").include(request,response);
这是在运行时包含,会将 每一个 jsp 都对应生成一个servlet,也就是最终生成不止一个 servlet 

我们一般选择静态导入,性能高 ;

六.JSP 指令-taglib指令

看下面的标签库.

七.JSP 动作

JSP中有3个动作标识:

1.<jsp:include>

    动态包含,用于将一个JSP页面包含在当前页面中。所谓动态包含指的是,被包含页面经编译后呈现在当前页面中,包含页面与      被包含页面各自生成一个Servlet。

2.<jsp:forward>

    用于页面跳转(服务器内部跳转)。

3.<jsp:param>

    与<jsp:forward>标识结合使用,用于在页面跳转时传递请求参数


// 动态包含
<jsp:include page=""> </jsp:include>  

 //跳转页面
<jsp:forward page="">    

// 负责带数据到另一个JSP页面中,value的值,可以是脚本表达式
// 一般和包含include便签一起使用
 <jsp:param name="" value=""></jsp:param>

// 将数据带到xxx.jsp 中
<jsp:include page="xxxx.jsp">  
    <jsp:param name="xxx" value="xxx"/>  
</jsp:include> 

八.JSP九大内置对象

JSP引擎 在调用 JSP 对应的 _JspServlet 时,会 传递或创建 9个与WEB开发相关的对象供_JspServlet使用。

JSP技术的设计者为了方便web开发人员在编写JSP页面时,获得这些对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这9个变量就可以快速的获得这9大对象的引用;

这九大隐式对象就是:responserequestsessionapplication(ServletContext)page (jsp对象自身)config(servlertConfig)exceptionout(JspWriter)PageContext

前面7个,在学JSP之前,都已经学过了,这里重点讲最后两个;

Out隐式对象

作用Out隐式对象 用于向客户端发送文本数据;

Out对象 是通过调用 PageContext 对象的 getOut() 方法返回的,其作用和用法与servletResponse.getWriter方法返回的 PrintWriter 对象非常相似。

九.JSP九大内置对象-PageContext对象

是jsp技术中最重要的一个对象,它代表jsp页面的运行环境;生命周期是一个jsp页面;

这个对象自身就封装可其他8大隐式对象的引用;(这个最厉害了)

它自身还是一个域对象,可以用来保存数据;

这个对象中,还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其他资源、检索其他域对象中的属性;


1.通过PageContext对象获得其他对象

通过 getXXX()方法;

PageContext对象中包含其他8大隐式对象的引用;

<%
    pageContext.getPage();
    pageContext.getRequest();
    pageContext.getResponse();
    pageContext.getSession();
    pageContext.getServletContext();
    pageContext.getServletConfig();
    pageContext.getOut();
    pageContext.getException();
%>

2.PageContext域的方法

javaweb四大域

获取数据
pageContext.getAttribute(String) ;

设置数据
pageContext.setAttribute(String,String);

移除数据
pageContext.removeAttribute(String);


//设置和获取其他域的数据
获取id对应的域的数据
pageContext.getAttribute(String,id) ; 
pageContext.setAttribute("name","joe",PageContext.REQUEST_SCOPE);

设置id对应的域数据
pageContext.setAttribute(String,String,id);

移除id对应的域数据
pageContext.removeAttribute(String,id);

PageContext查找属性的方法
pageContext.findAttribute(String)
用于查找某个属性的属性值,它会依次从page、request、session、application四个域,从小到大的查找,在某个域中查到数据,即刻返回这个数据,不会再继续查下去。如果四个域都没查到,则返回null;
这个方法,便利于我们可以在jsp中直接使用这个方法来查找数据,而不要去关注数据在哪一个域中;

3.引入和跳转到其他资源

PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher(...).forward方法和RequestDispatcher(...).include方法。

原始的操作

// forward
request.getRequestDispatcher("/xxx").forward(request, response);
// include
request.getRequestDispatcher("/xxx").include(request, response);

使用pageContext简化:

// forward
pageContext.forward("/xxx");
// include
pageContext.include("/xxxx");
方法接受的资源如果以 / 开头,/ 代表当前web应用;

十.JSTL标签

1、什么是JSTL?

JSTL JSP Standard Tag Library 标准标签库 
JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是JSP内置的标签,需要我们自己导包,以及指定标签库而已!

2、JSTL标签库:

JSTL一共包含四大标签库:

  • core:核心标签库,我们学习的重点;
  • fmt:格式化标签库,只需要学习两个标签即可;
  • sql:数据库标签库,不需要学习了,它过时了;
  • xml:xml标签库,不需要学习了,它过时了。

3、使用taglib指令导入标签库:

除了JSP动作标签外,使用其他第三方的标签库都需要:

  • 导包;
  • 在使用标签的JSP页面中使用taglib指令导入标签库;

下面是导入JSTL的core标签库:

<%@ taglib prefix="c"uri="http://java.sun.com/jstl/core" %>
  • prefix="c":指定标签库的前缀,这个前缀可以随便给值,但大家都会在使用core标签库时指定前缀为c;
  • uri="http://java.sun.com/jstl/core":指定标签库的uri,它不一定是真实存在的网址,但它可以让JSP找到标签库的描述文件;

4、core标签库常用标签:

(1)out和set标签

<c:out value=”aaa”/> 输出aaa字符串常量

<c:out value=”${aaa}”/> 与${aaa}相同

<c:out value=”${aaa}” default=”xxx”/> 当${aaa}不存在时,输出xxx字符串


<c:set var=”a” value=”hello”/> 在pageContext中添加name为a,value为hello的数据。

<c:set var=”a” value=”hello” scope=”session”/> 在session中添加name为a,value为hello的数据。

(2)remove标签

<%

    pageContext.setAttribute("a","pageContext");

    request.setAttribute("a","session");

    session.setAttribute("a","session");

    application.setAttribute("a","application");

%>

<c: remove var="a"/> 删除所有域中name为a的数据!

<c:remove var="a" scope=”page”/>	删除pageContext中name为a的数据 

(3)url标签:该标签会在需要重写URL时添加。

<c:url value="/"/> 输出上下文路径:/项目名/

<c:url value="/" var="a" scope="request"/> 把本该输出的结果赋给变量a。范围为request

<c:url value="/AServlet"/> 输出:/项目名/AServlet


输出:/项目名/AServlet?username=abc&password=123 如果参数中包含中文,那么会自动使用URL编码! 
<c:url value="/AServlet">
  <c:param name="username" value="abc"/>
  <c:param name="password" value="123"/>   
</c:url>                

(4)if标签:

    if标签的test属性必须是一个boolean类型的值,如果test的值为true,那么执行if标签的内容,否则不执行。

<c:set var="a" value="hello"/>
<c:if test="${not empty a }">
	<c:out value="${a }"/>
</c:if>

(5)choose标签:

choose标签对应Java中的if/else if/else结构。when标签的test为true时,会执行这个when的内容。当所有when标签的test都为false时,才会执行otherwise标签的内容。

<c:set var="score" value="${param.score }"/>
<c:choose>
	<c:when test="${score > 100 || score < 0}">错误的分数:${score }</c:when>
	<c:when test="${score >= 90 }">A级</c:when>
	<c:when test="${score >= 80 }">B级</c:when>
	<c:when test="${score >= 70 }">C级</c:when>
	<c:when test="${score >= 60 }">D级</c:when>
	<c:otherwise>E级</c:otherwise>
</c:choose>

(6)forEach标签:

forEach当前就是循环标签了,forEach标签有多种两种使用方式:

  • 使用循环变量,指定开始和结束值,类似for(int i = 1; i <= 10; i++) {};
  • 循环遍历集合,类似for(Object o : 集合);

循环变量:

<c:set var="sum" value="0" /> 
<c:forEach var="i" begin="1" end="10"> 
	<c:set var="sum" value="${sum + i}" /> 
</c:forEach>
<c:out value="sum = ${sum }"/>

<c:set var="sum" value="0" />
<c:forEach var="i" begin="1" end="10" step ="2">
	<c:set var="sum" value="${sum + i}" />
</c:forEach>
<c:out value="sum = ${sum }"/>

遍历集合或数组方式:

<%
String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
	<c:out value="name: ${item }"/><br/>
</c:forEach>

遍历List:

<%
	List<String> names = new ArrayList<String>();
	names.add("zhangSan");
	names.add("liSi");
	names.add("wangWu");
	names.add("zhaoLiu");
	pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
	<c:out value="name: ${item }"/><br/>
</c:forEach>

遍历Map:

<%
	Map<String,String> stu = new LinkedHashMap<String,String>();
	stu.put("number", "N_1001");
	stu.put("name", "zhangSan");
	stu.put("age", "23");
	stu.put("sex", "male");
	pageContext.setAttribute("stu", stu);
%>
<c:forEach var="item" items="${stu }">
	<c:out value="${item.key }: ${item.value }"/><br/>
</c:forEach>

forEach标签还有一个属性:varStatus,这个属性用来指定接收“循环状态”的变量名,例如:<forEach varStatus=”vs” …/>,这时就可以使用vs这个变量来获取循环的状态了。

count:int类型,当前以遍历元素的个数;
index:int类型,当前元素的下标;
first:boolean类型,是否为第一个元素;
last:boolean类型,是否为最后一个元素;
current:Object类型,表示当前项目。
 

<c:forEach var="item" items="${ns }" varStatus="vs">
	<c:if test="${vs.first }">第一行:</c:if>
	<c:if test="${vs.last }">最后一行:</c:if>
	<c:out value="第${vs.count }行: "/>
	<c:out value="[${vs.index }]: "/>
	<c:out value="name: ${vs.current }"/><br/>
</c:forEach>

5、fmt标签库常用标签:

     fmt标签库是用来格式化输出的,通常需要格式化的有时间和数字。

格式化时间:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%
	Date date = new Date();
	pageContext.setAttribute("d", date);
%>
<fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>

格式化数字:

<%
	double d1 = 3.5;
	double d2 = 4.4; 
	pageContext.setAttribute("d1", d1);
	pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
<fmt:formatNumber value="${d2 }" pattern="#.##"/>

十一.EL表达式介绍

    EL表达式定义规则:以 $ 开头 内容写在 {} 中,都是针对Attrbute()的 例: ${test},.

1.EL表达式查找顺序

    如果使用类似于 ${username} 的时候没有在哪一个范围查找username 那么它会以:

  1. Page
  2. Request
  3. Session
  4. Application

   为顺序来进行查找,加入中途找到了 username 那么就会返回值  如果一路没找到 返回 null

2.EL表达式的隐性变量

从这里开始就是介绍EL表达式的隐性变量,通过这些隐性变量可以让我们简便完成很多复杂的操作:

pageContext 用来访问JSP的隐性对象
pageScopepage对象的MAP
requestScope request对象的MAP
requestScope request对象的MAP
sessionScope session对象的MAP
applicationScope application对象的MAP
param 包含请求参数字符串的MAP
paramValues 包含请求参数字符串数组的MAP
header 包含请求头字符串的MAP
headerValues 包含请求头字符串数组的MAP
cookie 按名称存储请求附带的cookie的MAP
例:假设我们是想要session中的name值 那么我们可以使用:
${sessionScope.name}

再例:我们想要获得GET或则POST传递过来的name参数,在以前我们只能使用:
request.getParameter(name);
 
使用EL表达式可代替为:${param.name}

同样,如果我们想要得到一个参数的数组,可以使用:${paramValues.name}
当然,返回的是一个数组对象.

3.EL常用操作

获得对象的属性

${name}
//如果明确知道是在哪个域,也可以复杂地这样写:
${pageContext.findAttribute("name") }
${requestScope.name}

//<!-- 从WEB域中找到键值为person的对象,然后再person对象中找到name属性 -->
${person.name}  
${person.address.city} 
//<!-- 也可以用[]方式 -->,例如,健名中有“-”的,就要用这个取值了
${person['name']}  
${person['address']['city']}  

从List集合对象中获取某个值并显示。

<%  
    List<Person> list = new ArrayList<Person>();  
    list.add(new Person("kkk"));  
    list.add(new Person("sss"));  
    list.add(new Person("jjj"));  
    application.setAttribute("list_1", list);  
%>  
${list_1[1].name }  

从Map中获取某个值并显示

<%  
    Map map = new HashMap();  
    map.put("a", new Person("aaa"));  
    map.put("b", new Person("bbb"));  
    map.put("1", new Person("ccc"));  
    request.setAttribute("map", map);  
%>  
${map['1'].name }<!-- 是数字的话只能用括号,就算put进去的key值是字符串类型-->  
${map.a.name }  

EL运算符

1)语法:${运算表达式}
2)常见运算符:
==(eq)   !=(ne)    <(lt)    >(gt)    <=(le)    >=(ge)    &&(and)   ||(or)   !(not)
3)判断是否为空:
${empty name }
4)三目运算符:
${name == null?"null":name }

6、获取常用对象

十二.表单提交使用的编码

关于编码的 form 标签的属性

accept-charset:可以指定form编码形式
enctype: 规定在发送表单数据之前如何对其进行编码。

有三种设置类型
    默认为application/x-www-form-urlencoded:发送前编码所有字符
    multipart/form-data:不对字符编码,包含文件上传控件的表单时,必须使用该值
    text/plain:空格转换为 "+" 加号,但不对特殊字符编码。
    method:规定用于发送 form-data 的 HTTP 方法。有 post 和 get

默认的,无论表单提交的method是post 还是 get,都会默认使用页面的编码进行数据的编码,但是一旦指定了accept-charset="utf-8"这个参数,那么他就会运用你约定的编码方式来编码你的数据。

页面的编码也就是:<%@ page contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%> 中contentType
 

<%@ page contentType="text/html;charset=gb2312" language="java"%>
<html>
  <head>
    <title>title</title>
  </head>
  <body>
 
<form method="get" action="${pageContext.request.contextPath}/hello"  accept-charset="UTF-8">
   name: <input type="text" name="name"/><br/>
    age:<input type="text" name="age"/><br/>
    <input type="submit" value="提交" />
 
  </form>
 
如果没有指定 accept-charset="utf-8",则使用页面的编码方式 gb2312,如果指定了则使用 accept-charset="utf-8"指定的 utf-8进行编码

十三.JSP 调用和运行原理(详细版)

问题:

<%@ page contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>  中 charset="utf-8" 与 pageEncoding="utf-8"区别


关于JSP页面中的pageEncoding和contentType两种属性的区别:

    pageEncoding是jsp文件本身的编码(从 jsp到 servlet 源码使用的编码)

    contentType的charset是指服务器发送给客户端时的内容编码(从 tomcat 服务器发送到浏览器使用的编码)

    pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了. 但这不是绝对的.

   JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。

第一阶段是jsp编译成java

它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。

第二阶段是由JAVAC的JAVA源码至java byteCode的编译

不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。

第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值