Java EE day12学习总结

今天主要学习JSP基础

思维导图:

Java EE day12学习总结

 

一.JSP的概念:

JSP的全名是Java Server Pages,他的一个建立在Servlet的规范上推出一个动态网页的开发技术,在JSP上,HTML代码可以和Java代码共同存在。其中html代码负责的是网页的静态内容,java代码负责是网页的动态内容,为了区分他和html的区别,所以命名为jsp,其实jsp本质上不是一个网页而是一个java类。

二.JSP执行原理:

JAVA代码和我们的HTML代码的混合运行,既然可以在JSP页面直接去写Java代码,那么我们之前学的Servlet还有存在的意义吗?两种是互补行为,不是取代行为。

 1.浏览器访问了服务器的demo.jsp

2.Tomcat会根据URL去寻找你的jsp

3.会将找到的jsp加载到Tomcat当中

 4.Tomcat会将这个jsp翻译成一个Java文件

(Tomcat会调用org.apache.jasper.runtime.HttpJspBase这个类文件,对我们的jsp进行编译其实HttpJspBase这个类除了可以对jsp进行编译,同时还继承了HttpServlet,那么也就意味着我之前说过的一句话(Servlet的所有技术都是适用在JSP的/JSP也是一个建立在Servlet标准的基础上进行开发)所以说,JSP不单单可以写HTML代码,可以写Java代码,甚至还可以直接编写Servlet的实现代码)

 5.翻译成java文件之后(_demo_jsp.java),然后会对这个文件进行编译(_demo_jsp.class)

6.Tomcat就会去调用这个类

【tomcat自动调用,无法干预(Eclipse的存储位置在tomcat/work/..、IDEA的存储位置在C:\Users\IntellijIdeaxxx\system\tomcat\xxx...)】

7.输出到浏览器

(所谓的输出到浏览器,就是内部将一个静态HTML使用out.write()的方式进行写出,Java代码就按照正常类方式进行处理)

8.总结:

(1)jsp之所以能够编写HTML代码,其实本质上也是依靠类似于我们Servlet的response.getWriter().println()方法进行输出的

(2)jsp之所以能够直接的使用request,不用像我们之前写Servlet的时候那样去继承然后重写doGet,是因为HttpJspBase这个类从一开始就已经继承了HttpServlt并且实现了service等方法

 

三.编译的过程(JSP的生命周期):

1.翻译成java文件

2.编译成class文件

3.执行构造方法

4.执行_jspInit方法,完成的JSP的初始,顺便完成Servlet的初始化

5.执行_jspService方法,跟Servlet的逻辑一致

 6.执行_jspDestroy方法,在本JSP完全结束后销毁

 

四.JSP的语法:

1.注释:

(1)JSP注释:

            <%-- 我是一个JSP的注释 --%>

(2)HTML注释:

            <!-- 我是一个HTML的注释 -->

(3)结论:

这两个注释都会正常生效,但是HTML代码的注释 会直接显示在浏览器当中(浏览器是可以读到只是不执行)而JSP的注释,浏览器不会读、也不会执行,也就意味 JSP的注释比HTML的注释更加的安全,如果你不想让用户看到你的注释内容,建议使用JSP的注释。

2.如何在JSP当中书写我们的java代码:

(1)JSP的动态输出:

                <%= 输出的内容 %>

作用:就是向页面输出一些内容,但是这里的语句必须是有返回值的只要在System.out.print()能够输出的内容,他可以输出。

原理:其实就是调用了out.print()这个方法

(2)JSP的代码脚本:

                <% java代码 %>

作用:可以在这里面编写任意的Java代码,作用域跟我们之前写的Java类是完全一致的(编写除成员方法之外的所有代码)

原理:会通过tomcat翻译成一个java文件,在编译成class文件,这里是不能书写成员方法

3.JSP的变量声明:

                <%! 变量或者方法 %>

作用:用于生成一个成员变量和成员方法(只能编写成员变量和成员方法)

原理:就是编译的时候,将这里的代码声明在成员位置

 

4.在页面输出10次hello(是页面不是控制台):

其实在页面当中,java脚本是可以拆分执行,比如下面

<%for (int i = 0; i < 10; i++) {%>

                        <span>hello</span><br/>

<%}%>

但是一般千万不要这样去执行,因为会导致前端和后端都不看懂代码,以后会有一些表达式帮我们解决这样的问题。

