Skip to content

JSP开发基础

B/S架构简介

B/S 架构 = Browser / Server(浏览器 / 服务器),是一种基于 Web 的软件架构模式。

sequenceDiagram actor 用户 as 用户 participant 浏览器 as 浏览器 participant Web服务器 as Web服务器 participant JSP容器 as JSP容器(Tomcat) participant 数据库 as 数据库 %% 1. 用户访问 用户->>浏览器: 输入URL/点击页面 %% 2. 浏览器发请求 浏览器->>Web服务器: HTTP/HTTPS 请求访问 .jsp %% 3. 转发给JSP容器 Web服务器->>JSP容器: 转发JSP请求 %% 4. JSP编译执行 JSP容器->>JSP容器: 翻译JSP→Servlet→编译执行 %% 5. 访问数据库 JSP容器->>数据库: 查询/新增/修改数据 数据库-->>JSP容器: 返回数据结果 %% 6. 生成HTML JSP容器-->>Web服务器: 生成动态HTML页面 Web服务器-->>浏览器: 返回HTML页面 %% 7. 浏览器渲染 浏览器-->>用户: 解析渲染,展示页面

核心特点

  1. 客户端只需浏览器 用户不用安装专门软件,通过 Chrome、Edge、Safari 等浏览器即可访问系统。

  2. 业务集中在服务器 程序、逻辑、数据库都部署在服务器端,统一维护、升级方便。

  3. 跨平台、易访问 只要有网络和浏览器,电脑、平板、手机基本都能使用。

  4. 通信基于 HTTP/HTTPS 浏览器发请求 → 服务器处理 → 返回网页/数据 → 浏览器展示。

典型应用

网站、管理后台、OA 系统、在线教务系统、云平台等。

优点

  • 部署维护简单,升级只需改服务器
  • 客户端零安装,使用门槛低
  • 易于跨设备、跨网络访问

缺点

  • 交互体验通常不如本地客户端(C/S)

  • 功能和性能受网络、浏览器限制



JSP开发环境的搭建

JDK

