共计 6218 个字符,预计需要花费 16 分钟才能阅读完成。
(jsp 入门 &mvc& 案例)
一、学习目标
- 阐述什么是 JSP 及其运行原理
- 阐述 JSP 中如何嵌入脚本元素以及软件开发模式的发展历程
- 解决开发中的路径问题:相对路径与绝对路径
- 阐述请求转发和重定向的区别(面试重点)
- 完成案例开发的准备工作:数据库、环境搭建、jar 包
- 完成登录功能的分析与代码实现(重点)
- 完成记录登录成功人数功能分析与代码实现(重点)
JSP 的概述
什么是 JSP
JSP:Java Server Pages (Java 服务器端页面),其实就在 HTML 中嵌入 Java 代码。
为什么学习JSP
SUN 公司提供了动态网页开发技术:Servlet。Servlet 自身有一些缺点,SUN 公司发现了这些问题,推出了一个新的动态网页开发技术 JSP。
Servlet 的缺点:
- Servlet 需要进行配置,不方便维护
- Servlet 很难向网页中输出 HTML 页面内容
JSP的运行原理
JSP的简单使用
创建一个 JSP 页面
运行 JSP
JSP 需要发布到服务器中才可以运行的。
- 发布项目到 Tomcat 中
- 访问 JSP 页面
JSP 的运行原理
JSP 文件翻译成 Java 文件,将这个 Java 文件编译生成 class 文件,运行 class 文件。
JSP 的脚本元素
什么是 JSP 的脚本元素
JSP = HTML + Java 代码 + JSP 自身东西
JSP 的脚本元素就是在 JSP 中嵌入 Java 代码。
JSP 的脚本元素的分类
声明标签
- 语法:
-
- <%! 变量或方法声明 %>
- 写在这个脚本中的代码,翻译成 Servlet 内部的成员变量或成员方法。
- 用法:
表达式标签
- 语法:
-
- <%= 表达式 %>
- 写在这个脚本中的代码,翻译成方法内部的 out.print(); 当中的内容。
- 用法:
程序代码标签
- 语法:
-
- <% 程序代码 %>
- 写在这个脚本中的代码,翻译成方法内部的局部变量或方法内部代码片段。
- 用法:
JSP 的开发模式之 MVC 模式
JSP 开发模式
动态网页开发模式的发展
开发中的路径问题
路径问题描述
什么时候会遇到路径问题
提供一些页面,在页面中会提供链接或者表单,当点击链接或者表单的时候需要进行提交,提交到 Servlet 中。从页面向 Servlet 发送请求的地址(路径)应该如何编写。
路径的分类
相对路径
- 相对路径的写法:
-
- 相对路径不是以 / 开头的。
- 相对路径的使用:
-
- 在跟路径下的页面访问 Servlet
demo2.jsp 的访问路径:
http://localhost:8080/web02/demo2.jsp
ServletDemo1 的访问路径:
http://localhost:8080/web02/ServletDemo1
-
- 在某个目录下的页面访问 Servlet
demo2.jsp 的访问路径:
http://localhost:8080/web02/demo2/demo2.jsp
ServletDemo1 的访问路径:
http://localhost:8080/web02/ServletDemo1
绝对路径(通常)
- 绝对路径的写法:
-
- 通常以 / 开始的路径
使用绝对路径,不需要关心当前文件和要请求的文件的相对位置的关系!!!
- 注意:
-
- 绝对路径分成服务器端路径和客户端路径
- 客户端路径 需要带工程名
- 服务器端路径 不需要带工程名
案例
案例需求
案例需求描述
提供登录页面,用于用户登录(用户名和密码需要查询数据库)。如果登录失败,需要回到登录页面(给出提示信息)。如果登录成功,页面进行跳转,在成功页面上显示登录成功的总人数。
案例流程分析
Request 作为域对象存取数据
Request 作为域对象作用范围
Request 对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向 Request 中所保存的数据有效期也是 一次请求范围。
一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
请求转发和重定向完成页面跳转
请求转发
请求转发的写法
通过 ServletRequest 对象获得 RequestDispatcher 对象。
再根据 RequestDispatcher 中的方法进行请求转发。
请求转发的代码实现
请求转发的效果
重定向
重定向的写法
通过 HttpServletResponse 对象中的以下方法实现重定向
重定向的代码实现
重定向的效果
请求转发和重定向区别
请求转发和重定向原理
请求转发和重定向区别总结
- 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
- 请求转发地址栏不会变化的,重定向地址栏发生变化。
- 请求转发路径不带工程名,重定向需要带工程名路径。
- 请求转发只能在本网站内部,重定向可以定向到任何网站。
代码演示请求转发和重定向区别
- 注意:
如果需要使用 request 进行值传递,需要通过请求转发完成。如果页面需要跳转到其他网站上必须使用重定向。
MVC 在案例中的应用
案例准备 – 创建数据库
创建数据库
建表语句
create database web02_login;
use web02_login;
create table user(
uid int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(20)
);
insert into user values (null,’zs’,’123′,’ 张三 ’);
insert into user values (null,’ls’,’123′,’ 李四 ’);
insert into user values (null,’ww’,’123′,’ 王五 ’);
案例准备项目环境搭建
项目环境搭建
创建 web 项目
创建相关的包结构
案例准备引入相关资源
引入相关资源
引入相关的 jar 包:
- MySQL 数据库驱动包
- C3P0 连接池所需 jar 包
- DBUtils 开发的 jar 包
引入 C3P0 配置文件
将配置文件放到工程的 src 下即可
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///u1</property>
<!-- 注意数据库表的路径及名称 -->
<property name="user">root</property>
<property name="password">123</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
案例准备创建登录页面
创建登录页面
登录页面实现
<form action="/web02_login/LoginServlet" method="post">
<table border="1" width="400">
<tr>
<td> 用户名 </td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td> 密码 </td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
登录页面效果
引入 JDBC 开发的工具类
案例代码登录代码实现
登录代码实现
登录代码实现流程
登录页面(login.jsp)登录的 Servlet(LoginServlet),在这个 Servlet 中需要接收数据,将这个数据封装到一个 JavaBean 中,调用另一个 JavaBean 处理数据。根据处理结果进行页面跳转。
登录代码实现
- 第一步:在 controller 包下创建 LoginServlet
- 第二步:在 domain 下创建一个 User 类
- 第三步:在 model 包下创建一个 UserModel 类
在这个类中提供一个 login 的方法
- 第四步:根据处理结果进行页面跳转
登录的 Servlet 的业务代码
/**
* 登录的 Servlet 的编写
*/
public class LoginServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try{
// 1. 接收数据
// 处理中文乱码
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
// 2. 封装数据
User user = new User();
user.setUsername(username);
user.setPassword(password);
// 3. 处理数据
UserModel userModel = new UserModel();
User existUser = userModel.login(user);
// 4. 页面跳转
if(existUser == null){
// 登录失败
// 向 request 域中保存一个错误信息:request.setAttribute("msg", "用户名或密码错误!");
// 使用请求转发进行页面跳转
request.getRequestDispatcher("/login.jsp").forward(request, response);
}else{
// 登录成功
this.getServletContext().setAttribute("count", count);
// 重定向到成功页面
response.sendRedirect("/web02_login/success.jsp");
}
}catch(Exception e){e.printStackTrace();
throw new RuntimeException();}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);
}
}
案例代码登录代码底层代码
登录底层代码
处理数据部分代码
public class UserModel {
/**
* 处理用户登录的方法:*
* @param user
* @return
* @throws SQLException
*/
public User login(User user) throws SQLException {
// 连接数据库:通过传入的用户名和密码去数据库中进行查询
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
User existUser = queryRunner.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>
错误信息显示效果
案例代码记录登录成功人数分析
记录登录成功的人数分析
画图分析
案例代码记录登录成人数代码实现
记录登录成功人数的代码
完成初始化操作
- 在服务器启动的时候初始化一个值为零,将这个值存入到 ServletContext 域中。
/**
* 初始化的 Servlet
* * 将这个 Servlet 配置成启动时加载
*/
public class InitServlet extends HttpServlet {
@Override
/**
* 初始化的方法:
*/
public void init() throws ServletException {
// 初始一个值为 0。int count = 0;
// 将这个值存入到 ServletContext 域中。this.getServletContext().setAttribute("count", count);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);
}
}
- 将这个 Servlet 配置成启动时加载
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.itheima.controller.InitServlet</servlet-class>
<!-- 配置启动时加载 -->
<load-on-startup>2</load-on-startup>
</servlet>
记录登录成功的人数
// 记录登录成功的人数:// 将 ServletContext 中的值取出 +1
int count = (int) this.getServletContext().getAttribute("count");
// 进行了 + 1 的操作
count++;
// 将 + 1 后的值存回到 ServletContext 中去。
在登录成功页面上显示总人数
<h1> 登录成功的页面!</h1>
<%
Integer count = 0;
// 判断,如果 ServletContext 中有值,获取并显示:if(this.getServletContext().getAttribute("count")!=null){count = (Integer)this.getServletContext().getAttribute("count");
}
%>
<h3> 登录成功的总人数:<%= count %></h3>
</body>
</html>