5.JSP的指令:

JSP指令是一个为JSP引擎设计的一个用于设置JSP内容的一个属性(有点类似我们之前在HTML里面学的head是差不多)这里面的内部并不会输出或显示在页面,只是处理JSP一些设置性的东西。

6.JSP指令的语法:

<%@ 指令名 属性名="值"%>

举例:

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

注意:

因为这个指令本质还是一些Java代码的设置的,所以会有一定程度上的大小写敏感问题,注意下这个问题

7.JSP指令的分类:

在JSP2.0版本当中,提供三个指令,page、include、taglib。每一个指令都有自己独立的语法和属性设置。

(1)page:

 <%@ page

                        language="java"

                        import="java.util.*"

                        import="java.util.*"

                        session="true"

                        buffer="8kb"

                        errorPage="/error.jsp"

                        isErrorPage="true"

                        pageEncoding="utf-8"

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

                        isELIgnored="true"

 %>

language="java":告诉服务器以一个什么样的编程语言来解析文件的内容

import="java.util,*":跟我们之前写java代码导包是一样的,如果是多个包的导入使用逗号分隔

session="true":控制当前页面是否开启一个session,如果是true则代表开启,其实本质上就是去调用了一个session的对象使用

buffer="8kb":控制当前页面的缓冲区大小(跟我们之前学的BufferedWriter是一致的),jsp页面里面的内容并不会立即的输出到页面当中,而是等页面的缓冲大小达到指定大小,或者关闭或者加载完毕之后,才会输出。

errorPage="/error.jsp"当页面发生异常的时候,转发到的指定的页面。(一般不太常用,因为每一个页面都需要去写,而且没有办法根据不同的错误状态转发到不同的页面显示)建议在web.xml里面配置一个全局的错误跳转

                      <error-page>

                            <error-code>错误状态码1</error-code>

                            <location>/需要跳转的页面(可以是本地,也可以是网址)</location>

                        </error-page>

                        <error-page>

                            <error-code>错误状态码2</error-code>

                            <location>/需要跳转的页面(可以是本地,也可以是网址)</location>

                        </error-page>

isErrorPage="true":是否指定当前页面为错误显示页面,如果指定则会在发生错误之后,直接在本页面显示一个错误信息(调用了一个exception对象)否则不会创建(默认的操作的就是这个)

pageEncoding="utf-8":设置当前页面的内容以什么样的字符集编码翻译成java类

contentType="text/html;charset=UTF-8":设置当前页面的内容以什么样的字符集编码传输到浏览器(跟我们之前写Servlet的时候,设置的response.setContentType("text/html;charset=UTF-8")完全一致的也就意味的,如果设置了这个属性,在JSP页面当中凡是响应给浏览的内容就不需要单独设置字符集了)

isELIgnored="true":设置页面是否忽略EL表达式

(2)include:

        <%@ include

            file="header.jsp

        "%>

include指令主要是用于通知JSP在翻译本页面的同时,也去翻去其他被导入的文件,并且合并在同一个页面进行执行;一个页面当中,嵌套包含另外一个页面,这种又被称之为静态导入[包含](可以动态资源,也可以是静态资源)

(3)taglib:暂时不讲,后面马上讲到。

五.JSP的内置(隐藏)九大对象:

   重要:

(1)HttpServletRequest request:请求对象,其实用的就是Servlet的,原理一致[作用域]

(2)HttpServletResponse response:响应对象,其实用的就是Servlet的,原理一致

(3)ServletContext application:上下文对象,其实用的就是Servlet的,不过改了个名字 叫做application(Servlet叫做ServletContext)[作用域]

(4)ServletConfig config:配置对象,其实用的就是Servlet的,其实用的就是Servlet的

(5)HttpSession session:会话作用域,用于一个会话数据存储[作用域]

  了解:

(6)PageContext pageContext:JSP作用域,这个作用域只能在本jsp当中有效[作用域]【因为这九大对象都是隐藏的,JSP直接调用的,如果想获取这九大对象的具体实例,可以通过如下方法获取】

//返回的是页面输出一些异常信息对象(默认的错误页面其实就是他调用的)

pageContext.getException();

//返回的paga对象(可以理解一个Object对象)

pageContext.getPage();

//返回的是一个在本JSP当中生效的一个请求对象

