JSP系列教材 (一)- 教程

通过Servlet进行整个网站的开发是可以的。 不过在Servlet中输出html代码,特别是稍微复杂一点的html代码,就会给人一种很酸爽的感觉。 
如果能够直接使用Html代码,然后在html中写java代码,就好了~ 
JSP ... 就可以干这个事情。

步骤1:hello.jsp
步骤2:代码解释
步骤3:<%=

步骤 1 : hello.jsp

在web目录下下新建一个文件hello.jsp
访问网页

http://127.0.0.1/hello.jsp

注: 不需要重启tomcat

<%@page contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

你好 JSP

<br>

<%=new Date().toLocaleString()%>

步骤 2 : 代码解释

<%@page contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8" import="java.util.*"%>

是JSP的<%@page指令

contentType="text/html; charset=UTF-8"

相当于response.setContentType("text/html; charset=UTF-8"); 通知浏览器以UTF-8进行中文解码

pageEncoding="UTF-8"

如果jsp文件中出现了中文,这些中文使用UTF-8进行编码

import="java.util.*

导入其他类,如果导入多个类,彼此用,逗号隔开,像这样 import="java.util.*,java.sql.*"

步骤 3 : <%=

<%=new Date().toLocaleString()%>

输出当前时间,相当于在Servlet中使用response.getWriter()进行输出

response.getWriter().println(new Date().toLocaleString());

JSP系列教材 (二)- 转译为Servlet


为什么JSP可以在html中运行java代码? 这是因为JSP被转译成了Servlet

步骤1:执行过程
步骤2:hello_jsp.java 为什么是Servlet

步骤 1 : 执行过程

1. 把 hello.jsp转译为hello_jsp.java
2. hello_jsp.java 位于
d:\tomcat\work\Catalina\localhost\_\org\apache\jsp
3. hello_jsp.java是一个servlet
4. 把hello_jsp.java 编译为hello_jsp.class
5. 执行hello_jsp,生成html
6. 通过http协议把html 响应返回给浏览器

步骤 2 : hello_jsp.java 为什么是Servlet

在Servlet章节中,我们说HelloServlet是一个Servlet,不是因为它的类名里有一个"Servlet",而是因为它继承了 HttpServlet
打开转译hello.jsp 后得到的hello_jsp.java,可以发现它继承了类
(D:\tomcat\work\Catalina\localhost\_\org\apache\jsp\hello_jsp.java)

org.apache.jasper.runtime.HttpJspBase

而HttpJspBase 继承了HttpServlet
所以我们说hello_.jsp.java 是一个Servlet

/*

* Generated by the Jasper component of Apache Tomcat

* Version: Apache Tomcat/7.0.64

* Generated at: 2017-01-07 01:45:17 UTC

* Note: The last modified time of this file was set to

*       the last modified time of the source file after

*       generation to assist with modification tracking.

*/

package org.apache.jsp;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

import java.util.*;

public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase

implements org.apache.jasper.runtime.JspSourceDependent {

private static final javax.servlet.jsp.JspFactory _jspxFactory =

javax.servlet.jsp.JspFactory.getDefaultFactory();

private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

private javax.el.ExpressionFactory _el_expressionfactory;

private org.apache.tomcat.InstanceManager _jsp_instancemanager;

public java.util.Map<java.lang.String,java.lang.Long> getDependants() {

return _jspx_dependants;

}

public void _jspInit() {

_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();

_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());

}

public void _jspDestroy() {

}

public void _jspService(final javax.servlet.http.HttpServletRequest request, finaljavax.servlet.http.HttpServletResponse response)

throws java.io.IOException, javax.servlet.ServletException {

final javax.servlet.jsp.PageContext pageContext;

javax.servlet.http.HttpSession session = null;

final javax.servlet.ServletContext application;

final javax.servlet.ServletConfig config;

javax.servlet.jsp.JspWriter out = null;

final java.lang.Object page = this;

javax.servlet.jsp.JspWriter _jspx_out = null;

javax.servlet.jsp.PageContext _jspx_page_context = null;

try {

response.setContentType("text/html; charset=UTF-8");

pageContext = _jspxFactory.getPageContext(this, request, response,

null, true, 8192, true);

_jspx_page_context = pageContext;

application = pageContext.getServletContext();

config = pageContext.getServletConfig();

session = pageContext.getSession();

out = pageContext.getOut();

_jspx_out = out;

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

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

out.write("你好 JSP\r\n");

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

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

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

out.print(new Date().toLocaleString());

} catch (java.lang.Throwable t) {

if (!(t instanceof javax.servlet.jsp.SkipPageException)){

out = _jspx_out;

if (out != null && out.getBufferSize() != 0)

try {

if (response.isCommitted()) {

out.flush();

} else {

out.clearBuffer();

}

} catch (java.io.IOException e) {}

if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);

else throw new ServletException(t);

}

} finally {

_jspxFactory.releasePageContext(_jspx_page_context);

}

}

}

