jsp入门mvc案例

54次阅读

共计 6218 个字符,预计需要花费 16 分钟才能阅读完成。

(jsp 入门 &mvc& 案例)

一、学习目标

  1. 阐述什么是 JSP 及其运行原理
  2. 阐述 JSP 中如何嵌入脚本元素以及软件开发模式的发展历程
  3. 解决开发中的路径问题:相对路径与绝对路径
  4. 阐述请求转发和重定向的区别(面试重点)
  5. 完成案例开发的准备工作:数据库、环境搭建、jar 包
  6. 完成登录功能的分析与代码实现(重点)
  7. 完成记录登录成功人数功能分析与代码实现(重点)

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>

正文完
 0