ServletRequest request1 = pageContext.getRequest();

//返回的是一个在本JSP当中生效的一个响应对象

pageContext.getResponse();

//返回的是一个在本JSP当中生效的一个Servlet配置对象

pageContext.getServletConfig();

//返回的是一个在本JSP当中生效的一个ServletContext上下文对象

pageContext.getServletContext();

//返回的是一个在本JSP当中生效的一个Session对象

pageContext.getSession();

//返回的是一个在本JSP当中生效的一个JspWriter对象

pageContext.getOut();

(7)JspWriter out:用于jsp输出的对象,<%= %>就是使用的这个对象

(8)Object page:其实就是一个本页面的对象,或者可以理解为调用了Object的方法

(9)Throwable exception:异常输出对象,用于JSP页面的异常输出

六. JSP的四大作用域:

我们要知道,在Servlet当中一共有三个作用域(request/servletContext/session)。但是JSP不但实现的Servlet的三大作用域,自己还有一个特有的pageContext作用域,也就是说Servlet有三大作用域,而JSP有四大作用域。

四大作用域的比较:

(1)pageContext(JSP作用域):

                作用范围:只在当前JSP页面当中有效

                开始时间:页面被加载的时候

                结束时间:页面刷新或者离开

(2)request(请求作用域):

                作用范围:在一个请求(链)当中有效

                开始时间:收到请求

                结束时间:响应完毕

(3)session(会话作用域):

                 作用范围:同一个会话当中有效

                 开始时间:会话开始

                 结束时间:会话结束

(4)application(上下文作用域):

                作用范围:在一个Web项目当中有效

                开始时间:项目被运行

                结束时间:项目被结束

 

pageContext:

添加数据:

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

添加数据到指定作用域:

                pageContext.setAttribute("age",10,pageContext.REQUEST_SCOPE);

 

                pageContext不但可以将数据保存到page域,同样也可以保存到其他域

                        PAGE_SCOPE:默认,JSP作用域

                        REQUEST_SCOPE:请求作用域

                        SESSION_SCOPE:会话作用域

                        APPLICATION_SCOPE:全局作用域

 

获取数据:

                pageContext.getAttribute("name");

从指定作用域获取数据:

                pageContext.getAttribute("age",pageContext.REQUEST_SCOPE);

                 PAGE_SCOPE:默认,JSP作用域

                 REQUEST_SCOPE:请求作用域

                 SESSION_SCOPE:会话作用域

                 APPLICATION_SCOPE:全局作用域

 

 

搜索作用域:

                 pageContext.findAttribute("name");

                 在JSP的四个作用域当中,去寻找一个叫做name的数据,默认从小到大去寻找,一旦找到就返回

 

移除作用域:

                pageContext.removeAttribute("name");

移除其他作用域的数据

                pageContext.removeAttribute("name",pageContext.REQUEST_SCOPE);

总结:

<1>作用域从小到大的排序应该是pageContext < request  < session  <  application在实际开发当中,最小和最大的我们一般都不太常用,特别是pageContext。

<2>pageContext:作用域范围太小,没有转发 也就意味着存储的数据永远只能在一个页面当中

<3>application:作用域范围太大,一个WEB当中,可能有无数个Servlet,也可以有无数个程序员一个数据存到application当中,作用范围太大 就不能保证你数据的稳定性,很有可能被其他程序员无意篡改或者冲突。

<4>JSP的基础:

                JSP的执行原理(写个JSP代码->翻译->编译->执行)

                JSP的语法(JSP的表达式,JSP的输出,JSP的声明)

                JSP的九大内置对象(笔记看)

                JSP的四大作用域(笔记看,Servlet只有三大作用域)

                JSP的三大指令(include,page,taglib)

                JSP和Servlet的工作区别:(重点)

                 JSP:负责将Servlet的结果转换为一个页面动态数据的展示

                 Servlet:负责从JSP将数据取到后端

<5>注意:虽然我们现在学到了JSP,但是我们仍然不建议太广泛去使用JSP。因为JSP里面不但嵌套了前端代码,也嵌套了JAVA代码,也就造成了前端和后端混合开发在前端代码里面写上太多的JAVA代码其实是不明智的,你看不懂前端,前端也看不懂后端。在以后,我们会慢慢的将前端和后端进行代码的分离(前后端分离开发)。