JSP系列教材 (三)- 的7种页面元素


步骤1:页面元素
步骤2:<%=%>和 <%out.println()%>
步骤3:for循环

步骤 1 : 页面元素

jsp由这些页面元素组成:
1. 静态内容
就是html,css,javascript等内容
2. 指令
以<%@开始 %> 结尾,比如<%@page import="java.util.*"%>
3. 表达式 <%=%>
用于输出一段html
4. Scriptlet
在<%%> 之间,可以写任何java 代码
5. 声明
在<%!%> 之间可以声明字段或者方法。但是不建议这么做。
6. 动作
<jsp:include page="Filename" > 在jsp页面中包含另一个页面。在包含的章节有详细的讲解
7. 注释 <%-- -- %>
不同于 html的注释 <!-- --> 通过jsp的注释,浏览器也看不到相应的代码,相当于在servlet中注释掉了

步骤 2 : <%=%>和 <%out.println()%>

<%="hello jsp"%>

就相当于

<%out.println("hello jsp");%>

out是jsp的隐式对象,可以直接使用。一共有9种隐式对象,请参考 隐式对象 章节
注: <%=%> 不需要分号结尾,<%%> 需要以分号结尾,和java代码一样

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

<%="hello jsp"%>

<br>

<% out.println("hello jsp");%>

步骤 3 : for循环

结合for循环在jsp里输出html是常见的做法。 只是第一次这么写会稍显别扭
下面是一段实例,以供参考

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

<%

List<String> words = new ArrayList<String>();

words.add("today");

words.add("is");

words.add("a");

words.add("great");

words.add("day");

%>

<table width="200px" align="center" border="1" cellspacing="0">

<%for (String word : words) {%>

<tr>

<td><%=word%></td>

</tr>

<%}%>

</table>

JSP系列教材 (四)- include包含其他页面的两种方式,以及其区别


每个网页的最下方都有 版权声明等信息。 如果不使用包含,那么每个网页都需要单独写,如果版权声明要修改,则需要很大的工作量。 
使用include的办法,只需要准备一个footer.jsp,然后在其他页面包含footer.jsp即可。 
修改的时候,只需要修改footer.jsp所有的页面就都修改了,维护成本降低了很多。 
include有两种方式指令include和动作include

步骤1:首先准备一个footer.jsp
步骤2:指令include
步骤3:动作include
步骤4:指令include和动作include的区别
步骤5:传参

步骤 1 : 首先准备一个footer.jsp

<hr>

<p style="text-align:center">copyright@2016

</p>

步骤 2 : 指令include

通过指令

<%@include file="footer.jsp" %>

在hello.jsp中包含该页面

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

你好  JSP

<%@include file="footer.jsp" %>

步骤 3 : 动作include

通过动作

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

在hello.jsp中包含该页面

转存失败重新上传取消

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

你好  JSP

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

步骤 4 : 指令include和动作include的区别

通过之前的学习知道,JSP最后会被转译成Servlet
如果是指令include

<%@include file="footer.jsp" %>

footer.jsp的内容会被插入到 hello.jsp 转译 成的hello_jsp.java中,最后只会生成一个hello_jsp.java文件
如果是动作include

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

footer.jsp的内容不会被插入到 hello.jsp 转译 成的hello_jsp.java中,还会有一个footer_jsp.java独立存在。 hello_jsp.java 会在服务端访问footer_jsp.java,然后把返回的结果,嵌入到响应中。

步骤 5 : 传参

因为指令<%@include 会导致两个jsp合并成为同一个java文件,所以就不存在传参的问题,在发出hello.jsp 里定义的变量,直接可以在footer.jsp中访问。
而动作<jsp:include />其实是对footer.jsp进行了一次独立的访问,那么就有传参的需要。
如本例:
1. 在hello.jsp中使用动作<jsp:include,并通过<jsp:param 带上参数

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

<jsp:param  name="year" value="2017" />

</jsp:include>

2. 在footer.jsp中,使用request.getParameter("year")取出year

  • hello.jsp
  • footer.jsp

<%@page contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

你好 JSP

<%=new Date().toLocaleString()%>

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

<jsp:param  name="year" value="2017" />

</jsp:include>

<hr>

<p style="text-align:center">copyright@<%=request.getParameter("year")%>

</p>


和Servlet的跳转一样,JSP的跳转也分服务端跳转和客户端跳转。

步骤1:首先准备 jump.jsp 
步骤2:客户端跳转
步骤3:服务端跳转

示例 1 : 首先准备 jump.jsp

首先准备一个jump.jsp 来分别演示客户端跳转和服务端跳转

