二、JSP技术介绍

JSP

前言

在web开发中,服务器利用网络,将数据通过IO流的形式传输给浏览器。但是,浏览器,只支持超文本标记语言,多种数据。例如:HTML,CSS,Javascript,音频和视频等等。而然,不管是哪种数据,都是通过HTTP协议传输给浏览器,且常用的数据是HTML相关数据。所以,WEB开发,需要将原生数据,组装成HTML语言类型的数据,然后再传输给浏览器。此时,JavaWeb的设计发现,开发相对麻烦。因为对原生数据进行加工时,在做重复的工作,且工作量相对较大。基于这样大的原因,JavaWeb利用,模板技术,将公共部分进行封装,然后再公共部分中进行解析动态的数据,这样就形成一套模板技术,例如:freemarker,Thymeleaf,Velocity,jsp等等。而JSP这个模板技术,是Java自身的。

jsp引入.png

1.JSP介绍

1.1.什么是JSP

JSP(全称JavaServer Pages)是由[Sun Microsystems](https://baike.baidu.com/item/Sun Microsystems)公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。

JSP通俗而言,就是一个可以书写Java代码的页面技术。JSP本质其实一个类。

1.2.JSP的特征

JSP本质是一个类,所以在JSP页面中,代码默认是自上而下执行的,且需要书写Java代码时,必须使用<%%>或者

<%= %>包裹,注意,<% %> 中包裹的代码会当做Java代码进行执行,而<%=%> 包裹的代码会将代码运算结果输出到页面。

设置JSP页面编码.png

例如:

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




jsp demo


<%
    /* 会执行的java代码 */
    System.out.print("元宵快乐");
    String message = "元宵快乐";
%>

<%=message %>

9*9乘法表

<% for(int i=1;i<=9;i++){ for(int m = 1;m<=i;m++){ String str = i+"*"+m +"="+i*m+" "; %> <%=str %> <% } %>
<% } %>

注意: 被<%%>包裹的是Java代码

效果1.png

1.3.jsp为什么能写java代码

因为所有的jsp页面,在第一个被访问时,会被翻译成一个对应的java文件,jsp名称作为java文件名前缀,使用_jsp进行拼接的java文件。然后,会将java文件进行编译产生class文件,再将编译后的字节码文件加载到JVM中进行运行。

每一个jsp,都会被翻译成一个实现了servlet接口的类,所以所有的jsp本质上是一个类,且是一个Servlet类。jsp中的内容,被这个类中的_jspService方法进行了处理。在这个方法中,获取了一个对应的输出流对象,这个输出流对象会将jsp页面中内容,默认当做字符串进行流输出。当遇到<%%>包裹的内容时,会当做java代码不进行输出。会将<%=%>包裹的内容,使用输出流进行打印(会使用print进行打印输出,writer只能输出字符串之类的类型,而print可以输出任意类型,而被输出的java内容,可能是任意类型,所以不能使用writer)。这样就生成 了一个HTML页面。

翻译示例:

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    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("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("jsp demo\r\n");
      out.write("\r\n");
      out.write("\r\n");

    /* 会执行的java代码 */
    System.out.print("元宵快乐");// 在控制台打印。     System.out  和  out  
    String message = "元宵快乐";// 定义了一个变量

      out.write("\r\n");//  换行   2行 
      out.write("\r\n");
      out.print(message );
      out.write("\r\n");
      out.write("

9*9乘法表

\r\n"); for(int i=1;i<=9;i++){ for(int m = 1;m<=i;m++){ String str = i+"*"+m +"="+i*m+"         "; out.write("\t\r\n"); out.write("\t\r\n"); out.write("\t"); out.print(str ); out.write('\r'); out.write('\n'); out.write(' '); } out.write("\t\r\n"); out.write("\t\r\n"); out.write("\t\t
\r\n"); out.write("\t"); } out.write("\r\n"); out.write("\r\n"); out.write("\r\n"); out.write(""); } 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); } }

1.4.JSP案例

由于JSP本质是一个类,那么在一个类中调用另外一个类中方法是理所当然的。那么,使用JSP将数据库中的数据呈现在页面。

使用JSP,将数据库中数据展示现在页面。

<%@page import="com.sxt.pojo.Student"%>
<%@page import="java.util.List"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="com.sxt.dao.StudentDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




学生信息列表



 <%
    /* 在jsp中  一样需要 import 包   ,在jsp中使用 alt+/ */
    Map param = new HashMap();
    //调用dao层方法  获取数据库中所有学生数据
    List sts = new StudentDao().selectList(param);
 %>
 
 <%
    for(int i=0;i

<%} %>
 
ID 学号 名称 性别 年龄 总分
<%=st.getId() %> <%=st.getStNo() %> <%=st.getName() %> <%=st.getSex() %> <%=st.getAge() %> <%=st.getScore() %>

效果:

列表示例1.png

注意: 此时JSP页面就充当了View(视图,界面)的角色。

1.5.JSP的作用

在web中,JSP可以转化为WEB页面,所以JSP可以充当视图,界面。用于,与用户进行交互。JSP还能接收用户的请求,且对这个请求作出处理,生成动态数据相关web网页,且将网页数据返回给客户端。用户的请求request,用户请求的是服务器。

tomcat处理服务请求.png

1.6.JSP九大内置对象

tomcat在处理jsp页面时,会自动生成9个对象(内建对象),所以被称之为9大内置对象:

对象名 类型 描述
request javax.servlet.http.HttpServletRequest 用于处理客户端的请求的对象,服务器将请求信息都封装在这个对象中
response javax.servlet.http.HttpServletResponse 用于向客户端作出响应的对象。可以通过该对象,向客户端作出数据响应
pageContext javax.servlet.jsp.PageContext 当前页面容器对象,包含其它内置对象
config javax.servlet.ServletConfig Servlet配置对象,每个JSP都是一个Servlet,可以通过该对象获取初始化配置参数
page java.lang.Object 表示当前jsp对应的类对象
application javax.servlet.ServletContext 表示整个应用的容器的对象
session javax.servlet.http.HttpSession 表示当前会话的,会话对象
out javax.servlet.jsp.JspWriter 表示一个输出对象,可以将数据输出到页面
exception java.lang 表示一个异常对象,当JSP页面发生异常时,异常信息就会封装在该对象中

注意: 以上九大内置对象需要默写下来,因为9大内置对象,属于面试的内容之一。

9大内置对象,可以在JSP页面直接使用。

<%
    /*  request对象 
        此时是没有创建  request 对象的
        如果一下打印语句  不为null 那说明,程序中内部存在request对象
        request 对象是用于 处理客户端的请求信息的对象 request 对象 代表就是客户端的请求信息
        客户端的请求信息 都被封装在该对象中
    */
    System.out.println(request);
    // getParameter("name") :  根据名称  获取对应的请求参数的值 ,name就是请求参数的key
    System.out.println(request.getParameter("name"));
    System.out.println(request.getParameter("age"));
    /* response 对象 用于向客户端作出响应数据的对象 */
    System.out.println(response);
    // 获取与客户端相关联的输出流对象   字符流
    PrintWriter pw = response.getWriter();
    //pw.print("元宵节快乐!!!");
    //字节流  这个用于向客户端输出 非文本信息的数据   多媒体数据
    //ServletOutputStream  os = response.getOutputStream();
    /*pageContext : 当前页面容器。 该容器包含,其他内置对象   */
    System.out.println("pageContext:"+pageContext);
    System.out.println("request:"+pageContext.getRequest());
    System.out.println("response:"+pageContext.getResponse());
    /*config 对象  具体的讲解  待  servlet时进行讲解*/
    /*page 对象: 表示当前jsp对应类的对象*/
    System.out.println("page:"+page);
    /*application对象  : 表示当前应用一个全局容器对象  注意,整个应用启动时就会创建该对象,有且只有一个*/
    System.out.println("application对象:"+application);
    /*session对象: 表示与当前请求关联的会话对象,一个会话包含多个请求,默认会话对象有效30分钟,一般会话对象
        从第一次就浏览器请求,到关闭浏览器窗口(30分钟内)
    */
    System.out.println("session对象:"+session);
    /* out对象:根据当前response对象,获取的一个输出对象,用于将一般的数据输出给客户端  */
    out.print("元宵节快乐!!!");
%>

1.7.四大作用域

1.7.1.什么是作用域?

域:范围。作用域: 有效的范围。

1.7.2.四大作用域

在JSP中,9大内置对象由于某些内置对象的特殊性,区分出了4大作用域,如下:

对象名 作用域 描述
pageContext 当前页面 在pageContext中存储的数据,只能被当前页面获取到
request 一次请求 在request中存储的数据,在同一次请求中可以获取到
session 一次会话 在session中存储的数据,在同一次会话中可以获取到
application 当前应用 在application中存储的数据,在当前应用中生效

注意:所有作用域对象,有一些功能的方法:存储数据/获取数据/删除数据等

setAttribute(name, value) :向作用域中存储数据,以key-value的形式存储

getAttribute("name") :从作用域中获取数据

removeAttribute(“name”):从作用域中删除数据,根据name作为key,从容器中删除数据

4大作用域讲解1.png

1.7.3.pageContext与request

pageContext的范围,是单纯当前页面,而request的返回是一次请求,一次请求可以包含多个页面。

可以通过内部转发的形式,将一个请求传递到另外一个页面中,此时一次请求可能经历多个页面。所以就是一个请求可以包含多个页面。

注意:

根据以上分析:四大作用于,其范围从小到大:pageContext --- > request ---> session ----> application作用域的意义,在于存储数据,进行数据传递。那么在程序开发,若需要将数据进行传输,需要使用4大作用域。4个作用域,根据其范围,也有其特定的生命周期,最大的作用域,生命周期其贯穿整个程序,任何人都能访问。若数据存在里面,不安全。session,作用域,是同一次会话,session默认是30分钟,只要创建session对象,那么这个对象就会驻留在内存中30分钟。可能存在浪费内存的行为,一般用于处理,多次请求的数据,会将多次请求需要使用的共享数据放入session。request对象,一般用于同一次请求中,不同地址间的数据传输。若在其他页面(地址)需要使用当前一些数据,可以存在request中,使用内部转发,跳转到指定的地址。pageContext作用,一般不做业务数据的存储,只用于获取其他内置对象。所以,在程序开发中,尽量选择作用域范围小的作用域对象。节约资源。

1.7.4.内部转发和重定向

在之前的例子中,可以使用:内部转发

request.getRequestDispatcher("地址").forward(request, response);

进行页面跳转,而且还可以进行数据传输.这种跳转方式被称之为内部转发。JavaWeb还提供了一种方式,重定向:重定向

response.sendRedirect("地址");

以上两种方式都可以实现页面跳转。那么差别在哪里:

比较 重定向 内部转发
URL地址栏 地址栏会发生改变 地址栏不会发生改变
参数传递 不能将request作用域数据进行传递 可以将request作用域中数据进行传递
浏览器请求 会通知浏览器进行多次请求 服务器内部处理,只需要一次请求
重定向与内部转发.png

思考:重定向和内部转发都能实现地址的跳转,需要进行地址跳转时,使用哪种?

重定向与内部转发对比而言,内部转发在数据的传递上更具优势,所以若涉到数据传递,就优先使用内部转发。但是,使用内部转发的程序,一旦发生页面刷新。期间,所有已经执行过的程序,会重新执行。容易造成服务器的压力和异常,其根本原因,是因为浏览器URL地址栏,没有发生改变,所以刷新后,会重新请求。

而重定向,会改变浏览器URL地址栏上的地址,所以刷新时,没有相关问题,所以,若要实现地址的跳转,优先使用重定向,若涉及到数据的传输,重定向无法满足,考虑使用内部转发。

你可能感兴趣的:(二、JSP技术介绍)