0%

【JavaWeb】JSP

JavaWeb关于JSP页面的学习


1 介绍

1.1 基本介绍

  • JSP:java server page
  • 作用:代替servlet程序回传html页面数据
    • 因为servlet程序回传html页面数据是非常繁琐的事情,开发成本和维护成本极高

1.2 servlet回传页面数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// servlet
public class PrintHtmlServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 动态返回页面
resp.setContentType("text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("<!DOCTYPE html>\r\n");
writer.write("<html lang=\"en\">\r\n");
writer.write("<head>\r\n");
writer.write(" <meta charset=\"UTF-8\">\r\n");
writer.write(" <title>Title</title>\r\n");
writer.write("</head>\r\n");
writer.write("<body>\r\n");
writer.write(" 这里是要动态显示在页面的数据,html是静态页面,数据是写死的\r\n");
writer.write("</body>\r\n");
writer.write("</html>\r\n");
}
}
1
2
3
4
5
6
7
8
<servlet>
<servlet-name>printHtmlServlet</servlet-name>
<servlet-class>com.letere.jsp.servlet.PrintHtmlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>printHtmlServlet</servlet-name>
<url-pattern>/printHtml</url-pattern>
</servlet-mapping>
  • 由此例子可知,用servlet动态返回页面数据,十分麻烦,因此引入JSP来返回动态数据页面

1.3 JSP本质

  • JSP页面本质是一个Servlet程序
  • (1)在我们访问jsp页面时,会自动生成一个jsp的java文件,以及其编译class文件
  • (2)查看源码发现index_jsp.java继承HttpJspBase,而HttpJspBase继承HttpServlet
  • (3)简单查看index_jsp.java源码,跟上面演示的servlet程序写法类似
  • 综上所述:JSP的本质就是一个servlet程序

2 Page指令

1
2
3
4
5
6
7
8
9
10
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8"
language="java"
pageEncoding="UTF-8"
autoFlush="true"
buffer="8kb"
errorPage="/errorPage.html"
isErrorPage="false"
session="true"
extends="java.util.List" %>
  • 属性介绍
  • import:跟java一样,导入包,类
  • contentType:jsp返回的数据类型,即源码中response.setContentType()的参数值
  • language:jsp翻译后的语言文件,目前只支持java
  • autoFlush:out输出流缓冲区满后是否自动刷新,默认true
  • buffer:缓冲区大小,默认8kb
  • errorPage:设置页面报错后跳转错误页面位置,/即以web目录开头的相对路径
  • isErrorPage:当前页面是否错误页面,默认false。true源代码多出一个Execption类
  • session:访问页面时,是否创建HttpSession对象,默认true
  • extends:生成的java文件默认继承的类,不建议修改

3 脚本

3.1 声明脚本

  • 语法<%! 声明的java代码 %>
  • 作用:jsp可以翻译出java定义的类属性、静态代码块,方法和内部类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<%!
// 声明类属性
public static String name;

// 声明静态代码块
static {
name = "你好";
}

// 声明类方法
public void hello() {
System.out.println("Hello World!");
}

// 声明内部类
public class InnerClass {
public String sex;
}
%>
</body>
  • 声明脚本会将代码填写到jsp生成的java文件中,仅做声明,不执行

3.2 表达式脚本

  • 语法<%=表达式%>
  • 作用:在Jsp页面上输出数据,数据可以是一个变量或对象
1
2
3
4
5
6
<body>
<%!public String name = "456";%>

<%= 123 %>
<%= name %>
</body>
  • 表达式脚本最主要的作用还是能够输出变量
  • 注意表达式脚本不能以;,否则翻译出的代码为out.print(xxx;);,在java是错误语法

3.3 代码脚本

  • 语法<%可执行代码%>
  • 作用:Jsp页面刷新时,执行代码脚本中的代码