示例 2 : 客户端跳转

jsp的客户端跳转和Servlet中是一样的。

response.sendRedirect("hello.jsp");

可以通过firefox的调试工具可以观察到访问jump.jsp返回302(临时客户端跳转),跳转到了hello.jsp

<%

response.sendRedirect("hello.jsp");

%>

示例 3 : 服务端跳转

与Servlet的服务端跳转一样,也可以使用

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

或者使用动作,简化代码

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

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


步骤1:cookie 在平时生活中的运用
步骤2:什么是cookie
步骤3:setCookie.jsp
步骤4:getCookie.jsp
步骤5:cookie原理示意图

步骤 1 : cookie 在平时生活中的运用

有的网站,登陆的时候,会出现一个选项,问你是否要一周内或者一个月内保持登陆状态。
如果你选了,那么一周之内,都不需要再输入账号密码。
这个功能,就是靠cookie来实现的

步骤 2 : 什么是cookie

Cookie是一种浏览器和服务器交互数据的方式。
Cookie是由服务器端创建,但是不会保存在服务器。
创建好之后,发送给浏览器。浏览器保存在用户本地。
下一次访问网站的时候,就会把该Cookie发送给服务器。

步骤 3 : setCookie.jsp

在web目录下创建一个文件 setCookie.jsp

Cookie c = new Cookie("name", "Gareen");

创建了一个cookie,名字是"name" 值是"Gareen"

c.setMaxAge(24 * 60 * 60);

表示这个cookie可以保留一天,如果是0,表示浏览器一关闭就销毁

c.setPath("/");

Path表示访问服务器的所有应用都会提交这个cookie到服务端,如果其值是 /a, 那么就表示仅仅访问 /a 路径的时候才会提交 cookie

response.addCookie(c);

通过response把这个cookie保存在浏览器端
访问地址:

http://127.0.0.1/setCookie.jsp

通过HTTP调试工具也可以在Cookies这一栏看到

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

<%

Cookie c = new Cookie("name", "Gareen");

c.setMaxAge(60 * 24 * 60);

c.setPath("/");

response.addCookie(c);

%>

<a href="getCookie.jsp">跳转到获取cookie的页面</a>

步骤 4 : getCookie.jsp

在web目录下创建文件getCookie.jsp
然后访问网页:

http://127.0.0.1/getCookie.jsp

Cookie[] cookies  = request.getCookies();

表示获取所有浏览器传递过来的cookie

if (null != cookies )

如果浏览器端没有任何cookie,得到的Cookie数组是null

for (int d = 0; d <= cookies.length - 1; d++) {

out.print(cookies[d].getName() + ":" + cookies[d].getValue() + "<br>");

}

遍历所有的cookie
可以看到name:Gareen,这个在setCookie.jsp中设置的cookie
注; JSESSIONID 这个不是我们自己设置的cookie,这是tomcat设置的cookie,会在下一章session的学习中用到
通过HTTP调试工具也可以看到浏览器在请求信息里提交了这个Cookie。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

<%

Cookie[] cookies = request.getCookies();

if (null != cookies)

for (int d = 0; d <= cookies.length - 1; d++) {

out.print(cookies[d].getName() + ":" + cookies[d].getValue() + "<br>");

}

%>

步骤 5 : cookie原理示意图


步骤1:健身房的储物柜
步骤2:什么是Session
步骤3:setSession.jsp
步骤4:getSession.jsp
步骤5:Session和Cookie的关系
步骤6:Session 原理示意图
步骤7:如果没有cookie,session如何工作
步骤8:session的有效期

步骤 1 : 健身房的储物柜

考虑这个场景:
李佳汜到健身房去练胸肌,首先领了钥匙,然后进了更衣间,把衣服,裤子,手机,钱包都放在盒子里面。
毛竞也到健身房,去练翘臀。首先领了钥匙,然后 进了更衣间,把衣服,裤子,手机,《Java 21天从入门到精通》也放在了一个盒子里,但是这个盒子是和李佳汜的是不同的。
健身房,就相当于服务器,盒子,就是会话Session。
切换到我们常见的购物网站的场景
李佳汜登陆天猫之后,在购物车里看到的物品是蜡烛和皮鞭
毛竞登陆天猫之后,在购物车里看到的物品是手铐和《Java 21天从入门到精通》

步骤 2 : 什么是Session

Session对应的中文翻译是会话。 
会话指的是从用户打开浏览器访问一个网站开始,无论在这个网站中访问了多少页面,点击了多少链接,都属于同一个会话。 直到该用户关闭浏览器为止,都属于同一个会话。

步骤 3 : setSession.jsp

session.setAttribute("name", "teemo");

session对象保存数据的方式,有点像Map的键值对(key-value)
"name"是键,"teemo" 是值

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

<%

