尚硅谷的古老视频第二弹
本文实在是没有什么价值,2013 年 7 月的视频,教学内容也不更新一下,我晕,老师也懒得不行,吐槽一下。
2020 年 7 月 8 日 :为什么没有 1 2 3 ?因为老师的视频里也没有
4.请求的转发和重定向:
1).本质区别:请求的转发只发出了一次请求,而重定向则发出了两次请求。
①. 请求的转发: 地址栏是初次发出请求的地址。
请求的重定向: 地址栏不再是初次发出的请求地址。地址栏为最后响应的那个地址
②. 请求的转发: 在最终的Servlet 中,request 对象和中转的那个request 是同一个对象.
请求的重定向: 在最终的Servlet中,request 对象和中转的那个request不是同一个对象.
③. 请求的转发:只能转发给当前WEB应用的的资源
请求的重定向:可以重定向到任何资源。
④. 请求的转发: /代表的是当前WEB应用的根目录
请求的重定向: /代表的是当前WEB站点的根目录,
5. JSP: Java Server Page
1). WHY:
JSP是简化Servlet编写的一种技术,它将 Java 代码和 HTML 语句混合在同-一个文件中编写, 只对网页中的要动态产生的内容采用 Java 代码来编写,面对固定不变的静态内容采用普通静态 HTML 页面的方式编写.
简而言之,就是 Servlet 是在 java 中写 HTML,JSP 是在 HTML 中写 java
2). helloworld:
新建一个JSP页面,在body节点内的<% %>即可编写Java代码.
<body>
<%
Date date = new Date();
System.out.print(date);
%>
</body>
3). JSP 可以放置在 WEB 应用程序中的除了 WEB-INF 及其子目录外的其他任何目录中, JSP 页面的访问路径与普通 HTML 页面的访问路径形式也完全一样。
原因是它是隐私文件
4). JSP 的运行原理: JSP 本质上是一个Servlet.
每个 JSP 页面在第一次被访问时,JSP 引擎将它翻译成一个 Servlet 源程序,接着再把这个 Servlet 源程序编译成 Servlet 的 class 类文件.
然后再由 WEB 容器(Servlet引擎)像调用普通 Servlet 程序一样的方式来装载和解释执行这个由 JSP 页面翻译成的 Servlet 程序。
5). 隐含变量
JSP 页面一共有九个隐含变量。这篇文章解释得很详细👉jsp中的九大隐含对象和EL中的隐含对象,我就不照搬了。
<%--
Created by IntelliJ IDEA.
User: Admin
Date: 2020/7/7
Time: 11:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
hello
<a href="servLet/Servlet">超链接</a>
<%
// JSP 页面的隐含对象
// ① request: HttpServletRequest
String name = request.getParameter("name");
System.out.println(name);
// ② response: HttpServletResponse, 几乎不调用 response 的任何方法
Class clazz = response.getClass();
System.out.println(clazz);
// ③ pageContext: 页面的上下文,可以获取其它 8 个隐含对象
ServletRequest req = pageContext.getRequest();
System.out.println(req == request);
// ④ session: HttpSession
System.out.println(session.getId()); // 这号每次都一样,所以可以保持服务器和客户端的通信。
// ⑤ application: 代表当前 WEB 应用。是 ServletContext 对象。
System.out.println(application.getInitParameter("password"));
// ⑥ config: 当前 JSP 对应的 Servlet 的 ServletConfig对象 (几乎不使用)
// 路径是 <url-pattern>/hellojsp</url-pattern>
System.out.println(config.getInitParameter("test")); // 在 web.xml 中配置的名为 test 的 Servlet
// ⑦ out:JspWriter 对象
out.print(request.getParameter("name"));
out.print("<br>"); // 换行
// ⑧ page:指向当前 JSP 对应的 Servlet 对象的引用,但为 object 类型,只能调用 object 类的方法(几乎不使用)
System.out.println(this);
System.out.println(page);
// ⑨ exception: 特殊情况下使用。在声明了page指令的isErrorpage= "true"时,才可以使用。
<%--<%@ page isErrorPage="true" %>--%>
%>
</body>
</html>
6. JSP 基本语法
6). JSP 模板元素:JSP 页面中的静态 HTML 内容
7). JSP 表达式:将变量直接输出到页面上
<%= 变量 %>
8). JSP 脚本片段(scriptlet) :是指嵌套在 <%
和 %>
之中的一条或多条Java程序代码。多个脚本片断中的代码可以相互访问。
9). JSP 声明:JSP声明将Java代码封装在 <%
和 %>
之中,它里面的代码将被插入进 Servlet 的 _jspService 方法的外面。
这个功能几乎不用,了解即可。
<%!
void test() {
// ...
}
%>
10). JSP 注释
<%-- JSP 的注释 --%>
7. 和属性相关的方法
虽然可能这些用的比较多,但是我觉得不是很重要,上网随便搜一搜到处都是。
1).方法
Object getAttribute(String name): 获取指定的属性
Enumeration getAttributeNames(): 获取所有的属性的名字组成的Enumeration对象
removeAttribute(String name): 移除指定的属性
void setAttribute(String name, object o):设置属性
2). pageContext, request, session, application 对象都有这些方法!
这四个对象也称之为域对象。
pageContext: 属性的作用范围仅限于当前JSP页面。
request: 属性的作用范围仅限于同一个请求。
session:属性的作用范围限于一次会话: 浏览器打开直到关闭称之为一次会话
(在此期间会话不失效)
application: 属性的作用范围限于当前WEB应用。
是范围最大的属性作用范围,只要在一处设置属性,
在其他各处的JSP或Servlet中都可以获取。
8. 请求的重定向和请求的转发
以下知识非常重要!吓唬一下先。
RequestDispatcher接口实现请求的转发
用forward方法实现请求转发
请求转发的运行流程
用sendRedirect方法实现请求重定向
请求重定向的运行流程
请求重定向与请求转发的比较
// 一、请求的转发
// 1. 调用 HttpServletRequest 的 getRequestDispatcher() 方法
// 获取 RequestDispatcher
String path = "testServlet";
RequestDispatcher requestDispatcher = req.getRequestDispatcher(path);
// 2. 调用 HttpServletRequest 的 forward(request, response) 进行请求的转发。
requestDispatcher.forward(req, resp);
// 二、请求的重定向
resp.sendRedirect(path);
感觉这老师讲的有点乱,主要原因可能是我很困,所以我听不下去了。
直接上网搜一搜别人的总结,或者等自己开始着手写项目再继续研究。
9. JSP指令
<%@ ... %>
(1)page 指令
1). page指令用于定义JSP页面的各种属性, 无论page指令出现在JSP页面中的什么地方, 它作用的都是整个JSP页面, 为了保持程序的可读性和遵循良好的编程习惯, page指令最好是放在整个JSP页面的起始位置。
2). page 指令常用的属性:
①. import 属性: 指定当前 JSP 页面对应的 Servlet 需要导入的类.
<%@page import="java.text.DateFormat"%>
②. session 属性: 取值为 true 或 false, 指定当前页面的 session 隐藏变量是否可用, 也可以说访问当前页面时是否一定要生成 HttpSession对象.
<%@ page session="false" %>
③. errorPage 和 isErrorPage:
errorPage 指定若当前页面出现错误的实际响应页面是什么。其中 / 表示的是当前 WEB 应用的根目录. <%@ page errorPage="/error.jsp" %>
在响应 error.jsp 时, JSP 引擎使用的请求转发的方式.
isErrorPage
指定当前页面是否为错误处理页面, 可以说明当前页面是否可以使用 exception
隐藏变量. 需要注意的是: 若指定 isErrorPage="true"
, 并使用 exception 的方法了, 一般不建议能够直接访问该页面.
如何使客户不能直接访问某一个页面呢 ? 对于 Tomcat 服务器而言, WEB-INF 下的文件是不能通过在浏览器中直接输入地址的方式 来访问的. 但通过请求的转发是可以的!
还可以在 web.xml 文件中配置错误页面:
<error-page>
<!-- 指定出错的代码: 404 没有指定的资源, 500 内部错误. -->
<error-code>404</error-code>
<!-- 指定响应页面的位置 -->
<location>/WEB-INF/error.jsp</location>
</error-page>
OR
<error-page>
<!-- 指定异常的类型 -->
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/WEB-INF/error.jsp</location>
</error-page>
④. contentType: 指定当前 JSP 页面的响应类型. 实际调用的是 response.setContentType("text/html; charset=UTF-8")
;通常情况下, 对于 JSP 页面而言其取值均为 text/html; charset=UTF-8
.
charset
指定返回的页面的字符编码是什么. 通常取值为 UTF-8
⑤. pageEncoding: 指定当前 JSP 页面的字符编码. 通常情况下该值和 contentType 中的 charset 一致.
⑥. isELIgnored: 指定当前 JSP 页面是否可以使用 EL 表达式
. 通常取值为 true.
(2)include 指令
include 指令: <%@ include file="b.jsp" %>
1). include 指令用于通知 JSP 引擎在翻译当前 JSP 页面时将其他文件中的内容合并进当前 JSP 页面转换成的 Servlet 源文件中,这种在源文件级别进行引入的方式称之为静态引入, 当前JSP页面与静态引入的页面紧密结合为一个Servlet。
2). file属性的设置值必须使用相对路径
3). 如果以 / 开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件。
10. JSP 标签
(1). jsp:incluce 标签
1). <jsp:include page="b.jsp"></jsp:include>
2). 动态引入: 并不是像 include 指令生成一个 Servlet 源文件, 而是生成两个 Servlet 源文件, 然后通过一个方法的方式把目标页面包含进来. org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "b.jsp", out, false);
(2).jsp:forward 标签
1).<jsp:forward page="/include/b.jsp"></jsp:forward>
相当于
<% request.getRequestDispatcher("/include/b.jsp").forward(request, response);%>
2). 但使用 jsp:forward 可以使用 jsp:param 子标签向 b.jsp 传入一些参数. 同样 jsp:include
也可以使用 jsp:param
子标签.
<jsp:forward page="/include/b.jsp">
<jsp:param value="abcd" name="username"/>
</jsp:forward>
OR
<jsp:include page="/include/b.jsp">
<jsp:param value="abcd" name="username"/>
</jsp:include>
在 b.
jsp 页面可以通过 request.getParameter(“username”) 获取到传入的请求参数。
(3)taglib 指令
略
11. 关于中文乱码:
1). 在 JSP 页面上输入中文, 请求页面后不出现乱码: 保证 contentType="text/html; charset=UTF-8", pageEncoding="UTF-8"
charset 和 pageEncoding 的编码一致, 且都支持中文. 通常建议取值为UTF-8 还需保证浏览器的显示的字符编码也和请求的 JSP 页面的编码一致.
2). 获取中文参数值: 默认参数在传输过程中使用的编码为 ISO-8859-1
①. 对于 POST 请求: 只要在获取请求信息之前(在调用 request.getParameter 或者是 request.getReader 等), 调用 request.setCharacterEncoding(“UTF-8”) 即可.
②. 对于 GET 请求: 前面的方式对于 GET 无效. 可以通过修改 Tomcat 的 server.xml 文件的方式. 参照 http://localhost:8989/docs/config/index.html 文档的 useBodyEncodingForURI 属性.
为 Connector 节点添加 useBodyEncodingForURI="true"
属性即可.
<Connector connectionTimeout="20000" port="8989"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
12. JavaBean (了解即可)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>get 和 set 属性实例</title>
</head>
<body>
<jsp:useBean id="students"
class="com.runoob.StudentsBean">
<jsp:setProperty name="students" property="firstName"
value="小强"/>
<jsp:setProperty name="students" property="lastName"
value="王"/>
<jsp:setProperty name="students" property="age"
value="10"/>
</jsp:useBean>
<p>学生名字:
<jsp:getProperty name="students" property="firstName"/>
</p>
<p>学生姓氏:
<jsp:getProperty name="students" property="lastName"/>
</p>
<p>学生年龄:
<jsp:getProperty name="students" property="age"/>
</p>
</body>
</html>
2020 年 7 月 9 日
13. EL 表达式
全称 Expression Language
(1) ${ ... }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL 表达式</title>
</head>
<body>
<form action="el.jsp" method="post">
username: <input type="text" name="username" value="<%= request.getParameter("username") == null ? "" : request.getParameter("username") %>">
<input type="submit" value="submit">
</form>
username: <%= request.getParameter("username") %>
OR
<form action="el.jsp" method="post">
EL表达式:username: <input type="text" name="usernameEL" value="${param.usernameEL}">
<input type="submit" value="submit">
</form>
username: <%= request.getParameter("usernameEL") %>
</body>
</html>
(2)EL 运算符
EL 运算符包括两种:.
和 []
$ { sessionScope.user.sex }
$ { sessionScope.user["sex"] }
(3)EL 变量
EL 存取变量数据的方法很简单,例如:${ username }
。它的意思是取出某一范围中 名称为 username 的变量。因为我们并没有指定哪一个范围的 username,所以它的默认值会先从 Page 范围找,假如找不到,再依序到 Request、Session、 Application 范围。假如途中找到 username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null :
(4)自动类型转换
// param.score = 89
score: ${param.score + 11} // 显示 100
score: <%= request.getParameter("score") + 11 %> // 显示 8911
(5) EL 保留字
(6) EL 隐含对象
总共有 11 个隐含对象。参考EL的隐含对象及使用
1. 与范围有关的
pageScope
pageScope隐含对象用于返回包含page(页面)范围内的属性值的集合,返回值为java.util.Map对象。例如可以通过pageScope隐含对象读取page范围内的JavaBean的属性值。
${pageScope.user.name} //获取、javaBean实例的name属性
requestScope
requestScope对象用于返回包含request(请求)范围的属性值的集合,返回值为java.util.Map对象。例:获取保存在request范围内的userName变量
<%
request.setAttribute("userName","mr"); //定义request范围内的变量userName
%>
${requestScope.userName}
sessionScope
sessionScope隐含对象用于返回包含session(会话)范围内的属性值的集合,返回值为java.util.Map对象。例:要获取保存在session范围内的manager变量,可以使用下面的代码:
<%
session.setAttribute("manager","mr"); //定义session范围内的变量manager
%>
${sessionScope.manager}
applicationScope
applicationScope隐含对象用于返回包含application(应用)范围内的属性值的集合,返回值为java.util.Map对象。例:要获取保存在application范围内的message变量,可以使用下面代码:
<%
application.setAttribute("message","欢迎光临!"); //定义application范围内的变量message
%>
${applicationScope.message}
2. 与输入有关的隐含对象
param
param对象用于获取请求参数的值,应用在参数值只有一个的情况。在应用param对像时,返回的结果为字符串。(常用于表单元素的提交后获取值)
paramValues
如果一个请求参数名对应多个值时,则需要使用paramValues对象获取请求参数的值。在应用paramValues对象时,返回的结果为数组。(例如相同name的复选框的值的获取)
3. 其他隐含对象
cookie
虽然在EL中并没有提供向cookie中保存值的方法,但是它提供了访问有请求设置的cookie的方法,这可以通过cookie隐含对象实现。如果在cookie中已经设定一个名称为username的值,那么可以使用${cookie.username}来获取该cookie对象。但如果要获取cookie中的值,需要使用cookie对象的value属性。
header
headerValues
header对象用于获取HTTP请求的一个具体的header的值,但是在有些情况下,可能存在同一个header拥有多个不同值的情况,这是就需要用headerValues对象。
initParam
initParam对象用于获取web应用初始化参数的值。(例如在web.xml文件中设置的初始化参数)
pageContext
页面上下文对象为pageContext,用于访问JSP内置对象(如request、out、session、page、exception,但不能用于获取application、config和pageContext对象)和servletContext。这些属性与对象的getXXX()方法相对应,在使用时,去掉方法中的get,并将首字母改写为小写即可。
总结代码
<a href="el2.jsp?score=89&name=A&name=B&name=C">TO EL@ Page</a>
<br>
<h4>4. 隐含对象之与范围相关的: pageScope, requestScope, sessionScope, applicationScope</h4>
<%
Date time = new Date();
application.setAttribute("time", time);
%>
time: ${ applicationScope.time } = <%= application.getAttribute("time") %>
<br>
<h4>5.与输入有关的隐含对象: param, paramValues。一路点下去就可以,Java 还需要调用方法</h4>
score = ${ param.score } = <%= request.getParameter("score") %>
<br>
names = ${ paramValues.name[0] } =
<%= request.getParameterValues("name")[0] %>
<br>
<p>目前,EL 没有遍历的能力,JSTL 才有</p>
<br>
<h4>6. 其它隐含对象</h4>
1) JSESSIONID: ${ cookie.JSESSIONID.name } -- ${ cookie.JSESSIONID.value } <br>
2) Accept-Language: ${ header["Accept-Language"] } <br>
3) 首先在 web.xml 中加入 <br>
<context-param> <br>
<param-name>initName</param-name> <br>
<param-value>RongRong</param-value> <br>
</context-param> <br>
initParam: ${ initParam.initName} <br>
4) pageContext pageContext即为PageContext类型,但只能读取属性就可以一直的点下去。<br>
contextPath: ${ pageContext.request.contextPath } <br>
sessionID: ${ pageContext.session.id } <br>
sessionAttributeNames: ${ pageContext.session.attributeNames } <br>
<h4>7. EL 关系运算符</h4>
分数: ${ param.score >= 60 ? "及格" : " 不及格" } <br>
<h4>8. EL 逻辑运算符</h4>
empty: 强大的侦测功能,可以作用于一一个集合,若该集合不存在或集合中没有元素,其结果都为true
<%
List<String> names = new ArrayList<>();
request.setAttribute("names", names);
%> <br>
names is empty: ${ empty requestScope.names } <br>
代码运行结果