代码可参考: Demo地址
1 入门
1.1 环境搭建
创建moven项目目录结构如下
1.2 依赖配置
<!-- 依赖 -->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 插件 -->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
1.3 创建页面
在webapp下创建 hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>hello jsp</h1>
<%
System.out.println("hello, jso~");
%>
</body>
</html>
1.4 测试
启动tomcat
访问 http://localhost:8080/Jsp-Demo/hello.jsp后
控制台输出
hello, jso~
2 原理
hello.jsp是Servlet
访问hello.jsp会生成如下的类
继承关系
class HttpJspBase extends HttpServlet implements HttpJspPage
public final class hello_jsp extends HttpJspBase implements JspSourceDependent {
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static Map<String, Long> _jspx_dependants;
private ExpressionFactory _el_expressionfactory;
private InstanceManager _jsp_instancemanager;
public hello_jsp() {
}
public Map<String, Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
this._el_expressionfactory = _jspxFactory.getJspApplicationContext(this.getServletConfig().getServletContext()).getExpressionFactory();
this._jsp_instancemanager = InstanceManagerFactory.getInstanceManager(this.getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
JspWriter out = null;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
PageContext pageContext = _jspxFactory.getPageContext(this, request, response, (String)null, true, 8192, true);
_jspx_page_context = pageContext;
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getSession();
out = pageContext.getOut();
out.write("\n");
out.write("<html>\n");
out.write("<head>\n");
out.write(" <title>Title</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write(" <h1>hello jsp</h1>\n");
out.write(" ");
System.out.println("hello, jso~");
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (Throwable var13) {
if (!(var13 instanceof SkipPageException)) {
out = (JspWriter)_jspx_out;
if (_jspx_out != null && ((JspWriter)_jspx_out).getBufferSize() != 0) {
try {
out.clearBuffer();
} catch (IOException var12) {
}
}
if (_jspx_page_context == null) {
throw new ServletException(var13);
}
_jspx_page_context.handlePageException(var13);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在_jspService()方法中,会将html标签写入到JspWritter中返回给浏览器
3 jsp实践
3.1 jsp类型
3.1.1 <%…%>
内容会被放到_jspService()中
3.1.2 <%=…%>
内容会放到out.println()中,作为out.print()函数
3.1.3 <%!..%>
内容会被放到_jspService()方法之外,被类直接包含
下面是示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>hello jsp</h1>
<%
System.out.println("hello, jso~");
int i = 5;
%>
<%="hello"%>
<%=i%>
<%!
void show() {}
String name = "zhangsan";
%>
</body>
</html>
public final class hello_jsp extends HttpJspBase implements JspSourceDependent {
//<%!void show() {} String name = "zhangsan"; %>
String name = "zhangsan";
void show() {}
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
...
System.out.println("hello, jso~"); //<%System.out.println("hello, jso~");%>
int i = 5; //<% int i = 5%>
out.write("\n");
out.write("\n");
out.write(" ");
out.print("hello"); //<%="hello"%>
out.write("\n");
out.write(" ");
out.print(i); // <%=i%>
...
}
}
}
3.2 示例
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.jsp.Brand" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
List<Brand> brandList = new ArrayList();
brandList.add(new Brand(1, "华为", "华为", 200, "5G厂商", 1));
brandList.add(new Brand(2, "比亚迪", "比亚迪", 300, "国产电车", 1));
brandList.add(new Brand(3, "茅台", "茅台", 400, "白酒酱香", 1));
%>
<html>
<head>
<title>Title</title>
</head>
<body>
<input type="button" value="新郑"><br>
<hr>
<table border="1" cellspacing="0" width="800">
<tr>
<th>序号</th>
<th>品牌名称</th>
<th>企业名称</th>
<th>排序</th>
<th>品牌介绍</th>
<th>状态</th>
<th>操作</th>
</tr>
<%
for (int i = 0; i < brandList.size(); i++) {
Brand brand = brandList.get(i);
%>
<tr align="center">
<td><%=brand.getId()%></td>
<td><%=brand.getBrandName()%></td>
<td><%=brand.getCompanyName()%></td>
<td><%=brand.getOrdered()%></td>
<td><%=brand.getDescription()%></td>
<td><%=brand.getStatus() == 1 ? "启用" : "禁用"%></td>
<td><a href="#">修改</a> <a href="#">删除</a> </td>
</tr>
<%
}
%>
</table>
</body>
</html>
在浏览器地址栏输入
http://localhost:8080/Jsp-Demo/brand.jsp
效果展示
遇到报错
Only a type can be imported. * resolves to a package
解决方式: 在Avaliable Elements 这里选择对应的项目后,右键,选择 Put into Output Root
4 EL表达式
EL(全称Expression Language) 表达式语言,用于简化jsp页面的Java代码
主要作用是获取数据,然后展示在页面上
语法$ {expression},如${brands}就是获取域中存储的key为brands的数据
4.1 案例
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${brands}
</body>
</html>
@WebServlet("/demo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ServletDemo1 doGet");
List<Brand> brandList = new ArrayList();
brandList.add(new Brand(1, "华为", "华为", 200, "5G厂商", 1));
brandList.add(new Brand(2, "比亚迪", "比亚迪", 300, "国产电车", 1));
brandList.add(new Brand(3, "茅台", "茅台", 400, "白酒酱香", 1));
req.setAttribute("brands", brandList);
req.setAttribute("status", 111);
System.out.println(req.getAttribute("brands"));
req.getRequestDispatcher("/el-demo.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
访问http://localhost:8080/Jsp-Demo/demo1
后将会输出brands中的内容
如果el表达式获取不到值,则可能是WEB-INF包下的web.xml中的版本过低
修改成
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
另外jsp中添加 isELIgnored=“false”
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
4.2 域对象
page: 当前页面有效
request: 当前请求有效
session: 当前会话有效
applicaton: 当前应用有效
6 JSTL标签
jsp标准标签库(jsp Standarded Tab Library), 使用标签替代jsp页面上的代码
使用:
导入依赖
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
使用标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用示例:
jstp.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- <c:if>标签 --%>
<c:if test="${status == 1}">
开启
</c:if>
<c:if test="${status == 0}">
关闭
</c:if>
<br>
<%-- <c:forEach>标签 --%>
<c:forEach items="${brands}" var="brand">
<tr align="center">
<td>${brand.id}</td>
<td>${brand.brandName}</td>
<td>${brand.companyName}</td>
<td>${brand.description}</td>
</tr>
<br>
</c:forEach>
<br>
<%-- <c:forEach>标签 --%>
<c:forEach begin="0" end="10" step="1" var="i">
${i}
</c:forEach>
</body>
</html>
ServletDemo2.java
@WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//将数据存储到request域中
req.setAttribute("status", 1);
List<Brand> brandList = new ArrayList<>();
brandList.add(new Brand(1, "华为", "华为", 200, "5G厂商", 1));
brandList.add(new Brand(2, "比亚迪", "比亚迪", 300, "国产电车", 1));
brandList.add(new Brand(3, "茅台", "茅台", 400, "白酒酱香", 1));
req.setAttribute("brands", brandList);
//转发到jstl-if.jsp中
req.getRequestDispatcher("/jstl.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
使用浏览器访问
http://localhost:8080/Jsp-Demo/demo2
浏览器中输出内容
开启
1 华为 华为 5G厂商
2 比亚迪 比亚迪 国产电车
3 茅台 茅台 白酒酱香
0 1 2 3 4 5 6 7 8 9 10
7 示例
7.1 环境准备
1 创建web工程
2 创建数据库,添加数据
-- 创建tb_brand表
create table tb_brand(
id int primary key auto_increment,
brand_name varchar(20),
company_name varchar(20),
ordered int,
description varchar(100),
status int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values('比亚迪', '比亚迪汽车有限公司', 100, '高科技专业电动汽车', 0),
('宁德时代', '宁德时代科技公司', 200, '高科技锂电池', 1),
('小米', '小米科技有限公司', 300, '让每个人享受科技带来的美好生活', 1)
7.2 查询所有
1 配置web-app的版本,否则jsp中获取不到el表达式的值
WEB-INFO/web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
2 实体类 Brand
package com.test.pojo;
public class Brand {
private Integer id;
private String brandName;
private String companyName;
private Integer ordered;
private String description;
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
3 定义公共的查询工具类
package com.test.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String rescource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(rescource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
4 定义查询的Mapper类和xml
BrandMapper.java
public interface BrandMapper {
List<Brand> selectAll();
}
BrandMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.BrandMapper">
<resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName"></result>
<result column="company_name" property="companyName"></result>
</resultMap>
<select id="selectAll" resultType="com.test.pojo.Brand" resultMap="brandResultMap">
select * from tb_brand;
</select>
</mapper>
5 定义查询的方法
public class BrandService {
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
public List<Brand> selectAll() {
SqlSession sqlSession = factory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectAll();
System.out.println("brands = " + brands);
sqlSession.close();
return brands;
}
}
6 定义服务接口Servlet
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Brand> brands = service.selectAll();
req.setAttribute("brands", brands);
req.getRequestDispatcher("/brand.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
7 jsp页面
<%--
Created by IntelliJ IDEA.
User: yl
Date: 2022/11/30
Time: 5:11 PM
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<hr>
<table border="1" cellspacing="0" width="80%">
<tr>
<th>序号</th>
<th>品牌名称</th>
<th>企业名称</th>
<th>排序</th>
<th>品牌介绍</th>
<th>状态</th>
<th>操作</th>
</tr>
<c:forEach items="${brands}" var="brand" varStatus="status">
<tr align="center">
<td>${status.count}</td>
<td>${brand.brandName}</td>
<td>${brand.companyName}</td>
<td>${brand.ordered}</td>
<td>${brand.description}</td>
<c:if test="${brand.status == 1}">
<td>启用</td>
</c:if>
<c:if test="${brand.status != 1}">
<td>禁用</td>
</c:if>
<td>
<a href="/Mvc-Demo/selectByIdServlet?id=${brand.id}">修改
</a> <a href="#"> 删除</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
访问http://localhost:8080/Mvc-Demo/selectAllServlet地址后,
浏览器页面效果
7.3 添加
具体代码可参考顶部Demo中
1 Mapper方法
@Insert("insert into tb_brand values(null, #{brandName}, #{companyName}," +
" #{ordered}, #{description}, #{status})")
void add(Brand brand);
2 Service中的方法
public void add(Brand brand) {
SqlSession sqlSession = factory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.add(brand);
sqlSession.commit();
sqlSession.close();
}
3 添加页面jsp
<%--
Created by IntelliJ IDEA.
User: yl
Date: 2022/11/30
Time: 9:16 PM
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加品牌</title>
</head>
<body>
<h3>添加品牌</h3>
<form action="/Mvc-Demo/addServlet" method="post">
品牌名称: <input name="brandName"><br> <br>
企业名称: <input name="companyName"><br> <br>
品牌排序: <input name="ordered"><br> <br>
描述信息: <textarea rows="5" cols="20" name="description"></textarea> <br> <br>
状态:
<input type="radio" name="status" value="0">禁用
<input type="radio" name="status" value="1">启用 <br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
4 Servlet接口
package com.test.web;
import com.test.pojo.Brand;
import com.test.service.BrandService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Brand> brands = service.selectAll();
req.setAttribute("brands", brands);
req.getRequestDispatcher("/brand.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
5 列表页面新增
<input type="button" value="新增" id="add"><br>
<script>
document.getElementById("add").onclick = function () {
location.href = "/Mvc-Demo/addBrand.jsp"
}
</script>
请求地址: http://localhost:8080/Mvc-Demo/addBrand.jsp
效果展示
提交后,商品列表中多了一项
7.4 查询并展示单条数据
1 BrandMapper中添加查询语句
@Select("select * from tb_brand where id = #{id}")
@ResultMap("brandResultMap")
Brand selectById(int id);
2 BrandService添加查询Mapper逻辑
public Brand selectById(int id) {
SqlSession sqlSession = factory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
Brand brand = mapper.selectById(id);
sqlSession.commit();
sqlSession.close();
return brand;
}
3 添加查询的Servlet
@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
Brand brand = service.selectById(Integer.parseInt(id));
req.setAttribute("brand", brand);
req.getRequestDispatcher("/update.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
4 添加update.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>修改品牌信息</title>
</head>
<body>
<h3>修改品牌信息</h3>
<form action="/Mvc-Demo/updateServlet" method="post">
品牌名称: <input name="brandName" value="${brand.brandName}"><br> <br>
企业名称: <input name="companyName" value="${brand.companyName}"><br> <br>
品牌排序: <input name="ordered" value="${brand.ordered}"><br> <br>
描述信息: <textarea rows="5" cols="20" name="description"> ${brand.description} </textarea> <br> <br>
状态:
<c:if test="${brand.status == 0}">
<input type="radio" name="status" value="0" checked>禁用
<input type="radio" name="status" value="1">启用 <br><br>
</c:if>
<c:if test="${brand.status == 1}">
<input type="radio" name="status" value="0">禁用
<input type="radio" name="status" value="1" checked>启用 <br><br>
</c:if>
<input type="submit" value="提交">
</form>
</body>
</html>
5 访问http://localhost:8080/Mvc-Demo/selectAllServlet 后,选择任意一项品牌,然后点修改
展示效果:
7.5 修改
1 添加update sql 语句方法
BrandMapper.java
@Update("update tb_brand set brand_name = #{brandName}, company_name = #{companyName}, ordered = #{ordered}" +
", description = #{description}, status = #{status} where id = #{id}")
void update(Brand brand);
2 添加业务方法
public void update(Brand brand) {
SqlSession sqlSession = factory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
System.out.println("update brand = " + brand);
mapper.update(brand);
sqlSession.commit();
sqlSession.close();
}
3 updateServlet
WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String id = req.getParameter("id");
String brandName = req.getParameter("brandName");
String companyName = req.getParameter("companyName");
String ordered = req.getParameter("ordered");
String description = req.getParameter("description");
String status = req.getParameter("status");
Brand brand = new Brand();
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(Integer.parseInt(ordered));
brand.setDescription(description);
brand.setStatus(Integer.parseInt(status));
brand.setId(Integer.parseInt(id));
service.update(brand);
req.getRequestDispatcher("/selectAllServlet").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
4 隐藏id选项,id不可编辑
<input type="hidden" name="id" value="${brand.id}"><br>
在update.jsp页面中,修改内容,提交后,可看到内容被修改了