session.setAttribute("name", "teemo");

%>

<a href="getSession.jsp">跳转到获取session的页面</a>

步骤 4 : getSession.jsp

session.getAttribute("name");

通过session,根据"name" 取出对应的名称

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

<%

String name = (String)session.getAttribute("name");

%>

session中的name: <%=name%>

步骤 5 : Session和Cookie的关系

回到健身房的储物柜这一段:
李佳汜和毛竞都有自己的盒子,那么他们怎么知道哪个盒子是自己的呢? 
通过钥匙就能找到自己的盒子了。
盒子对应服务器上的Session。
钥匙对应浏览器上的Cookie。

步骤 6 : Session 原理示意图

步骤 7 : 如果没有cookie,session如何工作

如果浏览器把cookie功能关闭,那么服务端就无法获取jsessionid,每一次访问,都会生成一个新的session对象。
为了解决这个问题,可以使用

response.encodeURL("getSession.jsp")

response.encodeURL方法会把getSession.jsp这个url转换为

getSession.jsp;jsessionid=22424AEA86ADBE89F335EEB649D997A8

通过这个方式,提交jsessionid到服务器。 服务器根据这个jsessionid匹配到对应的session. 与session相关的功能,就可以正常工作了。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

<%

session.setAttribute("name", "teemo");

%>

<a href="<%=response.encodeURL("getSession.jsp")%>">跳转到获取session的页面</a>

步骤 8 : session的有效期

比如登录一个网站,登录后,在短时间内,依然可以继续访问而不用重新登录。
但是较长时间不登录,依然会要求重新登录,这是因为服务端的session在一段时间不使用后,就失效了。
这个时间,在Tomcat默认配置下,是30分钟。
可以通过 d:/tomcat/conf/web.xml 中的session-config 配置进行调整


JSP有4个作用域,分别是 
pageContext 当前页面 
requestContext 一次请求 
sessionContext 当前会话 
applicationContext 全局,所有用户共享

步骤1:pageContext
步骤2:requestContext 
步骤3:requestContext与服务端跳转
步骤4:requestContext与客户端跳转
步骤5:sessionContext 
步骤6:applicationContext

步骤 1 : pageContext

准备setContext.jsp和getContext.jsp,分别表示向作用域设置数据,和从作用域获取数据。
pageContext表示当前页面作用域
通过pageContext.setAttribute(key,value)的数据,只能在当前页面访问,在其他页面就不能访问了。

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

pageContext.setAttribute("name","gareen");

%>

<%=pageContext.getAttribute("name")%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=pageContext.getAttribute("name")%>

步骤 2 : requestContext

requestContext 表示一次请求。随着本次请求结束,其中的数据也就被回收。
常用写法是

request.setAttribute("name","gareen");

request.getAttribute("name")

但是也可以用pageContext来做,写成

pageContext.setAttribute("name","gareen",pageContext.REQUEST_SCOPE);

pageContext.getAttribute("name",pageContext.REQUEST_SCOPE)

不过不常用

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

request.setAttribute("name","gareen");

%>

<%=request.getAttribute("name")%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=request.getAttribute("name")%>

步骤 3 : requestContext与服务端跳转

requestContext指的是一次请求
如果发生了服务端跳转,从setContext.jsp跳转到getContext.jsp,这其实,还是一次请求。 所以在getContext.jsp中,可以取到在requestContext中设置的值
这也是一种页面间传递数据的方式

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

request.setAttribute("name","gareen");

%>

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

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=request.getAttribute("name")%>

步骤 4 : requestContext与客户端跳转

客户端跳转,浏览器会发生一次新的访问,新的访问会产生一个新的request对象。
所以页面间客户端跳转的情况下,是无法通过request传递数据的。

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

request.setAttribute("name","gareen");

response.sendRedirect("getContext.jsp");

%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=request.getAttribute("name")%>

步骤 5 : sessionContext

sessionContext 指的是会话,从一个用户打开网站的那一刻起,无论访问了多少网页,链接都属于同一个会话,直到浏览器关闭。 
所以页面间传递数据,也是可以通过session传递的。
但是,不同用户对应的session是不一样的,所以session无法在不同的用户之间共享数据。
与requestContext类似的,也可以用如下方式来做

pageContext.setAttribute("name","gareen",pageContext.SESSION_SCOPE);

pageContext.getAttribute("name",pageContext.SESSION_SCOPE)

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

session.setAttribute("name","gareen");

response.sendRedirect("getContext.jsp");

%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=session.getAttribute("name")%>

步骤 6 : applicationContext

applicationContext 指的是全局,所有用户共享同一个数据
在JSP中使用application对象, application对象是ServletContext接口的实例
也可以通过 request.getServletContext()来获取。
所以 application == request.getServletContext() 会返回true
application映射的就是web应用本身。
与requestContext类似的,也可以用如下方式来做

