# JSP
JSP——Java Server Page:Java服务端页面,在html页面中编写Java代码的页面。
绝大多数时候,我们希望响应的不是简简单单一句话,而是一个页面,我们用PrintWriter对象去写一个页面也是可以的,但缺点太明显。
所以直接返回一个页面,并且能够写Java代码就能大大简化我们的开发,这就是——JSP。
JSP是简化Servlet编写的一种技术,它将Java代码和HTML语句混合在同一个文件中编写,只对网页中的要动态产生的内容采用Java代码来编写,而对固定不变的静态内容采用普通静态HTML页面的方式编写。
***
### 建立对JSP的直观认识
在JSP页面中编写的Java代码需要嵌套在<%和%>中,嵌套在<%和%>之间的Java代码被称之为**脚本片段**(Scriptlets),没有嵌套在<%和%>之间的内容被称之为JSP的**模版元素**。
JSP文件就像普通的HTML文件一样,它们可以放置在WEB应用程序中的除了WEB-INF及其子目录外的其他任何目录中,JSP页面的访问路径与普通HTML页面的访问路径形式也完全一样。
在JSP页面中也可以使用一种称之为JSP表达式的元素,只需将要输出的变量或表达式直接封装在<%= 和 %>之中,就可以向客户端输出这个变量或表达式的运算结果。在JSP表达式中嵌套的变量或表达式后面不能有分号。
WEB容器(Servlet引擎)接收到以.jsp为扩展名的URL的访问请求时,它将把该访问请求交给JSP引擎去处理。
每个JSP 页面在第一次被访问时,JSP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的class类文件,然后再由WEB容器(Servlet引擎)像调用普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的Servlet程序——JSP本质上就是一个Servlet。
新建一个jsp页面hello.jsp
~~~
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
Date date = new Date();
System.out.println(date);
%>
</body>
</html>
~~~
运行可以看到控制台上有时间输出。
***
### JSP中9个隐式对象(重点)
隐式对象(或隐含变量):在JSP当中我们没有手动声明创建,但实际存在,可以直接使用的对象。
~~~
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;
// 还有request和response以及exception对象,一共9个
~~~
①**request**:客户端的请求信息被封装在request对象中,通过它才能了解用户的需求,然后做出响应
②response:包含了响应客户请求的有关信息,但在JSP中使用很少
③pageContext:页面的上下文,是PageContext的一个对象,可以从该对象中获取到其他8个隐含对象,也可以获取到当前页面的其他信息
④**session**:指的是客户端与服务器的一次会话,从客户端连到服务器的一个WebApplication开始,知道客户端与服务器断开连接为止
⑤**application**:代表当前web应用,是ServletContext对象,能实现用户间数据的共享,可存放全局变量,它开始于服务器的启动,直到服务器的关闭,在此期间,此对象一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命周期
⑥config:当前JSP对应的Servlet的ServletConfig对象,可获取该Servlet的初始化参数(开发时基本不用),需要通过映射的地址才可以。
⑦**out**:JspWriter对象,调用out.println()可以直接把字符串打印到浏览器上
⑧page:page对象就是指向当前JSP页面本身,类型为Object,有点类似于类中的this,几乎不使用
⑨exception:该对象是一个例外对象,只有页面是一个错误页面,即isErrorPage设置为true的时候(默认为false)才能使用,否则无法编译。
#### **注意:JSP可以放置在WEB应用程序中的除了WEB-INF及其子目录外的其他任何目录中**
***
### JSP模板元素
JSP页面中的静态HTML内容称之为JSP模版元素(比如html,body等等),在静态的HTML内容之中可以嵌套JSP的其他各种元素来产生动态内容和执行业务逻辑。
JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。
***
### JSP表达式
JSP表达式(expression)提供了将一个java变量或表达式的计算结果输出到客户端的简化方式,它将要输出的变量或表达式直接封装在<%= 和 %>之中。
~~~
<body>
<%
Date date = new Date();
%>
<%= date %>
</body>
~~~
***
### JSP脚本片断
像片段一样的JSP表达式,但整体必须是完整的
~~~
<body>
<%
String ageStr = request.getParameter("age");
int age = Integer.parseInt(ageStr);
if(age > 18){
%>
成年....
<% }else{ %>
未成年...
<% } %>
</body>
~~~
***
### JSP注释
~~~
<%--
<%= new Date() %>
--%>
~~~
~~~
<!--
<%= new Date() %>
-->
~~~
能够阻止Java代码运行,html注释则没有此功能
***
### 属性相关方法
①设置属性:void setAttribute(String name,Object o)
②获取指定属性:Object getAttribute(String name)
作为了解
③获取所有的属性的名字组成的Enumeration对象:Enumeration getAttributeNames()
④移除指定的属性:removeAttribute(String name)
#### 域对象
**能够使用这些方法的对象有4个:
pageContext,request,session,application-->这4个对象也称为域对象**
新建jsp书写一下代码运行测试
~~~
<body>
<%
pageContext.setAttribute("pageAttr", "pageValue");
request.setAttribute("requestAttr", "requestValue");
session.setAttribute("sessionAttr", "sessionValue");
application.setAttribute("applicationAttr", "applicationValue");
%>
<h2>Page1</h2>
pageContextAttr:<%= pageContext.getAttribute("pageAttr") %>
<br><br>
requestAttr:<%= request.getAttribute("requestAttr") %>
<br><br>
sessionAttr:<%= session.getAttribute("sessionAttr") %>
<br><br>
applicationAttr:<%= application.getAttribute("applicationAttr") %>
<br><br>
<a href="attr_2.jsp">to Page 2</a>
</body>
~~~
正常的得到当前jsp的属性。
![](https://box.kancloud.cn/95f3df504eb21f2fc5d3f5e7aa330abb_412x318.png)
点击超链接,跳转的attr_2.jsp
![](https://box.kancloud.cn/d3305f95e8de52c875793144ec192390_389x302.png)
pageContext:属性的作用范围仅限于当前JSP页面
request:属性的作用范围仅限于同一个请求
session:属性的作用范围限于一次会话(浏览器打开直到关闭,称为一次会话,前提是在此期间会话没有失效)
关闭浏览器,直接去attr_2.jsp发现
![](https://box.kancloud.cn/71be3476e52935bd160dd91617c9d89e_308x282.png)
application:属性的作用范围限于当前WEB应用,是范围最大的属性作用范围,只要在一处设置属性,在其他各处的JSP或Servlet中都可以获取,直到服务器关闭。
但学到这里其实还不能做什么,当有了请求转发和请求重定向将威力无穷。
***
### **请求转发和请求重定向(绝对重点)**
#### 一.请求转发
请求转发需要借助于一个接口,RequestDispatcher接口 ,利用这个接口的forward方法实现请求转发。
#### 二.请求重定向
用HttpServletResponse的sendRedirect方法实现请求重定向。
***
请求转发
~~~
<body>
<a href="forwardServlet">Forward</a>
</body>
~~~
~~~
@WebServlet("/forwardServlet")
public class ForwardServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ForwardServlet's doGet");
// 请求转发
// 1.调用HttpServletRequest的getRequestDispatcher()方法获得RequestDispatcher对象
// 调用getRequestDispatcher()需要传入要转发的地址(/代表当前WEB应用的根目录)
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/testServlet");
// 2.调用HttpServletRequest的forward(request,response)进行请求转发
requestDispatcher.forward(request, response);
}
}
~~~
~~~
@WebServlet("/testServlet")
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("TestServlet's doGet方法");
}
}
~~~
运行html,点击查看控制台
![](https://box.kancloud.cn/3bd2cf976d0305502456fd6cba9f4782_317x182.png)
***
请求重定向
~~~
<body>
<a href="forwardServlet">Forward</a>
<a href="redirectServlet">Redirect</a>
</body>
~~~
~~~
@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("RedirectServlet's doGet");
response.sendRedirect("testServlet");
}
}
~~~
再次运行html,点击Redirect,查看控制台
![](https://box.kancloud.cn/8e6280fa02be464c6cda2288a3c8f914_332x196.png)
貌似与请求转发没什么区别,但实际区别非常之大。
观察用请求转发和请求重定向时地址栏的变化
请求转发地址栏没变
![](https://box.kancloud.cn/69d3eaa451dff07b194e6cd6d865f21d_467x35.png)
请求重定向地址栏变化了
![](https://box.kancloud.cn/8635c80d473d6f14365543fe9db4e4a2_408x35.png)
说明一个重要问题(本质区别):
**请求转发只发出了一个请求
请求重定向发出了连个请求**
#### 验证:
~~~
@WebServlet("/forwardServlet")
public class ForwardServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ForwardServlet's doGet");
// 设置一个属性
request.setAttribute("name", "yzn");
// 请求转发
// 1.调用HttpServletRequest的getRequestDispatcher()方法获得RequestDispatcher对象
// 调用getRequestDispatcher()需要传入要转发的地址(/代表当前WEB应用的根目录)
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/testServlet");
// 2.调用HttpServletRequest的forward(request,response)进行请求转发
requestDispatcher.forward(request, response);
}
}
~~~
~~~
@WebServlet("/testServlet")
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object name = request.getAttribute("name");
System.out.println(name);
}
}
~~~
同样的,使用请求重定向,再次发出请求,发现得不到RedirectServlet中设置的属性,说明请求不是同一个。
**发现能够得到在ForwardServlet中设置的属性,说明请求是同一个请求**
***
~~~
@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("RedirectServlet's doGet");
request.setAttribute("name", "yzn111");
response.sendRedirect("testServlet");
}
}
~~~
***
### 在JSP中也可以实现的请求转发和重定向,但实际意义不大
***
#### **重要知识点:**
1.POST和GET的区别:
1)Get 是用来从服务器上获得数据,而Post 是用来向服务器上传递数据;
2)Get 将表单中数据按照variable=value 的形式,添加到action 所指向的 URL 后面,并且两者使用“?”连接,而各个变量之间使用“&”连接;Post 是将 表单中的数据放在form 的数据体中,按照变量和值相对应的方式,传递到action 所指向URL;
3)Get 是不安全的,因为在传输过程,数据被放在请求的URL 中;Post 的 所有操作对用户来说都是不可见的;
4)Get 传输的数据量小,这主要是因为受URL 长度限制;而Post 可以传输大量的数据,所以在上传文件只能使用Post;
2.请求转发及请求重定向的区别:
①请求转发实际上是问题的转发,在跳转的过程中并没有响应客户端,在源和目标之间是可以用request对象进行传值的;请求重定向在跳转的过程中实际上是响应了客户端了,客户端发送了两次请求,不能够使用request进行传值;
②客户端可以看到请求重定向目标资源的URL,不能看到请求转发目标资源的URL;
③请求转发速度快,请求重定向速度慢;
④请求转发只能访问站内资源,而请求重定向可以定位到站外资源(比如 百度);
⑤请求转发:/代表的是当前WEB应用的根目录;请求重定向:/代表的是当前WEB站点的根目录(http://localhost:8080/)
- 第一章 配置和安装Tomcat
- 第二章 Servlet(一)
- 第三章 Servlet(二)
- 练习 一 . Servlet配置级获取初始化参数
- 第四章 JSP(一)
- 第五章 JSP(二)
- 第六章 MVC设计模式
- 第七章 Cookie
- 第八章 Session
- 练习 二 . 简易版购物车
- 第九章 EL表达式
- 第十章 JSTL
- 第十一章 过滤器
- 第十二章 监听器
- 第十三章 文件的上传与下载
- 复习总结
- 如何手动启动Tomcat
- 如何修改Tomcat端口号
- 如何在web.xml中配置Servlet
- Servlet生命周期
- load-on-startup参数
- Servlet映射路径
- POST和GET的区别
- JSP中9个隐式对象及功能
- 请求转发及请求重定向的区别
- JSP指令有哪些
- 简述对MVC设计模式的理解
- 简述Cookie机制
- 简述Session机制
- HttpSession的生命周期
- Cookie和Session有什么区别
- 简述创建过滤器步骤
- 过滤器经典案例--统一编码字符集
- getParameter与getAttribute的区别
- JSP页面中可以包含哪些元素
- web应用中,是如何跟踪用户的
- InteliJ创建web项目