JavaWeb(7)之JSP

JSP的概述

什么是JSP

JavaWeb(7)之JSP_第1张图片
JSP: Java Server Pages (ava服务器端页面),其实就在HTML中嵌入Java代码。

为什么学习JSP

SUN公司提供了动态网页开发技术: Servlet. Servlet 自身有一些缺点, SUN公司发现了这些问题,推出了一个新的动态网页开发技术JSP。
Servlet的缺点:
Servlet 需要进行配置,不方便维护。
Servlet 很难向网页中输出HTML页面内容

JSP的运行原理

JSP的简单使用

创建一个JSP页面

在这里插入图片描述
JavaWeb(7)之JSP_第2张图片
创建JSP页面还自动创建模板,但是要将编码设置为UTF-8

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
	<h1>Hello JSP h1>
body>
html>

JSP需要发布到服务器中才可以运行的
发布项目到Tomcat中
访问JSP页面

运行结果:
JavaWeb(7)之JSP_第3张图片
运行原理:
JavaWeb(7)之JSP_第4张图片
JSP文件翻译成Java文件,将这个Java文件编译生成class文件,运行class文件,而class文件最终继承的是httpservlet。

JSP脚本元素

JSP脚本元素概述

JSP= HTML +Java代码+ JSP自身东西
JSP的脚本元素就是在JSP中嵌入Java代码。

脚本元素的分类

声明标签

语法:
<%!变量或方法声明%>
写在这个脚本中的代码,翻译成Servlet内部的成员变量或成员方法。、
因为Servlet是一个线程不安全类,所以不推荐使用。

用法:

<body>
	<%! 
		//声明变量
		int a=3;
	%>
body>

表达式标签

语法: <%=表达式%>
写在这个脚本中的代码, 翻译成方法内部的out,prin();当中的内容,显示在页面上。

用法:

	<%=
		a
	%>

运行结果后可以将声明便签好中的a输出到页面上

程序代码标签

语法:
<% 程序代码%>
写在这个脚本中的代码, 翻译成方法内部的局部变量或方法内部代码片段。
用法:

推荐使用程序代码标签,而不是声明标签,因为声明标签是写在Servlet中,而Servlet是一个线程不安全类。

JSP的开发模式之MVC模式

MVC模式简介

JSP开发模式

JavaWeb(7)之JSP_第5张图片

开发中的路径问题

web开发中的路径问题
web开发中目录路径问题的解决

什么时候会遇见路径问题

提供一些页面,在页面中会提供链接或者表单,当点击链接或者表单的时候需要进行提交,提交到Servlet中。从页面向Servlet发送请求的地址(路径)应该如何编写。

路径的分类

先创建一个动态web项目:
JavaWeb(7)之JSP_第6张图片
分别使用相对路径和绝对路径,使根目录下的demo1.jsp和demo1目录下的demo1.jsp,访问ServletDemo1。

相对路径

相对路径的写法:
 相对路径不是以 / 开头的。
 是以 ./(当前路径)和 …/(上一层路径)开头的。
相对路径的使用:

  •  在根路径下的页面访问Servlet
     demo1的访问路径:
     http://localhost:8080/web02/demo1.jsp
     ServletDemo1的访问路径:
     http://localhost:8080/web02/ServeltDemo1
    在这里插入图片描述

  •  在某个目录下的页面访问Servlet
     demo1的访问路径:
     http://localhost:8080/web02/demo1/demo1.jsp
     ServletDemo1的访问路径:
     http://localhost:8080/web02/ServeltDemo1
    在这里插入图片描述

绝对路径(推荐使用)

绝对路径的写法:
通常以 / 开始的路径

使用绝对路径,不需要关心当前文件和要请求的文件的相对位置的关系!!!

  • 注意:
    绝对路径分成服务器端路径和客户端路径
    客户端路径:需要带工程名
    服务器端路径:不需要带工程名

在这里插入图片描述

案例需求介绍

案例需求描述

提供登录页面,用于用户登录(用户名和密码需要查询数据库)。如果登录失败,需要回到登录页面(给出提示信息)。如果登录成功,页面进行跳转,在成功页面上显示登录成功的总人数。

案例流程分析

JavaWeb(7)之JSP_第7张图片

Request作为域对象存取数据

Request作为域对象的API

向Request域中保存数据
在这里插入图片描述
从Request域中获取数据
在这里插入图片描述
从Request域中移除数据
在这里插入图片描述

Request(请求)作为域对象的作用范围

Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。

一次请求范围:从客户端浏览器向服务器发送一次请求, 服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。

请求转发和重定向完成页面的跳转

请求转发

通过ServletReguest对象获得ReguestDispatcher对象
在这里插入图片描述
再根据RequestDispatcher中的方法进行请求转发
在这里插入图片描述
代码实现:

创建一个JSP 页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
	<h1>跳转后的页面h1>
body>
html>

创建一个Servlet