pageContext.setAttribute("name","gareen",pageContext.APPLICATION_SCOPE);

pageContext.getAttribute("name",pageContext.APPLICATION_SCOPE)

  • setContext.jsp
  • getContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%

application.setAttribute("name","gareen");

System.out.println(application == request.getServletContext());

response.sendRedirect("getContext.jsp");

%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%=application.getAttribute("name")%>


JSP的隐式对象指的是不需要显示定义,直接就可以使用的对象,比如request,response 
JSP一共有9个隐式对象,分别是 
request,response,out 
pageContext, session,application 
page,config,exception

步骤1:request,response,out
步骤2:pageContext, session,application
步骤3:page
步骤4:config
步骤5:exception

步骤 1 : request,response,out

这三个已经很熟悉了
request 代表请求 请参考 request常见方法
response 代表响应 请参考 response 用法
out 代表 输出

步骤 2 : pageContext, session,application

pageContext 代表当前页面作用域
session 代表当会话作用域
application 代表当全局作用域
更多的关于作用域的请参考 作用域

步骤 3 : page

page 对象即表示当前对象
JSP 会被编译为一个Servlet类 ,运行的时候是一个Servlet实例。 page即代表this

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

page:<%=page%>

<br>

this:<%=this%>

步骤 4 : config

config可以获取一些在web.xml中初始化的参数。
在JSP中使用config比较复杂,需要如下几个步骤
1. 在web.xml中进行配置
2. 创建一个testconfig.jsp
通过config.getInitParameter("database-ip") 获取参数
3. 访问路径,获取web.xml中配置的参数

http://127.0.0.1/testconfig

注1: 不能通过 http://127.0.0.1/testconfig.jsp 获取参数,只能通过/testconfig路径
注2:这种用法不常见,不推荐使用

  • web.xml片段
  • testconfig.jsp

<servlet>

<!-- 把 testconfig.jsp配置为一个 servlet -->

<servlet-name>testconfig</servlet-name>

<jsp-file>/testconfig.jsp</jsp-file>

<!-- 配置初始化参数 -->

<init-param>

<param-name>database-ip</param-name>

<param-value>127.0.0.1</param-value>

</init-param>

</servlet>

<!-- 将路径 testconfig映射到testconfig.jsp -->

<servlet-mapping>

<servlet-name>testconfig</servlet-name>

<url-pattern>/testconfig</url-pattern>

</servlet-mapping>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

database-ip: <%=config.getInitParameter("database-ip")%>

步骤 5 : exception

exception 对象只有当前页面的<%@page 指令设置为isErrorPage="true"的时候才可以使用。
同时,在其他页面也需要设置 <%@page 指令 errorPage="" 来指定一个专门处理异常的页面。
1. 准备一个try.jsp
设置errorPage="catch.jsp",表示有异常产生的话,就交给catch.jsp处理
故意在里面造成数组越界异常
2. 准备一个catch.jsp
设置 isErrorPage="true",表示当前页面可以使用exception对象

  • try.jsp
  • catch.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" errorPage="catch.jsp"%>

<%

int[] a = new int[10];

a[20] = 5;

%>

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isErrorPage="true"%>

<%=exception%>


JSTL JSP Standard Tag Library 标准标签库 
JSTL允许开人员可以像使用HTML标签 那样在JSP中开发Java功能。 
JSTL库有core, i18n, fmt, sql 等等。 
i18n和sql用的很少,core和fmt在工作中会用到,本章节主要讲解core和fmt

步骤1:导入jar包
步骤2:set out remove
步骤3:if else
步骤4:choose
步骤5:forEach
步骤6:forTokens
步骤7:fmt:formatNumber 格式化数字
步骤8:fmt:formatDate 格式化日期
步骤9:fn:

步骤 1 : 导入jar包

为了能够在JSP 中使用JSTL,首先需要两个jar包,分别是jstl.jar 和standard.jar
可以在右侧下载
把这两个jar包放在web/WEB-INF/lib 下

步骤 2 : set out remove

在页面中使用JSTL需要在jsp中 通过指令进行设置

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

prefix="c" 表示后续的标签使用都会以<c: 开头

<c:set var="name" value="${'gareen'}" scope="request" />

在作用域request中设置name,相当于
<%request.setAttribute("name","gareen")%>

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

相当于 <%=request.getAttribute("name")%>

<c:remove var="name" scope="request" />

在作用域request中删掉name,相当于
<%request.removeAttribute("name")%>
作用域可以是pageContext, request, session, application, 参考 作用域

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

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

<c:set var="name" value="${'gareen'}" scope="request" />

通过标签获取name: <c:out value="${name}" /> <br>

<c:remove var="name" scope="request" /> <br>

通过标签获取name: <c:out value="${name}" /> <br>

