javaWeb基础---Jsp

 

目录

1.jsp简述

2.jsp的生命周期

2.1 JSP编译

2.2 JSP初始化

2.3 JSP执行

2.4 JSP清理

3.jsp的基本语法

 3.1   2种注释类型

 3.2  3个脚本元素

 3.3  3个指令元素 

    3.3.1   page

    3.3.2   include

    3.3.3   taglib 

  3.4   6个动作标签

  3.5 九大隐式(内置)对象

4.EL表达式

4.1 使用el表达数据

4.2 使用el表达11大内置对象的数据

4.3 使用el自带的函数库表达数据

4.4 自创el表达数据

5. EL辅助--JSTL

  5.1 JSTL是什么

  5.2 JSTL标签库

  5.2.1 core

  5.2.2   fmt


 

学习内容概括:1个EL表达式,2种注释类型,3个脚本元素,3个指令元素,6个动作标签 9大内置对象

                      EL表达式因为内容多放在后面

1.jsp简述

jsp技术是web网站的服务端技术,可以简单理解为jsp技术说是用来生成动态网页的。

普通的网页是html的,它是静态的,需要事先用html语言编写好。那么我们在html页面中加入一些java代码,用java代码部分动态的内容插入到原来的html页面中,那么,这个页面就可以成为jsp页面。即,jsp=html+java。(来自简书的用户:李灿辉
链接:https://www.jianshu.com/p/88db37562751)

后来jsp继续发展,用更方便的标签、指令代替了大部分的java脚本,使得jsp更独立和更方便

有人说jsp落后了,但是理解jsp对于我们学习后面springmvc很有帮助。学生党不要挑剔那么多,一门语言存在即合理。

下面给出一些参考文章

jsp与php的对比:https://www.cnblogs.com/jiangzhaowei/p/6419353.html  来自博客园的用户qiuri2008

jsp走向没落?:https://blog.csdn.net/xuaman/article/details/78296871 来自csdn的用户xuanman

jsp:一个装配工的没落:https://blog.csdn.net/yuanlaijike/article/details/79247856 来自csdn的用户 Jitwxs

JSP = html + Java脚本(代码片段) + JSP动态标签

 

2.jsp的生命周期

(下面是来自菜鸟教程的资料:http://www.runoob.com/jsp/jsp-life-cycle.html)

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

以下是JSP生命周期中所走过的几个阶段:

  • 编译阶段: servlet容器编译servlet源文件,生成servlet类

  • 初始化阶段:加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法
  • 执行阶段:  调用与JSP对应的servlet实例的服务方法
  • 销毁阶段:调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

很明显,JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示:

2.1 JSP编译

当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。

编译的过程包括三个步骤:

  • 解析JSP文件。
  • 将JSP文件转为servlet。
  • 编译servlet。

2.2 JSP初始化

容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样:

public void jspInit(){
  // 初始化代码
}

一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()方法中初始化数据库连接、打开文件和创建查询表。


2.3 JSP执行

这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。

当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。

_jspService()方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样:

void _jspService(HttpServletRequest request,
                 HttpServletResponse response)
{
   // 服务端处理代码
}

_jspService()方法在每个request中被调用一次并且负责产生与之相对应的response,并且它还负责产生所有7个HTTP方法的回应,比如GET、POST、DELETE等等。


2.4 JSP清理

JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。

jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。

jspDestroy()方法的格式如下:

 

3.jsp的基本语法

 3.1  2种注释类型

  ①html注释  

   <!--注释内容-->             

    这个应该都很熟悉  不过这个会把注释发到客户端,但是客户端不显示而已 

  ②jsp注释

<%--注释内容--%>

  jsp的注释不会发到客户端,服务器在把jsp文件编译为java文件时已经忽略了注释部分。

ps:以上两种只能定义在脚本元素之外,即非java代码区。如果要想在java代码区填写注释,还是得用//或者/*  */

客户端代码,可以看到只有<!-- -->这种注释才会发送到客户端

 

 3.2  3个脚本元素

正如上面所说,jsp由html、java代码片段、jsp动态标签组成。jsp脚本元素是用来表述java片段的。jsp脚本元素三种形式

  • <%........%>     可以存放 0-n条java语句,等同于java方法里的语句
  • <%=.......%>   可以存放表达式,用于输出一条表达式(变量)的结果 比如<%=i> 就是输出变量i的值
  • <%!.......%>    可以存放全局变量或者全局方法(不是方法体内的局部变量)

 

 3.3  3个指令元素 

jsp指令的格式:<%@指令名 attr1="" attr2="" %>,一般都会把jsp指令放在jsp文件的最上方,但不是必须的。jsp有三大指令:page,include,taglib,其中最常用也是最复杂的就是page指令了。先放一张图让你们认识认识这三个指令元素 

    3.3.1   page

      page指令被称为页面指令,用来定义jsp页面的全局属性。page指令有挺多属性的,这里介绍重点的几个。

  •   pageEncoding、contentType

        pageEncoding指定当前页面的编码,这个编码是给服务器看的,因为服务器需要把当前jsp编译为java文件;contentType和response.setContentType()一样,都是设置字符流的编码,此外它还有一个功能,设置response的content-type响应头。

 

         无论是pageEncoding还是contentType,默认值都是iso-8859-1,这个值是无法显示中文的,所以jsp存在中文的话,一定得设置这两个属性。但是有点特殊,这两个属性只要设置了一个,另一个的默认值就等于已设定的属性的值。因此一般都是选择设置contentType,毕竟它多了个“text/html”

  •    extends、import

         extends指定jsp继承的父类;import指定导入的包,其中Java.lang.*、javax.servlet.*、javax.servlet.jsp.*、javax.servlet.http.*这几个包本身已经被导入,无需再导入。import指令是唯一一个一条page指令中可重复出现的属性,不过我们一般写多条指令,每条带一个import属性。这两个的效果是一样的

  • isErrorPage、errorPage

        当你设置isErrorPage为true时,说明该界面为错误界面,即专门处理错误的界面;errorPage指定处理错误的界面,当当前界面发生错误时,会将请求转向errorPage指定的界面(这个界面得设置isErrorPage="true")。

 

  在jsp中除了可以用page的属性进行指定错误界面,其实也可以在web.xml中指定。

       web.xml

  <error-page>

    <error-code>404</error-code>

    <location>/error404.jsp</location>

  </error-page>

  <error-page>

    <error-code>500</error-code>

    <location>/error500.jsp</location>

  </error-page>

  <error-page>

    <exception-type>java.lang.RuntimeException</exception-type>

    <location>/error.jsp</location>

  </error-page>

 

  <error-page>有两种使用方式:

      <error-code>和<location>子元素

      <exception-type>和<location>子元素;

   其中<error-code>是指定响应码,<location>指定转发的界面;<exception-type>是指定抛出的异常类型

   所以在上面这张图中:

  • 当出现404时,会跳转到error404.jsp页面;
  • 当出现RuntimeException异常时,会跳转到error.jsp页面;
  • 当出现非RuntimeException的异常时,会跳转到error500.jsp页面。

 

        除了以上的这6中常见属性,还有session:指定该界面是否可以用session对象;isThreadSafe:制定该jsp界面是否支持多线程; isElignored:指定该jsp界面是否支持EL表达式; info:设置页面的相关信息

          

  •    其他的属性

 

    3.3.2   include

include表示静态包含,即把多个jsp文件合成一个servlet文件。静态包含就是在编译前先把这两个文件合并成一个jsp文件再编译为  servlet文件。既然有静态包含也有动态包含,动态包含下面会提到

其中的file属性用于指定被引入文件的相对路径。  file属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件

 

    3.3.3  taglib 

      taglib的作用是用来引用标签库。语法:

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

     prefix是前缀,你可以随便起,url是该标签库地址 

 

  3.4   6个动作标签

   动作标签的作用就是用来简化java脚本的,通俗的讲,这就是提前制定好的一些“java”片段,我们可以直接拿来使用,减少我们的工作量。就跟类库有点相似。据说,javaWeb提供了20个jsp动作标签(我在菜鸟教程只找到了10个),先来张图

语法描述
jsp:include在页面被请求的时候引入一个文件。
jsp:useBean寻找或者实例化一个JavaBean。
jsp:setProperty设置JavaBean的属性。
jsp:getProperty输出某个JavaBean的属性。
jsp:forward把请求转到一个新的页面。
jsp:plugin根据浏览器类型为Java插件生成OBJECT或EMBED标记。
jsp:element定义动态XML元素
jsp:attribute设置动态定义的XML元素属性。
jsp:body设置动态定义的XML元素内容。
jsp:text在JSP页面和文档中使用写入文本的模板

      这里的我们只讨论6个:jsp:include  jsp:forward jsp:parameter jsp:useBean  jsp:setProperty   jsp:getProperty,后面三个跟javaBean有关。

 

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

     jsp:include动作标签是动态包含 功能和RequestDispatcher的include()方法是一样的,都是在运行级别时完成合并,即当前jsp和被include的jsp各自编译为servlet文件,再“合并”(具体为当前jsp编译的servlet文件在执行时完成包含另一个jsp的servlet文件)。

     与Page指令的include属性不一样,include是静态合并,是在运行前合并。

 

  • jsp:forward   
<jsp:forward page="loginB.jsp" />

  jsp:forward标签的作用就是请求转发,与request中介绍的请求转发一致

ps:客户端最后看到的界面时请求转发设置的界面(loginB.jsp),比如下面这个例子中loginA\.jsp的<h1>欢迎登录</h1>是不会发到客户端的,只看到loginB.jsp的<h1>登录界面</h1>

loginA.jsp

loginB.jsp

显示结果

ps:这里page中的路径没带/就默认是当前文件下的,我的loginA.jsp和loginB.jsp都是保存在jspforward文件夹下。所以才可以直接写<jsp:forward page="loginB.jsp" />

如果要跳转的是其他文件夹的得加 /  。比如你jspforward文件夹的loginA.jsp想请求转发至jspinclude文件夹的loginB.jsp。应该这样敲

<jsp:forward page="/jspinclude/loginB.jsp" />

 

  • jsp:param

jsp:param是jsp:include jsp:forward的子标签,起到传递参数的作用。举例说明

loginA.jsp

<body>

<h1>这里是loginA.jsp界面</h1>
<%-- 如果是跳转到其他文件夹的jsp文件得加 /   --%>
<jsp:include page="/jspforward/loginB.jsp">
    <jsp:param name="name" value="zhangsan" />
    <jsp:param name="password" value="123"/>
</jsp:include>

</body>

loginB.jsp

<body>
      <h1>登录界面  这是loginB.jsp的界面</h1>
<%
    String name = request.getParameter("name");
    String password = request.getParameter("password");
    out.println("登录名:" + name);
    out.println("登录密码:" + password);

%>
</body>

显示结果

 

  • jsp:useBean 、jsp:getProperty、jsp:setProperty
<jsp:useBean id="唯一标识" class="JavaBean类名" scope="作用的域名" />
<%--scope四个参数为page request session application 这四大域  --%>

<jsp:setProperty property="属性名" name="id名" value="属性值" />
<jsp:getProperty property="属性名" name="id名" />
作用
jsp:useBean  :创建javaBean

jsp:setProperty :设置javaBean中属性的值和名称 跟settter类似

jsp:getProperty :获取javaBean中属性的值和名称  跟gettter类似

jsp:setProperty中的属性名就是创建的bean中定义的属性(那些变量)值,name是jsp:useBean中的id名,value就是属性值。

 

  3.5 九大隐式(内置)对象

        每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。


        由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。


      JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。这九大对象分别是

对象描述
requestHttpServletRequest 接口的实例
responseHttpServletResponse 接口的实例
outJspWriter类的实例,用于把结果输出至网页上
sessionHttpSession类的实例,当设置page指令的session属性为false时,这个页面不能使用session
applicationServletContext类的实例,与应用上下文有关
configServletConfig类的实例
pageContextPageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page类似于Java类中的this关键字
ExceptionException类的对象,代表发生错误的JSP页面中对应的异常对象

  九大对象中,有很多是极少被使用的,比如config、page、exception

   九大对象中pageContext对象最重要,它代表着着一个jsp页面,另外,它的本事还不小,它自身封装着其他8个对象的引用,而且本身还是一个域(javaWeb中四大域之一),使用该对象可以访问页面中的共享数据。

pageContext作为隐式对象

  pageContext可以获取其他八个对象的引用,写法: 

PageContext.getOut();                    //获取out对象
PageContext.getSession();                //获取session对象
PageContext.getPage();                   //获取page对象
PageContext.getServletConfig();          //获取config对象
PageContext.getServletContext();         //获取application对象
PageContext.getRequest();                //获取request对象
PageContext.getResponse();               //获取response对象
PageContext.getExceptioin();             //获取exception对象

pageContext作为域对象

 在介绍pagecontext作为域对象的功能前,得先讲一下jsp的四大域对象:page、request、session、application(从小到大)

 page域

     作用范围:当前jsp页面

     生命周期:从对jsp页面的访问开始到离开该jsp页面为结束

     作用:为当前jsp共享数据

 ①作为域对象必定有的三个方法:

      void   setAttribute(String name,Object vaue)

      Object getAttribute(String name,Object value)

      void removeAttribute(String name,Object value)

 ②代理其他域对象的功能,即可以使用pageContext向request、session、application域对象中存取数据

   void setAttribute(String name,Object value,int scope);          //在指定域范围内添加数据

   Object getAttribute(String name,Object value,int scope);      //在指定域范围内获取数据

   void removeAttribute(String naem,Object value,int scope);   //删除指定域范围内的数据

    其中四个域的的常量scope写法为:REQUEST_SCOPE    SESSION_SCOPE   APPLICATION_SCOPE  PAGE_SCOPE

 ③全域查找

    Object findAttribute(String name)

   这个方法的作用是在四个域中寻找name数据,寻找顺序从小到大:page、request、session、application

 

4.EL表达式

EL表达式是什么  EL(Expression Language)表达式是jsp2.0推出的产物,旨在取代这个 <%=  %>jsp的脚本元素。就是取代java程序中的表达部分

EL表达式的语法也简单:${变量或者表达式}

我们顺着表达这个核心讲解EL表达式

 

4.1 使用el表达数据

 使用el表达式你可以表达你定义的变量或者对象的值,变量很简单,直接${变量}就好了;对于一些对象,比如bean,list,map,就是如下的操作

操作bean属性 ${person.name} 、${person['name']}  替换getName()

操作List集合/数组属性  ${list[0]}  ${arr[0]}

操作map的值  ${map.key}   ${map['key']}   替换map.get(key)

 

  • .和 [ ]的区别: 

对EL来说,.和 [ ]都能表达数据,但是还是有一些不同

当要存取的属性名称里包含一些特殊字符时,比如-  ?等非字母或数字的符号,一定要使用 [' '];。下面举例

  person对象里有个My-name字段  ${person['My-name']}

或者是要动态取值时

  ${sessionScope.person[data]}  data是一个变量

  • 取值顺序

    EL表达式表达数据时是用${}里的数据名为关键字,依次从page request session application四个域中检索对应的对象。当然你也可以直接指定要从那个域中获取数据。

不过有个注意的点 这四个域在El表达式里的写法是在其名字后加上Scope,即pageScope  requestScope  sessionScope applicationScope

指定从session域中取值:  ${sessionscope.person.name}

 

4.2 使用el表达11大内置对象的数据

    el内置了11个常见的对象,你可以直接使用这些对象里的值。除了第一个不是map类型,其他事10个都是map类型

隐含对象
隐含对象名称描 述
pageContext对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。)
pageScope代表page域中用于保存属性的Map对象
requestScope代表request域中用于保存属性的Map对象
sessionScope代表session域中用于保存属性的Map对象
applicationScope代表application域中用于保存属性的Map对象
param表示一个保存了所有请求参数的Map对象
paramValues
 
表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
header表示一个保存了所有http请求头字段的Map对象
headerValues同上,返回string[]数组。注意:如果头里面有“-”,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
cookie表示一个保存了所有cookie的Map对象
initParam表示一个保存了所有web应用初始化参数的map对象

           该图来源简书的作者:暗香抚动  链接:https://www.jianshu.com/p/6bc6b14663cf

  • pageContext对象

pageContext是PageContext类型!根据2.5所说,它内置了其他8个jsp对象,因此可以用它来干很多事情。

获取request

  获取request就可以实现获取请求相关的东西(只要是request对象的方法都可以),比如请求头,请求码,请求行

       ${pageContext.request.protocol}

      ${pageContext.request.contentPath}   //这个很实用 以后就不必要每次都要写死路径了,下面是一个例子

<form action="${pageContext.request.contextPath}/user/testSpringMVCFileupload" method="post" enctype="multipart/form-data">

其他还有很多,比如获取cookie对象之后就可以设置cookie,读取cookie;获取session对象后就可以读取sessionID了。更多的可以去查看JavaEE的api:https://docs.oracle.com/javaee/7/api/ 或者直接在你的ide中打开智能补全代码就好了

 

  •  pageScope requestScope sessionSCope applicationScope 

      这几个在前面3.1取值顺序已经说了,就不在多说了。直接上个图显示简单的例子

 

  • param paramValues

param: Map<String,String>类型,param对象可以获取参数,不过获取的是request中url?后带的参数,即与request.getParameter()效果一样

ps:如果参数不存在,返回的是空字符串,不会是“null”。这个点与request.getParameter()不一样

paramValues:Map<String,String>类型,与param一样,也是获取到请求参数,但是不同的是它获取的是同一个参数名下多值的参数,返回的是一个String[]数组。比如你在url?后输入name=张三&name=李四,就可以用paramValue获取,返回的就是String[0]=“张三” String[1]="李四"

 

  • header headerValues

   header与headerValues跟上面的param/paramValues一样,都是map类型的对象,不同的是header获取的是请求头(不清楚的可以看下图,也可以去我的另一篇博客关于request看一下:https://blog.csdn.net/Vibugs/article/details/86376668)相关的数据,而headerValues不用说了,就是获取请求头多值数据的数组。下面我就介绍header就好了。

红色部分都是请求头的字段

 

ps:记得如果数据里带有-这种非字母/数字符号的不能使用 . 得使用 [ ' ' ]

 

  • cookie

  cookie表示一个保存了所有cookie的map对象 。所以当你想取某个值时,你得这样取 ${cookie.key.value} 其中key是cookie的name,value是cookie的值。当然如果你cookie里有一些非字母/数字的值,记得用[ ' '] 。

  • initParam

   initParam也是map类型的对象,主要是获取web.xml文件下的<context-param>的参数

 <context-param>:说的通俗一点,就是web程序的全局变量(不知道这样说对不对)参考csdn的用户晓梦_知行  的文章https://blog.csdn.net/csdn_ds/article/details/72318557

 

4.3 使用el自带的函数库表达数据

“EL你已经满18岁了,是时候该自己表达数据了"  因此我们介绍一下el自带的函数库,这些函数库的作用挺多的,我抽一些来讲,其他的看api吧(这个我找了半天就找到一个,里面好像也没怎么描述,推荐你们用ide直接下载吧)

函数的功能包括对字符串的一些操作,例如转换大小写  判断是否有要查询的字符串等等 里面的跟以前String中的方法很相似

String toUpperCase(String input):      //转换大写
String toLowerCase(String input):      //转换小写
int indexOf(String input, String substring):  
boolean contains(String input, String substring):    //判断是否包含
boolean containsIgnoreCase(String input, String substring):  //判断是否包含 忽略大小写
boolean startsWith(String input, String substring):
boolean endsWith(String input, String substring):
String substring(String input, int beginIndex, int endIndex):
String substringAfter(String input, String substring):hello-world, “-“
substringBefore(String input, String substring):hello-world, “-“
String escapeXml(String input):把字符串的“>”、“<”。。。转义了!
String trim(String input):
String replace(String input, String substringBefore, String substringAfter):
String[] split(String input, String delimiters):
int length(Object obj):可以获取字符串、数组、各种集合的长度!
String join(String array[], String separator):

 要想用这个库,还得导包  使用taglib指令导包  <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

下面是一个例子,注释里面是最后的运行结果。这个例子来源于黑马javaWeb视频资源中day13。

<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
…
String[] strs = {"a", "b","c"};
List list = new ArrayList();
list.add("a");
pageContext.setAttribute("arr", strs);
pageContext.setAttribute("list", list);
%>
${fn:length(arr) }<br/><!--3-->
${fn:length(list) }<br/><!--1-->
${fn:toLowerCase("Hello") }<br/> <!-- hello -->
${fn:toUpperCase("Hello") }<br/> <!-- HELLO -->
${fn:contains("abc", "a")}<br/><!-- true -->
${fn:containsIgnoreCase("abc", "Ab")}<br/><!-- true -->
${fn:contains(arr, "a")}<br/><!-- true -->
${fn:containsIgnoreCase(list, "A")}<br/><!-- true -->
${fn:endsWith("Hello.java", ".java")}<br/><!-- true -->
${fn:startsWith("Hello.java", "Hell")}<br/><!-- true -->
${fn:indexOf("Hello-World", "-")}<br/><!-- 5 -->
${fn:join(arr, ";")}<br/><!-- a;b;c -->
${fn:replace("Hello-World", "-", "+")}<br/><!-- Hello+World -->
${fn:join(fn:split("a;b;c;", ";"), "-")}<br/><!-- a-b-c -->

${fn:substring("0123456789", 6, 9)}<br/><!-- 678 -->
${fn:substring("0123456789", 5, -1)}<br/><!-- 56789 -->
${fn:substringAfter("Hello-World", "-")}<br/><!-- World -->
${fn:substringBefore("Hello-World", "-")}<br/><!-- Hello -->
${fn:trim("     a b c     ")}<br/><!-- a b c -->
${fn:escapeXml("<html></html>")}<br/> <!-- <html></html> -->

 

4.4 自创el表达数据

   感觉不好写出来,直接贴个视频地址你看吧(捂脸) 。步骤大概是  创建一个函数类(这个类里面的方法记得是静态)  然后再创建一个.tld的配置文件(类似下图这种)

 

5. EL辅助--JSTL

  5.1 JSTL是什么

 JSTL是apache对EL表达式的扩展,它是个标签语言,只不过跟jsp的内置标签不同,使用时需要导包。

JSTL提供了一个有效的途径,以在JSP页面中嵌入逻辑,而不是直接嵌入Java代码。使用标准标签集,减少了Java代码导致的不连续,从而提高代码的可维护性,并达到应用软件代码开发与用户界面间的关注点分离

安装JSTL库:如果你的是tomcat

  1. 下载的二进制发行版,从Apache标准标记库和解压的压缩文件。

  2. 使用标准的标签库从Jakarta Taglibs分布,复制发行版'lib'目录到应用程序的JAR文件 webapps\ROOT\WEB-INF\lib 目录中。

  5.2 JSTL标签库

       JSTL有四大库:core  fmt  sql xml 。下面只讲前两个,因为后面两个优点过时了

导入标签库

core:

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

 

 ps: prefix是前缀名,可以顺便写

  5.2.1 core

下面是core中的标签,这里我们挑一些讲,其他的可以看文档:https://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/tld-summary.html

  •  out set remove

从名字上也可以看出,out就是·输出,功能跟<%=  %>一样

set就是设置一个结果在指定域中,默认是page

remove是删除指定域中的数据,也可以不指定,不指定就默认page

<c:out value="abc" />   //输出 abc
<c:set var="name" value="zhangsan" />  //设置一个名为name,值为zhangsan的数据
<c:set var="name" value="lisi" scope="session" /> //设置一个名为name,值为lisi的数据到session域中
<c:remove var="name" value="lisi"  />   //在所有域中删除名为name的数据
<c:remove var="name" value="lisi" scope="session" />   //在session域中删除名为name的数据

ps:里面的c是prefix的值,如果你定义为core前缀,那就是<core:out value="abc" />

 

  • url

<c:url>标签将URL格式化为一个字符串,从而进行对URL的操作的标签。jstl标签都是为了简化java脚本才创建出来的,那url标签肯定有其比较方便实用的功能。在介绍功能前介绍URL几个属性

<c:url>标签有如下属性:

属性描述是否必要默认值
value基础URL
context本地网络应用程序的名称当前应用程序
var代表URL的变量名Print to page
scopevar属性的作用域Page

ps:用了var之后,url便签将不会输出到页面中,而是添加到指定域中(没有指定默认page域)

功能1:当value的值为路径时 在路径前面自动添加项目名

<c:url value="/index.jsp" />  会输出   /项目名/index.jsp

功能2:当有子标签param有参数时,自动进行URL编码

<c:url value="/index.jsp" >

    <c:param name="name" value="张三" />

</c:url>

输出:/项目名/index.jsp?name=%ED%2C     //这个张三转码后的值我是瞎打的

 

实际小例子:html标签嵌套jstl便签

严格来说,不单单是可以嵌套jstl便签,jsp标签也可以嵌套

 

输出:成为一个超链接, <a href="/项目名/index.jsp"  />",下图为客户端上的显示结果

原理:<a href="" />是一个静态标签,是由客户端解析;而<c:url>是动态标签,在发往客户端之前由服务器端解析,因此发到客户端时应该是这样的: <a href="/项目名/index.jsp"  />"

 

  • if  

if标签取代的就是java片段中的if,一般跟其他标签搭配,最常见的是<c:out>.先介绍属性

<c:if>标签有如下属性:

属性描述是否必要默认值
test条件
var用于存储条件结果的变量
scopevar属性的作用域page

下面给个实例

ps:test属性必须是一个boolean值,如果为true,执行if标签里面的内容

 

  • choose

choose对应着switch语句,case对应着<c:when>,default对应着<c:otherwise>。这些标签都只有一个属性test,这个属性我就不介绍了,也是判断。下面直接给出实例

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:choose 标签实例</title>
</head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<p>你的工资为 : <c:out value="${salary}"/></p>
<c:choose>
    <c:when test="${salary <= 0}">
       太惨了。
    </c:when>
    <c:when test="${salary > 1000}">
       不错的薪水,还能生活。
    </c:when>
    <c:otherwise>
        什么都没有。
    </c:otherwise>
</c:choose>
</body>
</html>

结果:

你的工资为 : 4000

不错的薪水,还能生活。

 

  • forEach forToken

这两个标签代替了java中的for循环和迭代输出,forToken多出一个特点,就是讲输出的数据按照条件分割为子串数组然后迭代。下面是属性介绍

<c:forEach>标签有如下属性:

属性描述是否必要默认值
items要被循环的信息
begin开始的元素(0=第一个元素,1=第二个元素)0
end最后一个元素(0=第一个元素,1=第二个元素)Last element
step每一次迭代的步长(比如i+2这个2)1
var代表当前条目的变量名称
varStatus代表循环状态的变量名称

<c:forTokens>标签与<c:forEach>标签有相似的属性,不过<c:forTokens>还有另一个属性:

属性描述是否必要默认值
delims分隔符

 

ps:item的两个冒号里面千万不能有空格,不然会报bug

实例

模仿for(int i=1; i<=5; i++){system.out.println("i");}

<c:forEach>实例演示

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:forEach 标签实例</title>
</head>
<body>
<c:forEach var="i" begin="1" end="5">
   Item <c:out value="${i}"/><p>
</c:forEach>
</body>
</html>

结果

Item 1
Item 2
Item 3
Item 4
Item 5

<c:forToken>实例

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:forTokens 标签实例</title>
</head>
<body>
<c:forTokens items="google,w3cschool,taobao" delims="," var="name">
   <c:out value="${name}"/><p>
</c:forTokens>
</body>
</html>

结果

google
w3cschool
taobao

遍历list、map、数组

遍历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 }">[崔1] 

    <c:out value="name: ${item }"/><br/>

</c:forEach>


与遍历数组没有区别!

for(String s : ns) {

   …

}

map也一样,只不过是输出的时候输出两个变量而已,一个key,一个value

遍历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[备注1] " items="${stu }">

    <c:out value="${item.key }: ${item.value }[备注2] "/><br/>

</c:forEach>


 

 [备注1]因为遍历的是Map,所以每一项是Entry类型

 [备注2]获取Entry的key和value

还有一个点就是varStatus的使用,这个属性可以获取当前循环到的变量的值

 

  5.2.2   fmt

使用fmt库

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

fmt的作用是格式化数据并输出的,下面是fmt库中的标签。

标签描述
<fmt:formatNumber>使用指定的格式或精度格式化数字
<fmt:parseNumber>解析一个代表着数字,货币或百分比的字符串
<fmt:formatDate>使用指定的风格或模式格式化日期和时间
<fmt:parseDate>解析一个代表着日期或时间的字符串
<fmt:bundle>绑定资源
<fmt:setLocale>指定地区
<fmt:setBundle>绑定资源
<fmt:timeZone>指定时区
<fmt:setTimeZone>指定时区
<fmt:message>显示资源配置文件信息
<fmt:requestEncoding>设置request的字符编

这里只介绍时间和数字 

 

  • <fmt:formatDate>

<fmt:formatDate>标签有如下属性:

属性描述是否必要默认值
value要显示的日期
typeDATE, TIME, 或 BOTHdate
dateStyleFULL, LONG, MEDIUM, SHORT, 或 DEFAULTdefault
timeStyleFULL, LONG, MEDIUM, SHORT, 或 DEFAULTdefault
pattern自定义格式模式
timeZone显示日期的时区默认时区
var存储格式化日期的变量名显示在页面
scope存储格式化日志变量的范围页面

直接上例子

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html>
<head>
  <title>JSTL fmt:dateNumber 标签</title>
</head>
<body>
<h3>日期格式化:</h3>
<c:set var="now" value="<%=new java.util.Date()%>" />

<p>日期格式化 (1): <fmt:formatDate type="time"     //日期格式化 (1): 11:19:43
            value="${now}" /></p>                  
<p>日期格式化 (2): <fmt:formatDate type="date"     //日期格式化 (2): 2016-6-26
            value="${now}" /></p>
<p>日期格式化 (3): <fmt:formatDate type="both"     //日期格式化 (3): 2016-6-26 11:19:43
            value="${now}" /></p>
<p>日期格式化 (4): <fmt:formatDate type="both"     //日期格式化 (4): 16-6-26 上午11:19
            dateStyle="short" timeStyle="short" 
            value="${now}" /></p>
<p>日期格式化 (5): <fmt:formatDate type="both"     //日期格式化 (5): 2016-6-26 11:19:43
            dateStyle="medium" timeStyle="medium" 
            value="${now}" /></p>
<p>日期格式化 (6): <fmt:formatDate type="both"     //日期格式化 (6): 2016年6月26日 上午11时19分43秒
            dateStyle="long" timeStyle="long" 
            value="${now}" /></p>
<p>日期格式化 (7): <fmt:formatDate pattern="yyyy-MM-dd"  //日期格式化 (7): 2016-06-26
            value="${now}" /></p>

</body>
</html>

 

  • <fmt:formatNumber>

fmtmatNumber用来解析数字,百分数,货币

<fmt:parseNumber>标签有如下属性:

属性描述是否必要默认值
value要解析的数字Body
typeNUMBER,,CURRENCY,或 PERCENTnumber
parseLocale解析数字时所用的区域默认区域
integerOnly是否只解析整型数(true)或浮点数(false)false
pattern自定义解析模式
timeZone要显示的日期的时区默认时区
var存储待解析数字的变量Print to page
scopevar属性的作用域page

pattern属性与<fmt:formatNumber>标签中的pattern有相同的作用。在解析时,pattern属性告诉解析器期望的格式。

例子:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
  <title>JSTL fmt:parseNumber 标签</title>
</head>
<body>
<h3>数字解析:</h3>
<c:set var="balance" value="1250003.350" />

<fmt:parseNumber var="i" type="number" value="${balance}" />
<p>数字解析 (1) : <c:out value="${i}" /></p>
<fmt:parseNumber var="i" integerOnly="true" 
                       type="number" value="${balance}" />
<p>数字解析 (2) : <c:out value="${i}" /></p>

</body>
</html>

结果:

数字解析:

数字解析 (1) : 1250003.35

数字解析 (2) : 1250003

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值