1
2
3
4
5
6
7
8
9
<body>
<%
Integer sum = 0;
for(int i=0; i<10; i++) {
sum += i;
}
System.out.println(sum);
%>
</body>
  • 翻译后的java代码在out.write()附近,所以当页面打印数据的时候,会调用代码脚本写的代码
  • 一个完整的Java语句,支持多个代码脚本拼接成一个完整Java语句

4 JSP九大内置对象

  • 依赖

    1
    2
    3
    4
    5
    6
    7
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
    </dependency>
  • JSP翻译成Servlet的类中,内置了9个可用的对象

  • request:请求
  • response:响应
  • pageContext:jsp上下文对象
  • session:HttpSession对象
  • exception:异常对象
  • application:ServletContext对象
  • config:ServletConfig对象
  • out:Jsp输出流对象
  • page:指向当前JSP的对象

5 JSP四大域对象

  • 在JSP九个内置对象中,有4个位域对象
  • 域对象就是像Map一样,可以存储和取出数据
  • PageContextImpl pageContext:范围 - 当前JSP页面内
  • HttpServletRequest request:范围 - 一次请求内
  • HttpSession session:范围 - 一次会话内(打开浏览器访问服务器 ~ 关闭浏览器 之间)
  • ServletContext application:范围 - 整个web工程内

6 输出流

6.1 JSP的out和response.getWriter

  • 示例1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <body>
    <%
    out.write("out输出1 <br/>");
    out.write("out输出2 <br/>");

    response.getWriter().write("response输出1 <br/>");
    response.getWriter().write("response输出2 <br/>");
    %>
    </body>
  • 说明:原本先执行的out输出,结果在末尾输出。out和response都有各自的缓存区,jsp在向页面输出内容前,会执行out.flush()方法,把out缓存区的内容加入到response缓存区的末尾,然后通过response向浏览器输出数据
  • 示例2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <body>
    <%
    out.write("out输出1 <br/>");
    out.flush(); // 手动将out缓存区内容加入到response缓存区

    out.write("out输出2 <br/>");

    response.getWriter().write("response输出1 <br/>");
    response.getWriter().write("response输出2 <br/>");
    %>
    </body>

6.2 out.print()和out.write()

  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <body>
    <%
    out.write("这是write字符串 <br/>");
    out.print("这是print字符串 <br/>");
    %>
    <br/>
    <%
    out.write(1);
    out.write("<br/>");
    out.print(1);
    %>
    </body>
  • 说明:print和write方法,在输出字符串时不会出现问题,而在输出数字时会出现乱码。是因为write方法会将int转成char然后再输出

7 JSP常用标签

7.1 静态包含

  • 将多个JSP共用的内容提取为一个单独的JSP页面,通过静态包含引入单独的JSP页面,模块化处理,减少维护成本
  • 语法<%@include file="共用的JSP页面路径"%>
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <%-- 主JSP页面 --%>
    <body>
    以下内容为引入的内容:<br/>
    <%@include file="/include/sub/sub.jsp"%>
    </body>

    <%-- 次JSP页面 --%>
    <body>
    这里是被引入的内容啊!
    </body>

7.2 动态包含

  • 动态包含的效果和静态包含的类似,但底层实现的逻辑不一样
  • 语法<jsp:include page="路径"></jsp:include>
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!-- 主JSP -->
    <body>
    动态包含:<br/>
    <jsp:include page="/include/sub/sub.jsp">
    <jsp:param name="myParam" value="你好啊"/>
    </jsp:include>
    </body>

    <!-- 次JSP -->
    <body>
    这里是动态包含的内容!<br/>
    这是接受到的参数:<%=request.getParameter("myParam")%>
    </body>
  • 动态包含特点
    • 会把包含的Jsp页面也翻译成Java代码
    • 调用方法去获取包含页面的输出信息,而不是直接将内容复制
    • 动态包含可以进行参数传递

7.3 请求转发

  • 语法<jsp:forward page="转发路径"></jsp:forward>
  • 示例
    1
    2
    3
    <body>
    <jsp:forward page="/include/sub/sub.jsp"/>
    </body>