步骤 3 : if else

JSTL通过<c:if test=""> 进行条件判断
但是JSTL没有<c:else,所以常用的办法是在<c:if的条件里取反
配合if使用的还有通过empty进行为空判断
empty可以判断对象是否为null,字符串长度是否为0,集合长度是否为0

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<c:set var="hp" value="${10}" scope="request" />

<c:if test="${hp<5}">

<p>这个英雄要挂了</p>

</c:if>

<c:if test="${!(hp<5)}">

<p>这个英雄觉得自己还可以再抢救抢救</p>

</c:if>

<%

pageContext.setAttribute("weapon", null);

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

pageContext.setAttribute("items", new ArrayList());

%>

<c:if test="${empty weapon}">

<p>没有装备武器</p>

</c:if>

<c:if test="${empty lastwords}">

<p>挂了也没有遗言</p>

</c:if>

<c:if test="${empty items}">

<p>物品栏为空</p>

</c:if>

步骤 4 : choose

虽然JSTL没有提供else标签,但是提供了一个else功能的标签

<c:choose>

<c:when test="${hp<5}">

</c:when>

<c:otherwise>

</c:otherwise>

</c:choose>

我个人觉得看上去繁琐,还是习惯用<c:if test="!" 来表示else

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<c:set var="hp" value="${3}" scope="request" />

<c:choose>

<c:when test="${hp<5}">

<p>这个英雄要挂了</p>

</c:when>

<c:otherwise>

<p>这个英雄觉得自己还可以再抢救抢救</p>

</c:otherwise>

</c:choose>

步骤 5 : forEach

可以在JSP中使用for循环,但是其可读性很差。 借助JSTL的c:forEach标签,可以改善可读性
在本例中,分别使用for循环和<c:forEach标签来演示遍历一个List的区别

<c:forEach items="${heros}" var="hero" varStatus="st"  >

items="${heros}" 表示遍历的集合
var="hero" 表示把每一个集合中的元素放在hero上
varStatus="st" 表示遍历的状态

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<%

List<String> heros = new ArrayList<String>();

heros.add("塔姆");

heros.add("艾克");

heros.add("巴德");

heros.add("雷克赛");

heros.add("卡莉丝塔");

request.setAttribute("heros",heros);

%>

<!-- 使用jsp中的for循环来遍历List -->

<table width="200px" align="center" border="1" cellspacing="0">

<tr>

<td>编号</td>

<td>英雄</td>

</tr>

<%

int i =0;

for (String hero : heros) {

i++;

%>

<tr>

<td><%=i%></td>

<td><%=hero%></td>

</tr>

<%}%>

</table>

<br>

<!-- 使用JSTL中的c:forEach 循环来遍历List -->

<table width="200px" align="center" border="1" cellspacing="0">

<tr>

<td>编号</td>

<td>英雄</td>

</tr>

<c:forEach items="${heros}" var="hero" varStatus="st"  >

<tr>

<td><c:out value="${st.count}" /></td>

<td><c:out value="${hero}" /></td>

</tr>

</c:forEach>

</table>

步骤 6 : forTokens

<c:forTokens专门用于字符串拆分,并且可以指定多个分隔符

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<c:set var="heros" value="塔姆,艾克;巴德|雷克赛!卡莉丝塔" />

<c:forTokens items="${heros}" delims=":;|!" var="hero">

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

</c:forTokens>

步骤 7 : fmt:formatNumber 格式化数字

fmt 标签常用来进行格式化,其中fmt:formatNumber用于格式化数字
使用之前要加上

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

<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>

<fmt:formatNumber 表示格式化数字
minFractionDigits 小数点至少要有的位数
maxFractionDigits 小数点最多能有的位数

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

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

<c:set var="money" value="888.8" />

<c:set var="pi" value="3.1415926" />

最少两个小数点:

<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>

<br>

最多两个小数点:

<fmt:formatNumber type="number" value="${pi}" maxFractionDigits="2" />

步骤 8 : fmt:formatDate 格式化日期

fmt 标签常用来进行格式化,其中fmt:formatDate 用于格式化日期
和fmt:formatNumber 格式化数字一样,使用之前要加上

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

<fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/>

<fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/>

<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>

<fmt:formatDate 表示格式化日期
yyyy 表示年份
MM 表示月份
dd 表示日期
E 表示星期几
a 表示是上午还是下午
HH 表示小时
mm 表示分钟
ss 表示秒
S 表示毫秒
z 表示时区

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

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

<%

Date now = new Date();

pageContext.setAttribute("now",now);

%>

完整日期: <fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/><br>

完整时间: <fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/><br>

常见格式: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>


EL表达式非常好用,好用的吓死人 ~

