Java Web06:JSP
JSP(Java Server Pages),Java服务器端页面,和Servlet一样用于开发动态Web
区别:
- Servlet只能用out.write("")的方式输出页面
- JSP就像是写HTML一样,而且还可以嵌入Java代码,为用户提供动态数据
JSP原理
在IDEA中使用Tomcat,其工作目录为C:\users\username\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet,JSP最终也会被转换为一个Java程序
JSP继承了HttpJspBase类,而该类继承了HttpServlet,所以JSP本质还是实现了Servlet接口,通过out.write("")的方式输出页面
/**
* 初始化
*/
public void _jspInit() {}
/**
* 销毁
*/
public void _jspDestroy() {}
/**
* JSPService方法
*/
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException {
/**
* 判断请求类型
*/
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method){
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
/**
* 内置对象,可以在JSP文件中直接调用
*/
final javax.servlet.jsp.PageContext pageContext; // 页面上下文
javax.servlet.http.HttpSession session = null; // 会话
final javax.servlet.ServletContext application; // 应用(ServletContext)
final javax.servlet.ServletConfig config; // 配置(ServletConfig)
javax.servlet.jsp.JspWriter out = null; // 输出
final java.lang.Object page = this; // 当前页
HttpServletRequest request // 请求
HttpServletResponse response // 响应
/**
* 输出JSP页面(除了这部分的out输出,其他地方一模一样)
*/
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("<html>");
} 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);
}
}
JSP语法和指令
Maven导入依赖
<dependencies>
<!--Servlet依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--JSP依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--JSTL表达式依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库依赖-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
基本语法
<%%>、<%=%>、<%!%>、${}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
HTML代码会被out对象直接输出到前端
--%>
<%--
Java代码
写在<%%>标签中,会原封不动的输出在_jsp.java文件中,作用域为_jspService()方法
--%>
<%
String name = "ty";
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
out.println("<h1>sum = " + sum + "</h1>");
/**
* 先存入域空间才能用EL表达式读取
*/
pageContext.setAttribute("name", name);
%>
<%--
JSP表达式
写在<%=%>标签中,将程序的输出,输出到客户端
本质是调用JspWriter的out默认对象进行输出,会在服务端被解析为Java代码然后输出,只要页面定义了name这个变量就可以访问到
--%>
name:<%=name%>
<%--
EL表达式(代替JSP表达式)
写在${}中,但要先在域空间存入
EL表达式的本质是从4个域空间取值,因此一定要先将name存入page域空间才能读取
--%>
name:${name}
<%--
JSP申明
写在<%!%>标签中,作用域为整个jsp.java类
--%>
<%!
static {
System.out.println("全局作用域");
}
%>
</body>
</html>
基本指令
<%@ page ... %>
contentType、errorPage(可在web.xml中统一配置)、import
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--自定义错误界面-->
<%@ page errorPage="error/error500.jsp" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
int a = 10 / 0;
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="img/error500.png" alt="500">
</body>
</html>
<!--或者直接在web.xml文件中统一配置-->
<error-page>
<error-code>500</error-code>
<location>/error/error500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/error404.jsp</location>
</error-page>
<%@ include file="..." %>
网站公用的部分可以调用同一个JSP文件(和<jsp:include page="...">标签有些许区别)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
JSP指令
后台会将该JSP文件的语句直接合并,用out输出
--%>
<%@ include file="common/header.jsp"%>
<p>这是网站的主体部分</p>
<%@ include file="common/footer.jsp"%>
<%--
JSP标签
后台会调用这个JSP文件,拼接成一个页面
灵活性更高,可以定义相同的变量,作用域独立
--%>
<jsp:include page="/common/footer.jsp"/>
</body>
</html>
JSP内置对象和作用域
pageContext、request、response、session、application、out、config、page、exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
/**
* 这四个内置对象都可以存储数据,但是作用域不同
* setAttribute()方法的第三个参数scope也可以手动指定作用域,但不建议
*/
pageContext.setAttribute("name1", "pageContext"); // 保存的数据在当前页面中有效,其他页面无法获取
request.setAttribute("name2", "request"); // 保存的数据在当前请求中有效,如果请求转发也会有效,直到请求结束
session.setAttribute("name3", "session"); // 保存的数据在当前会话中有效,直到关闭浏览器
application.setAttribute("name4", "application"); // 保存的数据在服务器中有效,直到关闭服务器
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
/**
* findAttribute()方法查找属性
* 其他页面只能获取到name3和name4
*/
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");
%>
<%--
EL表达式
对于不存在的name5属性,不会输出
--%>
<p>${name1}</p>
<p>${name2}</p>
<p>${name3}</p>
<p>${name4}</p>
<p>${name5}</p>
<hr/>
<%--
JSP表达式
对于不存在的属性,会输出null
--%>
<p><%=name5%></p>
</body>
</html>
JSP标签、JSTL标签、EL表达式
JSP标签:jsp:
include、forward、param
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
forward:请求转发
param:转发时携带参数
--%>
<jsp:forward page="otherPage.jsp">
<jsp:param name="name" value="ty"/>
<jsp:param name="age" value="24"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--取出请求中的参数--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
</body>
</html>
EL表达式:${}
作用:获取数据、执行运算、获取Web开发的常用对象
JSTL标签:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
JSTL标签库的使用是为了弥补HTML标签的不足,它定义了许多标签,功能和Java代码一样
所需依赖包:jstl-api、standard
if、out、choose、whe、forEach
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--要先引入JSTL核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="test.jsp" method="get">
<%--
${param.属性}获取表单的属性值
--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--if判断--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="登陆成功!"/>
</c:if>
<%--out输出--%>
<c:out value="${isAdmin}"/>
</body>
</html>
JavaBean
JavaBean是Java中一种特殊的类,必须要有无参构造器,属性必须要私有化,必须使用getter()和setter()方法访问属性
作用:和JSP页面交互数据
实体类
该Java类统称为实体类,和数据库中的表结构一一对应,即数据库做对象关系映射(ORM)
package com;
public class JavaBean {
private int id;
private String name;
private int age;
private String address;
public JavaBean(){}
public JavaBean(int id, String name, int age, String address){
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "com.JavaBean{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
useBean标签
<jsp:useBean id="" class="" scope="">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.JavaBean" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--实例化对象people--%>
<jsp:useBean id="people" class="com.JavaBean" scope="page"/>
<%--赋值--%>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="ty"/>
<jsp:setProperty name="people" property="age" value="24"/>
<jsp:setProperty name="people" property="address" value="China"/>
<%--获取值--%>
序号:<jsp:getProperty name="people" property="id"/>
姓名:<jsp:getProperty name="people" property="name"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
</body>
</html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