(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>