Open JDK 23+(https://jdk.java.net/23/)

应用服务器

Tomcat 11(https://tomcat.apache.org/download-11.cgi)

集成开发环境

Spring Tools 5(https://spring.io/tools/)

Spring Tools 5支持Dynamic Web Project

  1. 打开插件安装界面:Help>Install New Software

  2. Work with下选择All Available Sites

  3. 加载之后,选择Web, XML, Java EE and OSGi Enterprise Development后点击Next直到Finish完成安装

  4. 安装完成后(时间较长)重启STS5


Hello World!

打开STS5创建JSP目录,以该目录为Workspace创建Dynamic Web Project,配置如下。

  • Project Name
    • HelloJSP
  • Generate web.xml deployment descriptor

完成后形成的目录结构如下:

目录结构
JSP:.
├─.metadata //工作空间配置文件
└─HelloJSP
    ├─build //编译目录
      └─classes
    └─src //源代码
        └─main
            ├─java  //后端(Java)源代码根目录
            └─webapp  //前端源代码根目录
                ├─META-INF  //系统自动生成,存放系统描述信息
                └─WEB-INF //该目录中内容不能对外发布
                      web.xml  //部署描述符
                    └─lib //依赖包目录

webapp目录下创建Hello.jsp

hello.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<jsp:useBean id="datetime" class="java.util.Date" />
<title>Hello JSP</title>
</head>
<body>
    <h1>Hello world, from Tomcat!</h1>
    on ${datetime}
</body>
</html>

开发模式

  1. 打开Window>Show View>Other...>>Server>Servers视图

  2. 新建New>Server>>Apache>Tomcat v9.0 Server

  3. 右键Tomcat v9.0 Server at localhost,选择Add and removeHelloJSP部署到Tomcat

  4. 双击Tomcat v9.0 Server at localhost打开服务器配置界面

  5. Server Locations选择Use Tomat installation

  6. Ports设定HTTP/1.18080(默认)

  7. 右键Tomcat v9.0 Server at localhost,选择Start启动Tomcat服务器

    • 编译后的工程已部署到Tomcat下的wtpwebapps/HelloJSP目录

生产模式

  • 工程导出为War

在浏览器中打开http://localhost:8080/HelloJSP/hello.jsp


Web程序的调试与排错

在运行Web程序时,我们常犯的一些错误有:

  • 未启动Tomcat服务,或者没有在预期的端口中启动Tomcat服务

  • 未部署Web应用,就试图运行Web程序

  • 运行时,URL输入错误

  • 存放文件的目录无法对外引用,如:文件放入了WEB-INF、META-INF等文件夹


错误1:未启动Tomcat

常见处理方法:

  • 启动Tomcat服务

  • 如果在控制台上显示Tomcat服务已启动,观察端口号是否与预期端口号一致,按照实际端口号重新运行


错误2:未部署Web应用

错误2:未部署Web应用

常见处理方法:

  • 检查URL地址是否正确

错误3:目录不能被引用

常见处理方法:

  • 把需要公开的文件放在webapp下除WEB-INF外的位置

JSP语法基础

什么是JSP

JSP 即 JavaServer Pages,是一种运行在服务器端的 Java 动态网页技术,它允许在 HTML 中嵌入 Java 代码,由 Tomcat 等服务器将其翻译编译为 Servlet 执行,最终生成静态 HTML 返回给浏览器,主要用于实现 Web 应用的视图展示,是传统 Java Web 开发中 MVC 模式的重要组成部分。

  • 在HTML中嵌入Java脚本语言

  • 由应用服务器中的JSP引擎来编译和执行嵌入的Java脚本语言命令

  • 然后将生成的整个页面信息返回给客户端

什么是JSP


核心知识点

模块 主要内容
基础语法 大小写敏感、属性加引号、转义字符、URL路径规则
脚本标签 脚本片段 <% %>、表达式 <%= %>、声明 <%! %>、EL 表达式、JSTL 标签
指令与动作 page 指令、include 指令、taglib 指令、jsp:include、jsp:forward、jsp:useBean
内置对象 request、response、session、application、out、pageContext
运行原理 JSP 翻译为 Servlet、编译为 class、运行输出 HTML
开发应用 MVC 模式、JavaBean 封装、数据库访问

JSP执行过程

Web容器处理JSP文件请求需要经过3个阶段:

  • 翻译阶段编译阶段执行阶段
graph TD A[用户访问 JSP 页面
Tomcat] --> C{是否已编译?}:::danger C -->|否| D[JSP 引擎翻译 JSP]:::primary D --> E[生成 .java 源码文件]:::primary E --> F[编译为 .class 字节码]:::primary C -->|是| G["加载已编译的 Servlet"]:::success F --> G G --> H[执行 Servlet 处理请求] H --> K[返回 HTML 页面给浏览器]

JSP通用规则

  1. 大小写敏感 JSP 语法严格区分大小写,标签、指令、变量名等都需要严格匹配大小写,否则会出现编译或运行错误。

  2. 属性值引号规则

    • 标记中的属性值必须用引号(单引号/双引号)包裹
    • 若属性值本身包含引号,需使用HTML转义字符:&apos;(单引号)、&quot;(双引号)
  3. 转义字符规则

    • 在记号中,可使用反斜杠 \ 作为转义字符:
    • 例如需要输出 % 时,需写作 \%,避免和JSP脚本标记 <% %> 冲突
  4. URL路径规则

    • / 开头的URL:上下文相关路径(基于Web应用根目录解析)
    • 不以 / 开头的URL:相对路径(基于当前JSP文件所在目录解析)

JSP 页面组成

JSP页面组成

JSP页面组成示例


模板元素

模板元素指JSP文件中的静态HTML内容,它们是网页的框架,它们影响页面的结构和美观程度。

但模板元素主要由网页美工完成,对JSP程序员来说,不太关心这部分的内容。

注释

语法

<! -- Comments -->
<! -- Comments…<%= expression %> -->

其实就是HTML的注释,网页代码中会显示出来,在里面还可以嵌入其他JSP元素。如:

<! -- Now: <%=(new java.util.Date()) %> -->

语法

1
2
3
<%-- Comments --%>
<% // Comments %>
<% /* Comments */%>

完全被JSP编译器忽略,真正的注释,在客户端不会显示出来。

<!-- note.jsp文件代码-->
<%@page import="java.util.*"%>
<%@page contentType="text/html; charset=utf-8"%>
<html><head><title>JSP注释使用示例</title></head>
<body><!--HTML注释:当前时间为<%=(new Date()).toLocaleString()%>-->
<center><%--隐藏注释--%><br>
<%
//脚本代码注释:使用循环语句产生八行文字
for(int i=1;i<=8;i++){
    if(i%2==0)
      out.println("<font color=red>JSP注释使用示例</font><br>");
  else
      out.println("JSP注释使用示例<br>");
} 
%>
</center></body></html>

JSP指令(Directives)

JSP指令

用于通知JSP引擎如何处理JSP页面。

语法:

1
2
3
4
<%@ directive-name
  attribute-name=attribute-value
  attribute-name=attribute-value  
%>

常用的JSP指令包括:

  • page指令

  • taglib指令

  • include指令


page指令

定义整个JSP页面要使用的属性,主要的属性包括:language、import、buffer、isThreadSafe、isErrorPage、session、autoflush、errorPage、contentType等 。其位置可以在页面的任何位置,但推荐放在页首。但是除import外,其它任何属性/值对只能出现一次 。

语法:

<%@ page attr = value %>

示例:

<%@ page contentType = text/html;charset=utf-8 %>
属性 描述 缺省值
language 定义要使用的脚本语言。如果在将来 JSP容器支持多种语言时可使用它。 java
import 定义该JSP文件要使用的类。
session 设置当前页面是否参与一个Http会话。 true
buffer 设置客户输出流的缓冲区大小。 8KB
autoFlush 设置缓冲区是否自动刷新。 true
info 设置JSP页面的信息,可用servlet.getServletInfo()获得
isThreadSafe 定义该JSP是否支持多线程。 true
contentType 定义JSP的字符编码方式和JSP页面响应的MIME类型。 TYPE=text/html;CHARSET=iso-8859-1
isErrorPage 设置JSP页面是否为其他页面的错误处理页面。 false
errorPage 定义此页面出现异常时要调用的页面
method 指定Scriptlet代码属于哪个方法。 Method=“service”
isELIgnored 指定EL是否被忽略。 由web.xml的版本确定,Servlet2.3以前的版本将忽略

include指令

用于将另一个文件的内容插在JSP文件中。一个 JSP 页面中的 include 指令的数量不受限制。

语法:

<%@ include file = filename %>

示例:

<%@ include file = header.htm %>

页面布局

使用include指令可以把一个复杂的JSP页面分成若干简单的部分,当要对页面更改时,只需更改对应的部分就行了。

通常情况下把页面分成多个区,典型的分区方法如下:

页面布局


taglib指令

这个指令允许页面使用自定义标记库。标记库是扩展 JSP 功能的自定义标记的集合。

语法

<%@ taglib uri = "TagLibrary" prefix = "mypfx" %>
  • 声明此JSP文件使用了自定义的标签,同时引用标签库,也指定了他们的标签的前缀。

示例

<%@ taglib uri = "http://www.mycorp.com/supertag" prefix = "super" %>

脚本元素

包含程序逻辑,使开发者能直接将代码嵌入JSP页面。

类型:

  • 声明

  • 表达式

  • 代码段


声明

脚本片断概念

  • JSP Scriptlet就是在JSP页面里嵌入的一些Java代码片段。

语法

<% Scriptlets %>

示例

1
2
3
4
5
<%  for(int i=1; i<=3; i++)
{
out.print(hello, world!);
} 
%>

声明和Scriptlet中定义变量的区别

  • 因为JSP页面实际上是被编译成Servlet类执行的,所以声明中定义的变量是Servlet类的成员变量

  • Scriptlet中定义的变量是Servlet类的service()方法或doGet()方法或doPost()方法等中的局部变量


动作元素

是支持JavaBean的JSP特殊标记,与指令元素不同的是,动作元素在请求处理阶段起作用。

常用JSP动作

1
2
3
4
5
6
<jsp:useBean>
<jsp:getProperty>
<jsp:setProperty>
<jsp:param>
<jsp:include>
<jsp:forward>

<jsp:useBean>

用来加载要在页面中使用的JavaBean,通过该标记可以创建JavaBean的一个实例,并给这个实例命名。

语法:

<jsp:useBean id=“<bean name>   class=“<bean class> scope=“<scope>”/>
  • id

    • 定义要加载的Bean的实例名字。
  • Scope

    • 指定Bean存在的范围和id属性的有范围,缺省为page。可以为request、session、application。
  • Class

    • 指定要加载的Bean的类文件路径。

<jsp:setProperty>

设置Bean的属性值。

语法:

<jsp:setProperty name=“Bean的名字“ property=“属性名” value=“属性值”/>

<jsp:getProperty>

获取Bean的属性值。

语法:

<jsp:getProperty name=“Bean的名字“ property=“属性名” value=“属性值”/>

引用JavaBean实例
simplecart.html
<form method="post" action="simplecart.jsp">
<select name="item">
<option>哈里波特系列
<option>灰姑娘
<option>三国演义
<option>红楼梦
<option>十万个为什么
</select>
simplecart.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%  request.setCharacterEncoding("utf-8");%>
<html>
<jsp:useBean id="cart" scope="page" class="myBean.simplecart" />
<jsp:setProperty name="cart" property="*" />
<% 
    String item = cart.getItem();
  int number = cart.getNumber();
  out.println("<tr><td width=200>《"+item+"》</td>"); 
  out.println("<td width=200>"+number+"</td></tr>"); 
%>
simplecart.java
package myBean;
public class simplecart {
public String item;
public int number;

public void setItem(String name) {
item = name;
}
public String getItem() {
return item;
}
public void setNumber(int number)
{
this.number=number;
}
public int getNumber(){
return this.number;
}}

<jsp:param>

它被用来以“名-值”对的形式为其它标签提供附加信息。

它和jsp:include、jsp:forward、jsp:plugin一起使用。

语法:

<jsp:param name=“paramName” value=“paramValue”/>

<jsp:include>

<%@ include%>指令不同,<jsp:include>包含的内容可以是动态改变的,它在执行时才确定,而前者包含的内容是固定不变的。

语法:

1
2
3
4
<jsp:include page=“fileName” flush=“true”>
<jsp:param name=“pName”  value=“pValue”/>
……
</jsp:include>

<jsp:include><jsp:param>实例
include_action.jsp
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<html>
<body>
<center>
<h3>include动作示例</h3>
<hr />
<jsp:include page="welcome.jsp" flush="true">
<jsp:param name="yourname" value="Emma" />
</jsp:include>
</center>
</body>
</html>
welcome.jsp
1
2
3
4
5
6
7
8
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<br>
<%=request.getParameter("yourname")%>,您好!
<br>
现在是 <%=new java.util.Date().toLocaleString()%>
<br>
欢迎您访问本网页。
"

<jsp:forward>

这个动作允许请求被转发到另外的JSP、servlet或一个静态的资源上。当要根据不同的请求,把应用程序分割为不同的视图时,这个动作尤其有用。

语法:

1
2
3
4
5
<jsp:forward page=“uri” />
<jsp:forward page=“uri” >
<jsp:param name=“pName”  value=“pValue”/>
……
</jsp:forward>

<jsp:forward>注意事项

  • 如果JSP文件中包含该标记,那么这个JSP文件中的所有输出都不会被发送到客户端,并且<jsp:forward>标记以下的代码不会被执行。

  • <jsp:forward>标记从一个JSP文件向另一个文件传递包含用户请求的request对象。


<jsp:forward>示例
login.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<html>

<body>
  <form method=post action=check.jsp>
    <table>
      <tr>
        <td>用户名:</td>
        <td><input type=text name=name></td>
      </tr>
      <tr>
        <td>密码:</td>
        <td><input type=password name=password></td>
      </tr>
      <tr>
        <td align="center"><input type=submit value="提交"></td>
        <td align="center"><input type=reset value="重置"></td>
      </tr>
    </table>
</body>

</html>
check.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<html>

<body>
  <% String name=request.getParameter("name"); String password=request.getParameter("password");
    if(name.equals("Emma")&& password.equals("123456")) { %>
    <jsp:forward page="welcome.jsp">
      <jsp:param name="yourname" value="<%=name%>" />
    </jsp:forward>
    <% } else { %>
      <jsp:forward page="error.html" />
      <%}%>
</body>

</html>

<jsp:plugin>

可以使用这个动作来插入Applet或JavaBean。

语法:

<jsp:plugin type=“bean|applet” code=“classFileName” codebase=“classFileDirectoryName” …… <jsp:param name=“pName”  value=“pValue”/> <jsp:fallback>text message </jsp:fallback> </jsp:plugin>
plugin.jsp
1
2
3
4
5
6
7
8
<%@ page contentType="text/html; charset=gb2312" %>
……
<!--用plugin加载Applet-->
<jsp:plugin type="applet" code="DrawingGraphic.class" height="300" width="300">
    <jsp:fallback>Plugin tag OBJECT or EMBED not supported by browser.
    </jsp:fallback>
</jsp:plugin>
……
DrawingGraphic.jsp
……
public void paint( Graphics g ) {
    g.setColor(Color.red); 
    g.drawRect(10,30,getWidth()/2-50,getHeight()/2-50);
    g.drawOval(10,30,getWidth()/2-50,getHeight()/2-50);
    g.drawLine(10,30,5+getWidth()/2-50,30+getHeight()/2-50);
    g.setColor( Color.blue );
    g.fillRoundRect( 100, 160, 80, 110, 30, 40 );
    g.setColor( Color.darkGray );
    g.fillArc( 140, 40, 120, 120, 90, 135 );
}}

缺省引入的包

下面这些包在JSP编译时已经导入了,所以在JSP文件中无须再用page指令引入:

  • java.lang.*

  • javax.servlet.*

  • javax.servlet.jsp.*

  • javax.servlet.http.*

<%@page import = “java.lang.* %>