多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 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/)