步骤1:取值
步骤2:作用域优先级
步骤3:JavaBean概念
步骤4:获取JavaBean的属性
步骤5:结合JSTL的<c:forEach
步骤6:取参
步骤7:eq

示例 1 : 取值

不同版本的tomcat是否默认开启对EL表达式的支持,是不一定的。
所以为了保证EL表达式能够正常使用,需要在<%@page 标签里加上isELIgnored="false"
使用EL表达式,非常简单
比如使用JSTL输出要写成

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

但是用EL只需要

${name}

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false"%>

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

<c:set var="name" value="${'gareen'}" scope="request" />

通过标签获取name: <c:out value="${name}" /> <br>

通过 EL 获取name: ${name}

示例 2 : 作用域优先级

EL表达式可以从pageContext,request,session,application四个作用域中取到值,如果4个作用域都有name属性怎么办? 
EL会按照从高到低的优先级顺序获取 
pageContext>request>session>application

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false"%>

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

<c:set var="name" value="${'gareen-pageContext'}" scope="page" />

<c:set var="name" value="${'gareen-request'}" scope="request" />

<c:set var="name" value="${'gareen-session'}" scope="session" />

<c:set var="name" value="${'gareen-application'}" scope="application" />

4个作用域都有name,优先获取出来的是 : ${name}

示例 3 : JavaBean概念

EL可以很方便的访问JavaBean的属性,那么JavaBean是什么呢? 
JavaBean的标准
1. 提供无参public的构造方法(默认提供)
2. 每个属性,都有public的getter和setter
3. 如果属性是boolean,那么就对应is和setter方法
比如示例代码中的Hero类,默认提供了一个无参的public的构造方法。 同时每个属性都有getter和setter

package bean;

public class Hero {

public int id;

public String name;

public float hp;

public int damage;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public float getHp() {

return hp;

}

public void setHp(float hp) {

this.hp = hp;

}

public int getDamage() {

return damage;

}

public void setDamage(int damage) {

this.damage = damage;

}

}

示例 4 : 获取JavaBean的属性

获取JavaBean的属性,只需要通过.符号操作就可以了。
像这样 ${hero.name} ,就会自动调用getName方法了
注: 如果属性是boolean类型,那么就会自动调用isXXX方法了

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" isELIgnored="false" import="bean.*"%>

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

<%

Hero hero =new Hero();

hero.setName("盖伦");

hero.setHp(616);

request.setAttribute("hero", hero);

%>

英雄名字 : ${hero.name} <br>

英雄血量 : ${hero.hp}

示例 5 : 结合JSTL的<c:forEach

EL还可以结合 JSTL的<c:forEach 使用,进一步简化代码
原代码中的

<c:out value="${hero}" />

可以简写为

${hero}

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<%

List<String> heros = new ArrayList<String>();

heros.add("塔姆");

heros.add("艾克");

heros.add("巴德");

heros.add("雷克赛");

heros.add("卡莉丝塔");

request.setAttribute("heros",heros);

%>

<table width="200px" align="center" border="1" cellspacing="0">

<tr>

<td>编号</td>

<td>英雄</td>

</tr>

<c:forEach items="${heros}" var="hero" varStatus="st"  >

<tr>

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

<td>${hero}</td>

</tr>

</c:forEach>

</table>

示例 6 : 取参

EL表达式还可以做到request.getParameter("name") 这样的形式获取浏览器传递过来的参数
先把jstl.jsp代码改为如例所示,然后访问如下地址

http://127.0.0.1/jstl.jsp?name=abc

可以观察到获取了参数 name

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>

${param.name}

示例 7 : eq

进行条件判断,大大简化了 JSTL的 c:if 和 c:choose 代码
如例,一行代码就能起到其他好几行代码的效果

${killNumber ge 10? "超神":"还没超神" }

例子中讲的是大于等于,除此之外的其他用法如下:
eq相等 ne、neq不相等,
gt大于, lt小于
gt大于, lt小于
gte、ge大于等于 
lte、le 小于等于 
not非 mod求模 
is [not] div by是否能被某数整除 
is [not] even是否为偶数 
is [not] odd是否为奇

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8" import="java.util.*"%>

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

<%

request.setAttribute("killNumber", "10");

%>

c:if 的用法,运行结果:

<c:if test="${killNumber>=10}">

超神

</c:if>

<c:if test="${killNumber<10}">

还没超神

</c:if>

<br>

c:choose 的用法,运行结果:

<c:choose>

<c:when test="${killNumber>=10}">

超神

</c:when>

<c:otherwise>

还没超神

</c:otherwise>

</c:choose>

<br>

EL表达式eq的用法,运行结果:

${killNumber ge 10? "超神":"还没超神" }