@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 1. 请求转发的方式
		/*
		 * RequestDispatcher dispatcher = request.getRequestDispatcher("/demo1.jsp");
		 * dispatcher.forward(request, response);
		 */
		// 也可以一条写完
		request.getRequestDispatcher("/demo1.jsp").forward(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

运行Servlet结果:
运行后直接就跳转到了JSP页面
JavaWeb(7)之JSP_第8张图片

重定向

通过HttpServletResponse 对象中的以下方法实现重定向。
在这里插入图片描述
代码实现:

@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 2. 重新定向的方式
		response.sendRedirect("/web02/demo1.jsp");
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

运行结果:
JavaWeb(7)之JSP_第9张图片

请求转发与重定向的区别

请求转发与请求重定向的区别

请求转发和重定向的原理
JavaWeb(7)之JSP_第10张图片
总结:
请求转发是一次请求一次响应,而重定向是两次请求两次响应。

请求转发地址栏不会变化的,重定向地址栏发生变化。

请求转发路径不带工程名,重定向需要带工程名路径。

请求转发只能在本网站内部,重定向可以定向到任何网站。

代码演示请求转发与重定向的区别

使用请求转发
Servlet:

@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 向request域保存数据
		request.setAttribute("name", 123);
		// 请求转发的方式
		request.getRequestDispatcher("/demo1.jsp").forward(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
	<h1>跳转后的页面h1>
	<%=request.getAttribute("name")%>
body>
html>

运行结果:
将request域中保存数据输出到了页面上
JavaWeb(7)之JSP_第11张图片
使用重定向
修改Servlet代码

@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 想request域保存数据
		request.setAttribute("name", 123);
		// 重新定向的方式
		response.sendRedirect("/web02/demo1.jsp");
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

运行结果:
输出request域中保存的数据时为null
JavaWeb(7)之JSP_第12张图片
总结:
如果需要使用request进行值传递,需要通过请求转发完成。如果页面需要调整到其他网站上必须使用重定向。

MVC在案例中的应用

MVC设计模式在JavaWeb中的应用
MVC设计模式之业务逻辑分析
JavaWeb(7)之JSP_第13张图片

案例准备-创建数据库

Create Table
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
  `password` varchar(20) DEFAULT NULL,
  `nickname` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

JavaWeb(7)之JSP_第14张图片

案例准备-项目环境搭建

创建web项目
JavaWeb(7)之JSP_第15张图片
创建相关包结构
controller:控制层
model:存放处理数据的Javabean
domain:存放数据封装的Javabean
utils:工具类
JavaWeb(7)之JSP_第16张图片

案例准备-引入相关资源(jar包)

MySQL数据库驱动包
C3PO连接池所需jar包
DBUtils开发的jar包
JavaWeb(7)之JSP_第17张图片
引入c3p0配置文件,放到工程的src下即可。

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<!-- 默认配置,如果没有指定则使用这个配置 -->
	<default-config>
		<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
		<property name="jdbcUrl">
			jdbc:mysql://localhost:3306/jdbc?useSSL=false&amp;serverTimezone=UTC
		</property>
		<property name="user">root</property>
		<property name="password">123456</property>

		<property name="checkoutTimeout">30000</property>
		<property name="idleConnectionTestPeriod">30</property>
		<property name="initialPoolSize">3</property>
		<property name="maxIdleTime">30</property>
		<property name="maxPoolSize">100</property>
		<property name="minPoolSize">2</property>
		<property name="maxStatements">200</property>
	</default-config>
</c3p0-config>

引入JDBC开发的工具类
JavaWeb(7)之JSP_第18张图片

/**
 * JDBC的工具类
 * 
 * @author 25858
 *
 */
public class JDBCUtils {
	// 创建连接池,创建连接池默认去类路径下查找c3p0-config.xml
	// 创建一个连接池:但是这个连接池只创建一次即可。
	private static final ComboPooledDataSource ds = new ComboPooledDataSource();

	/**
	 * 获得连接的方法
	 * 
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return ds.getConnection();
	}

	/**
	 * 获得连接池
	 */
	public static DataSource getDataSource() {
		return ds;
	}

}

案例准备-创建登录页面

<body>
	<h1>登录页面h1>
	<form action="" method="post">
		<table>
			<tr>
				<td>用户名:td>
				<td><input type="text" name="username">td>
			tr>
			<tr>
				<td>    码:td>
				<td><input type="password" name="password">td>
			tr>
			<tr>
				<td><input type="submit" value="登录">td>
			tr>
		table>
	form>
body>

运行结果:
JavaWeb(7)之JSP_第19张图片

案例代码-登录代码

登录代码流程:
登录页面(login.jsp) →登录的Servlet (LoginServlet),在这个Servlet中需要接收数据,将这个数据封装到一个JavaBean中,调用另一个JavaBean处理数据。根据处理结果进行页面跳转。

登录代码实现:

  1. 在controller包下创建Servlet:LoginServlet.java
  2. 在domain下创建一个User类
**
 * 用于处理数据的Javabean
 * 
 * @author 25858
 *
 */
public class User {
	private Integer uid;
	private String username;
	private String password;
	private String nickname;
	
	//get、set方法省略
}
  1. 在model包下创建一个UserModel类
    在类中提供一个login的方法
/**
 * 用于处理数据的Javabean
 * 
 * @author 25858
 *
 */
public class UserModel {
	/**
	 * 处理用户登录的方法
	 * 
	 * @param user
	 * @return
	 */
	public User login(User user) {
		// TODO 自动生成的方法存根
		return null;
	}

}
  1. 根据处理结果进行页面跳转

登录的Servlet代码

/**
 * 
 * @author 25858
 *
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		// 1.接收数据
		// 处理中文乱码
		req.setCharacterEncoding("UTF-8");
		String name = req.getParameter("username");
		String password = req.getParameter("password");
		// 2.封装数据
		User user = new User();
		user.setUsername(name);
		user.setPassword(password);
		// 3.处理数据
		UserModel userModel = new UserModel();
		User existUser = userModel.login(user);
		// 4.页面跳转
		if (existUser == null) {
			// 登录失败
			// 向request域中保存一个错误信息
			req.setAttribute("msg", "用户名或密码错误!!!");
			// 使用请求转发的方式进行页面跳转
			req.getRequestDispatcher("/login.jsp");
		} else {
			// 登录成功
			// 使用重定向的方式进行页面跳转
			res.sendRedirect("/web_login/success.jsp");
		}
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

案例代码-登录代码底层代码

处理数据部分代码:

/**
 * 用于处理数据的Javabean
 * 
 * @author 25858
 *
 */
public class UserModel {
	/**
	 * 处理用户登录的方法
	 * 
	 * @param user
	 * @return
	 * @throws SQLException
	 */
	public User login(User user) throws SQLException {
		// 连接数据库:通过传入的用户名和密码去数据中查询
		QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
		User existUser = qr.query("select * from user where username=? and password=?",
				new BeanHandler<User>(User.class), user.getUsername(), user.getPassword());
		return existUser;
	}

}

案例代码-登录代码错误信息的回显

	<h1>登录页面h1>
	<%
		//判断request域中是否有错误信息: (第一次进入登录页面的时候,没有错误信息)
		//如果有错误信息:显示错误信息
		String msg = " ";
		if (request.getAttribute("msg") != null) {
			//有错误信息,显示错误信息
			msg = (String) request.getAttribute("msg");
		}
	%>
	<h3>
		<font color="red"><%=msg%>font>
	h3>

效果:
JavaWeb(7)之JSP_第20张图片

案例代码-记录登录成功人数

画图分析:
JavaWeb(7)之JSP_第21张图片
完成初始化操作
代码实现:
在服务器启动的时候初始化一个值为零,将这个值存入到ServletContext域中。

**
 * 初始化的Servlet
 * *将这个Servlet配置成启动加载
 * @author 25858
 *
 */
@WebServlet("/InitServlet")
public class InitServlet extends HttpServlet {
	@Override
	/**
	 * 初始化的方法
	 */
	public void init() throws ServletException {
		// 初始一个值为0
		int count = 0;
		// 将这个值存入到ServletContext
		this.getServletContext().setAttribute("count", count);
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

将这个Servlet配置成启动时加载,在web.xml中配置
Servlet的启动时加载

	<!-- 将InitServlet使用web.xml的方式配置 -->
	<servlet>
		<servlet-name>InitServlet</servlet-name>
		<servlet-class>con.wxw.controller.InitServlet</servlet-class>
		<!-- 配置启动时加载 -->
		<load-on-startup>2</load-on-startup>
	</servlet>

记录登录成功的人数

		// 4.页面跳转
		if (existUser == null) {
			// 登录失败
			// 向request域中保存一个错误信息
			req.setAttribute("msg", "用户名或密码错误!!!");
			// 使用请求转发的方式进行页面跳转
			req.getRequestDispatcher("/login.jsp").forward(req, res);
		} else {
			// 登录成功
			// 记录登录成功的人数
			// 将ServletContext中的值取出+1
			int count = (int) this.getServletContext().getAttribute("count");
			// 进行+1的操作
			count++;
			// 将+1的值放回ServletContext中去
			this.getServletContext().setAttribute("count", count);
			// 使用重定向的方式进行页面跳转
			res.sendRedirect("/web_login/success.jsp");
		}

在成功登录页面(success.jsp)上显示总人数

<body>
	<%
		Integer count = 0;
		//判断,如果ServletContext中有值,获取并显示
		if (this.getServletContext().getAttribute("count") != null) {
			count = (Integer) this.getServletContext().getAttribute("count");
		}
	%>
	<h3>
		登录总人数:<%=count%>
	</h3>
	<h1>登录成功</h1>
</body>

案例源码

链接:https://pan.baidu.com/s/1JuhpMXsXAOceewLeMcqB1Q
提取码:buzt

你可能感兴趣的:(JavaWeb)