本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1、关于JSP
JSP简介
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。 JSP本质是是一种Java Servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
原理:
当浏览器向服务器请求".jsp"文件时,服务器会去查找该文件是否存在,如果存在将这个jsp文件通过jsp引擎转换为".java"文件,并使用javac对该文件进行编译,生成".class"字节码文件,让该字节码文件对外提供服务。 我们可以找到这个".java"文件并打开,文件中的类继承了"org.apache.jasper.runtime.HttpJspBase"类,我们可以再Tomcat源码中寻找这个类,发现该类继承了HttpServlet,所以JSP本质上是一种Servlet。 ".jsp"文件中的HTML页面的代码,底层是在service方法中使用Writer对象调用write方法写到页面上的。
2、脚本和声明
脚本
脚本声明用<%%>,以分号结尾
<%
out.print("这是脚本");
%>
声明和引用
声明用<%!%>,引用用<%=%>
<%!
String name="张三";
int add(int a, int b){
return a+b;
}
%>
<%="name"+name%>
<%="1+2"+add(1,2)%>
<hr>
运行结果:
3、JSP三大指令
指令 | 描述 |
---|---|
page | 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 |
include(静态包含) | 常用来嵌入页面 |
taglib | 引入标签库 |
page指令
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.HashMap" %>
key | value |
---|---|
contentType | 当前JSP页面的MIME类型和字符编码 |
language | JSP页面所用的脚本语言 |
import | 导入一些包 |
autoFlush | 控制out对象的缓存区。true:自动刷新 |
errorPage | 指定发生错误时跳转页面,配合isErrorPage="true/false"使用 |
isErrorPage | 当前页面是否是错误页面 |
- 测试errorPage和errorPage
index.jsp有错误,设置发生错误时跳转到error.jsp页面(errorPage="error.jsp")
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" %>
<%
double c=1/0;
%>
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
设置错误页面error.jsp(isErrorPage="true")
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
发生错误
</body>
</html>
配合error-page标签使用
key | value |
---|---|
error-page | 错误代码,不同的代码有不同的页面 |
location | 对应的地址 |
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
区别: errorPage="error.jsp",页面内发生错误进行跳转 标签形式:全局发生错误时进行处理
Taglib指令
JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。 Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
<%@ taglib uri="uri" prefix="prefixOfTag" %>
<!--等价的XML格式:-->
<jsp:directive.taglib attribute="value" />
include指令
常用来将其他页面引入当前页面,只能将这个页面的全部引入,如:导航栏,页脚
- 测试include指令
创建主页面index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%@ include file="insert0.jsp"%>
<h1>在这里插入</h1>
</body>
</html>
创建被插入页面insert0.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>插入了</h1>
<p id="p1">这是p标签</p>
</body>
</html>
4、九大内置对象
- out
- request
out
request
request对象在完成请求前一直有效
jsp--->jsp
-
表单形式
-
url形式:以?隔开,以键值对的形式,多个参数用&
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="request.jsp">
账号:<input type="text" name="acc">
<button type="submit">登录</button>
</form>
<hr>
以url方式<a href="request.jsp?pws=123"> xx</a>
</body>
</html>
request.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
String acc = request.getParameter("acc");
String pws = request.getParameter("pws");
out.print("账号"+acc);
out.print("<br>");
out.print("pws"+pws);
%>
</body>
</html>
jsp--->java
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/request" method="get">
账号:<input type="text" name="acc">
<button type="submit">登录</button>
</form>
</body>
</html>
Request.java
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Request extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String acc = req.getParameter("acc");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.getWriter().println("账号"+acc);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
xml
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.servlet.Request</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/request</url-pattern>
</servlet-mapping>
运行结果:
5、JSP动作元素
语法:
<jsp:action_name attribute="value" />
第一类(JavaBean)
语法 | 描述 | 参数 |
---|---|---|
jsp:useBean | 实例化对象 | id:实例化对象的名称 ,class:实例化的类,scope作用范围(request,application,page,session) |
jsp:setProperty | 设置对象的属性 | name:实例化对象的名称,及实例化对象的id ,property:要实例化的属性名,value:属性的值 |
jsp:getProperty | 得到对象的属性 | name:实例化对象的名称,及实例化对象的id ,property:要实例化的属性名,会直接输出 |
jsp:include | 动态包含,插入页面 | name:实例化对象的名称,及实例化对象的id ,property:要实例化的属性名,会直接输出 |
其他:
//跟表单关联
<jsp:setProperty name="JavaBean实例名" property="*" />
// 跟表单关联
<jsp:setProperty name="JavaBean实例名" property="JavaBean属性名" />
//手工设置属性值
<jsp:setProperty name="JavaBean实例名" property="JavaBean属性名" value="BeanValue" />
//跟request参数关联
<jsp:setProperty name="JavaBean实例名" property="propertyName" param="request对象中的参数名" />
- 测试 jsp:useBean
创建需要实例化的类 User.java
package com.model;
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JSP实例化:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:useBean id="user1" class="com.model.User">
<jsp:setProperty name="user1" property="name" value="Tom"></jsp:setProperty>
<jsp:setProperty name="user1" property="age" value="16"></jsp:setProperty>
<jsp:getProperty name="user1" property="name"/>
<jsp:getProperty name="user1" property="age"/>
</jsp:useBean>
相当于:
<%@ page import="com.model.User" %><%--
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
User user=new User();
user.setName("Tom");
user.setAge(16);
out.print(user.getName());
out.print(user.getAge());
%>
第二类(基本元素)
语法 | 描述 | 参数 |
---|---|---|
jsp:include | 插入页面 | page:插入页面的地址 |
jsp:forward | 请求转发 | page:转发地址 |
jsp:param | 动作标记元素,必须和 jsp:forward,jsp:include,jsp:plugin一起使用,可以用来传递参数 | name:key,value:value |
<jsp:include page="insert0.jsp"></jsp:include>
<jsp:forward page="insert0.jsp"></jsp:forward>
第三、四、五类
- 第三类
jsp:root jsp:declaration jsp:scriptlet jsp:expression jsp:text jsp:output
- 第四类
- 第五类
6.静态包含与动态包含
静态包含
(1)使用场景: 例如一个jsp页面的导航栏和页脚
(2)使用方法: <%@include file=""%> 其中file属性设置要包含的JSP页面,以/打头,代表http://ip:port/工程路径/,对应web目录
(3)静态包含的特点: ①静态包含不会将被包含的JSP页面翻译成.java.class文件 ②静态包含是把被包含的页面的代码拷贝到body.jsp对应的Java文件的对应位置执行输出
动态包含
(1)使用方法: <jsp:include page=””></jsp:include> 其中page属性设置要包含的JSP页面,与静态包含一致
(2)动态包含的特点: ①动态包含将被包含的JSP页面翻译成.java.class文件 ②动态包含还可以传递参数(jsp:param) ③动态包含底层使用如下代码调用被包含的JSP页面执行输出: org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/foot.jsp”, out, false);