最详细的jsp基础教程相关推荐

  1. 简单计算机唱歌教学,【Da老师】最简单详细的唱歌基础教程

    原标题:[Da老师]最简单详细的唱歌基础教程 基础教程如下: 气息的初级入门大体分为基础的三个阶段 1,气量控制:此时横膈膜(横膈膜不是随意肌,要借助其他肌肉帮助)不一定有什么感觉,别想太多,但是肌肉 ...

  2. JSP基础教程:熟悉JSP服务器

    本篇文章由 泉州SEO www.234yp.com 整理发布,jsp入门教程 www.234yp.com/Article/176258.html 谢谢合作! jsp入门教程 熟悉JSP服务器 本&qu ...

  3. git的详细用法和基础教程

    Git 是当前最流行的版本控制程序之一,文本包含了 Git 的一些基本用法 创建 git 仓库 初始化 git 仓库 mkdir project  # 创建项目目录  cd project  # 进入 ...

  4. 【Javaweb】JSP基础教程

    文章目录 JSP简介 JSP工作原理 JSP生命周期 JSP注释 JSP中嵌套Java代码 JSP语法 中文编码问题 脚本程序 声明变量 表达式 指令 Page指令 Include指令 Taglib指 ...

  5. JSP学习笔记之基础教程

    JSP基础教程 什么是JSP JSP概念:Java 服务器页面 (Java Server Page ,JSP) 以扩展名== .jsp== 保存 在HTML中嵌入Java脚本语言 由应用服务器中的JS ...

  6. (四)DSP28335基础教程——SCI串口通信实验(上位机收发显示)

    0 前言 本期的实验目的为:使用核心板上的SCI串口通信功能,在电脑端上位机,输入数字0,1,2,3,4,分别控制五个LED亮灭. 1 DSP代码 (注意:查看代码时双击点进去看,否则会内容不全). ...

  7. 最后一篇,小白看的Python基础教程,详细得很(十一)

    @Author:Runsen 往期回顾: 第一篇.小白看的 Python 基础教程,详细得很(八) 第二篇.小白看的 Python 基础教程,详细得很(九) 第三篇.小白看的 Python 基础教程, ...

  8. 【MySQL基础教程】DML语句详细介绍

    前言 本文为 [MySQL基础教程]DML语句详细介绍 相关知识,DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增.删.改操作.下 ...

  9. vue2+vue3小白零基础教程—vue2篇,全网2021最详细教程

    vue教程 提示:Vue3系列请参考Vue2+Vue3小白零基础教程-vue3篇文章,本文为vue2篇. 1. Vue核心 1.1 Vue简介 1.1.1 Vue是什么 一套用于构建用户界面的渐进式J ...

  10. Git最详细的基础教程

    Git最详细的基础教程 Git简介 Git是什么 SVN与Git的最主要的区别 在windows上安装Git 下载安装Git 配置Git Git的基本使用 创建版本库. 版本回退 理解工作区与暂存区的 ...

最新文章

  1. 菜鸟配置SAMBA服务之4
  2. 一文看懂机器视觉芯片 ​
  3. 让nginx支持php和path_info(新版本)
  4. 在手机网页中使用USEMAP
  5. Win32 API 多线程编程示例 - 窗口版
  6. 微服务架构如何保证安全性?
  7. esxi5.1 添加vSwitch,转VM network to new vSwitch
  8. pivot 与 unpivot函数
  9. mysql插入数据显示:Incorrect datetime value: '0000-00-00 00:00:00'
  10. 小米球Ngrok-使用方法
  11. Matplotlib:科研绘图利器(写论文、数据可视化必备)
  12. SimpleBGC三轴云台用户手册
  13. 计算机缓存加速网络,教你win7怎么清理缓存为电脑提速
  14. 无验证码不扫码拼多多微信批量登陆思路
  15. 带上紧箍咒,特斯拉辅助驾驶系统即将更新
  16. 浅谈《英雄杀》5人局之反贼技巧
  17. 模拟量使用计算机电缆,远东电缆关于计算机电缆选型应用的友情提醒
  18. quick-and-dirty如何翻译
  19. 数据库 Oracle分区介绍
  20. spi ioctl无效参数解决

热门文章

  1. 正交试验设计例题及答案_正交试验设计与数理统计作业.doc
  2. 模糊c-均值聚类算法(FCM)
  3. ipython安装过程_IPython安装过程 @win7 64bit
  4. 共享单车调度_共享单车的调度算法
  5. Django框架基础知识(面试题)
  6. 【软件相关】CATIA v5R20使用技巧
  7. SDRAM控制器设计(8)SDRAM控制器仿真验证
  8. 机器人顶会RSS 2021各奖项出炉,CMU华人博士生摘得最佳论文
  9. fft算法的c语言实现,快速傅立叶变换(FFT)算法(蝶形算法)的C/C++源代码(zz)
  10. 1、锐捷交换机常用配置命令汇总,收藏备用!