java web 实验五 Servlet控制层设计(设计性)

发布于:2024-12-18 ⋅ 阅读:(8) ⋅ 点赞:(0)
实验  Servlet控制层设计(设计性)

//代码放在资源包里了

  1. 实验目的
    1. 熟悉Servlet的基本语法。
    2. 掌握采用HTML、JS、JDBC、JSP、Servlet和四层结构的综合应用。
  2. 实验要求
    1. 本实验要求每个同学单独完成;
    2. 调试程序要记录调试过程中出现的问题及解决办法,并写入到实验总结和心得;
    3. 完成实验后直接在题目后面按要求给出本实验的实验报告。
  3. 实验设备、环境

奔腾以上计算机,装有Myeclipse 6.0以上。

  1. 实验内容
    1. 使用前面所介绍的Servlet知识构建一个登陆应用,具体要求如下:
    1. 创建一个登陆应用,如下图所示。
    2. 用户输入登陆信息,如用户名和密码,
    3. LoginServlet调用UserBean完成身份验证(编写UserService,UserDao类,完成数据的访问),如果身份验证成功,跳转到成功页面,否则,跳转到失败页面。

`

把程序运行界面截图贴在这里,源码贴到附录部分

    1. 使用Servlet和四层结构知识,改进实验四中题4.2的用户信息管理系统,使其具有更好的软件结构,以及提升可读性和可扩展性。

把程序运行界面截图贴在这里,源码贴到附录部分

  1. 实验总结与心得请详细叙述你通过该实验掌握的知识点和心得,比如对错误的解决办法等)

问题:

1.java.lang.IllegalArgumentException: 名为 [LoginServlet]和 [com.example.controller.LoginServlet] 的servlet不能映射为一个url模式(url-pattern) [/login]

有两个Servlet试图映射到相同的URL模式(/login),这是不允许的。以下是解决此问题的步骤:

后面重新检查了web.xml配置解决了问题

<servlet>

    <servlet-name>LoginServlet</servlet-name>

    <servlet-class>com.example.controller.LoginServlet</servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>LoginServlet</servlet-name>

    <url-pattern>/login</url-pattern>

</servlet-mapping>

   

      2. SQL异常处理:在与数据库交互时,我经常遇到SQLException。我学会了如何使用try-catch块来捕获异常,并在控制台输出错误信息。这不仅帮助我快速定位问题,还让我意识到在生产环境中需要更优雅的错误处理机制,比如记录日志或向用户显示友好的错误信息。

3.表单验证:在用户注册和登录过程中,我发现表单输入的有效性非常重要。我通过在JSP中使用required属性来确保用户输入的完整性。此外,我还学习了如何在服务层中进行更复杂的验证,比如检查用户名是否已存在。

4.调试技巧:在调试过程中,我使用了System.out.println和调试器来跟踪程序的执行流程。这让我能够清晰地看到每一步的输出,帮助我理解程序的运行状态。

  

心得:

表现层:学习了如何使用JSP页面来构建用户界面。通过JSP,我能够动态生成HTML内容,并与用户进行交互。理解了如何使用JSP表达式和脚本来处理用户输入和显示信息。

  

控制层:在UserServlet中,我实现了请求的处理逻辑。通过doPost和doGet方法,我能够根据不同的请求参数(如action)调用相应的服务层方法。这让我认识到控制层在MVC架构中的重要性,它负责协调表现层和服务层之间的交互。

服务层:在UserService中,我实现了用户注册、删除和验证等业务逻辑。通过将业务逻辑与控制层分离,我提高了代码的可维护性和可读性。这一层的设计让我意识到,良好的业务逻辑封装可以使得后续的功能扩展更加容易。

数据访问层:在UserDAO中,我学习了如何使用JDBC与数据库进行交互。通过封装数据库操作,我能够更好地管理数据访问逻辑,避免在控制层中直接处理SQL语句。这种分层设计使得代码更加模块化。

  1. 源码附录

4.1实验

DatabaseConnection.java

package com.example;

import java.sql.Connection;

import java.sql.DriverManager;

// 数据库连接类

public class DatabaseConnection {

    // 获取数据库连接的方法

    public static Connection getConnection() {

        Connection con = null; // 初始化连接对象

        try {

            // 加载MySQL JDBC驱动

            Class.forName("com.mysql.cj.jdbc.Driver");

            // 连接到数据库

            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_system", "root", "123456");

        } catch (Exception e) {

            e.printStackTrace(); // 打印异常信息

        }

        return con; // 返回连接对象

    }

}

package com.example;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet("/LoginServlet") // 映射URL到此Servlet

public class LoginServlet extends HttpServlet {

 private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 获取用户输入的用户名和密码

        String username = request.getParameter("username");

        String password = request.getParameter("password");

        // 创建UserService实例以验证用户

        UserService userService = new UserService();

        boolean isValidUser = userService.validateUser(username, password);

        // 根据验证结果重定向到相应的页面

        if (isValidUser) {

            response.sendRedirect("success.jsp"); // 验证成功,跳转到成功页面

        } else {

            response.sendRedirect("failure.jsp"); // 验证失败,跳转到失败页面

        }

    }

}

package com.example;

// 用户数据模型类

public class UserBean {

    private String username; // 用户名

    private String password; // 密码

    // 获取用户名

    public String getUsername() {

        return username;

    }

    // 设置用户名

    public void setUsername(String username) {

        this.username = username;

    }

    // 获取密码

    public String getPassword() {

        return password;

    }

    // 设置密码

    public void setPassword(String password) {

        this.password = password;

    }

}

package com.example;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

// 数据访问类,用于与数据库交互

public class UserDao {

    // 验证用户凭据的方法

    public boolean validate(String username, String password) {

        boolean status = false; // 默认状态为无效用户

        try {

            // 获取数据库连接

            Connection con = DatabaseConnection.getConnection(); // 假设您有一个DatabaseConnection类

            // 准备SQL查询

            PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE username=? AND password=?");

            ps.setString(1, username); // 设置用户名参数

            ps.setString(2, password); // 设置密码参数

            ResultSet rs = ps.executeQuery(); // 执行查询

            status = rs.next(); // 如果找到记录,则用户有效

        } catch (Exception e) {

            e.printStackTrace(); // 打印异常信息

        }

        return status; // 返回用户验证状态

    }

}

package com.example;

// 用户服务类,处理用户相关的业务逻辑

public class UserService {

    private UserDao userDao = new UserDao(); // 创建UserDao实例

    // 验证用户的方法

    public boolean validateUser(String username, String password) {

        return userDao.validate(username, password); // 调用UserDao的验证方法

    }

}

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

<!DOCTYPE html>

<html>

<head>

    <title>Failure</title>

</head>

<body>

    <h2>登录失败</h2>

    <!-- 登录失败后的提示 -->

</body>

</html>

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

<!DOCTYPE html>

<html>

<head>

    <title>Login</title>

</head>

<body>

    <h2>登录</h2>

    <!-- 表单提交到LoginServlet -->

    <form action="LoginServlet" method="post">

        用户名: <input type="text" name="username" required /><br />

        密码: <input type="password" name="password" required /><br />

        <input type="submit" value="登录" />

    </form>

</body>

</html>

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

<!DOCTYPE html>

<html>

<head>

    <title>Success</title>

</head>

<body>

    <h2>登录成功</h2>

    <!-- 登录成功后的提示 -->

</body>

</html>

4.2实验

editUser

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

         version="3.1">

    <servlet>

        <servlet-name>UserServlet</servlet-name>

        <servlet-class>com.example.controller.UserServlet</servlet-class> <!-- 确保包名正确 -->

    </servlet>

    <servlet-mapping>

        <servlet-name>UserServlet</servlet-name>

        <url-pattern>/user</url-pattern>

    </servlet-mapping>

    <servlet>

        <servlet-name>LoginServlet</servlet-name>

        <servlet-class>com.example.controller.LoginServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>LoginServlet</servlet-name>

        <url-pattern>/login</url-pattern>

    </servlet-mapping>

    

    

</web-app>

Index.jsp

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

<html>

<head>

    <title>用户信息管理系统</title>

</head>

<body>

    <h1>欢迎来到用户信息管理系统</h1>

    <a href="login.jsp">登录</a> | <a href="register.jsp">注册</a>

</body>

</html>

Login.jsp

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

<html>

<head>

    <title>用户登录</title>

</head>

<body>

    <h1>用户登录</h1>

    <form action="login" method="post">

        用户名: <input type="text" name="username" required><br>

        密码: <input type="password" name="password" required><br>

        <input type="submit" value="登录">

    </form>

    <%

        String errorMessage = (String) request.getAttribute("errorMessage");

        if (errorMessage != null) {

            out.println("<p>" + errorMessage + "</p>");

        }

    %>

</body>

</html>

Register.jsp

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

<html>

<head>

    <title>注册</title>

</head>

<body>

    <h1>用户注册</h1>

    <form action="user" method="post">

        <input type="hidden" name="action" value="register">

        用户名: <input type="text" name="username" required><br>

        密码: <input type="password" name="password" required><br>

        年龄: <input type="number" name="age" required><br>

        <input type="submit" value="注册">

    </form>

</body>

</html>

userList.jsp

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

<%@ page import="com.example.entity.User" %>

<%@ page import="com.example.service.UserService" %>

<%@ page import="java.util.List" %>

<%@ page import="java.sql.SQLException" %>

<html>

<head>

    <title>用户列表</title>

    <script>

        function confirmDelete() {

            return confirm("您确定要删除该用户吗?");

        }

    </script>

</head>

<body>

    <h1>用户列表</h1>

    <%

        String deleteMessage = request.getParameter("message");

        if (deleteMessage != null) {

    %>

        <p style="color: green;"><%= deleteMessage %></p>

    <%

        }

    %>

    <h2>通过 JavaBean 删除用户</h2>

    <form action="user" method="post" οnsubmit="return confirmDelete();">

        <input type="hidden" name="action" value="delete">

        <label for="usernameToDelete">用户名:</label>

        <input type="text" id="usernameToDelete" name="username" required>

        <input type="submit" value="删除用户">

    </form>

    <table border="1">

        <tr>

            <th>用户名</th>

            <th>年龄</th>

            <th>操作</th>

        </tr>

        <%

            UserService userService = new UserService();

            try {

                List<User> users = userService.getAllUsers();

                for (User user : users) {

        %>

        <tr>

            <td><%= user.getUsername() %></td>

            <td><%= user.getAge() %></td>

            <td>

                <form action="user" method="post" style="display:inline;">

                    <input type="hidden" name="action" value="edit">

                    <input type="hidden" name="username" value="<%= user.getUsername() %>">

                    <input type="submit" value="编辑">

                </form>

            </td>

        </tr>

        <%

                }

            } catch (SQLException e) {

                e.printStackTrace();

                out.println("<tr><td colspan='3'>无法获取用户列表: " + e.getMessage() + "</td></tr>");

            }

        %>

    </table>

    <a href="login.jsp">注销</a>

</body>

</html>

package com.example.controller;

import javax.servlet.ServletException;

import javax.servlet.http.*;

import com.example.service.UserService;

import java.io.IOException;

import java.sql.SQLException;

public class LoginServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    private UserService userService = new UserService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");

        String password = request.getParameter("password");

        try {

            if (userService.validateUser(username, password)) {

                request.getSession().setAttribute("user", username);

                response.sendRedirect("userList.jsp");

            } else {

                request.setAttribute("errorMessage", "用户名或密码错误");

                request.getRequestDispatcher("login.jsp").forward(request, response);

            }

        } catch (SQLException e) {

            e.printStackTrace();

            response.sendRedirect("login.jsp?message=登录失败: " + e.getMessage());

        }

    }

}

//控制层(Controller Layer):负责接收用户请求并调用相应的服务层逻辑。在你的项目中,UserServlet类就是控制层的实现,它处理用户的请求,如注册、删除和更新用户信息。

package com.example.controller;

import java.io.IOException;

import java.sql.SQLException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.net.URLEncoder;

import com.example.entity.User;

import com.example.service.UserService;

public class UserServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    private UserService userService = new UserService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String action = request.getParameter("action");

        String username = request.getParameter("username");

        try {

            if ("register".equals(action)) {

                String password = request.getParameter("password");

                int age = Integer.parseInt(request.getParameter("age"));

                User user = new User(username, password, age);

                userService.registerUser(user);//调用userService中的registerUser方法

                response.sendRedirect("login.jsp");

            } else if ("delete".equals(action)) {

                userService.deleteUser(username);

                response.sendRedirect("userList.jsp?message=" + URLEncoder.encode("用户 " + username + " 已成功删除。", "UTF-8"));

            } else if ("edit".equals(action)) {

                User user = userService.getUser(username);

                request.setAttribute("user", user);

                request.getRequestDispatcher("editUser.jsp").forward(request, response);

            } else if ("save".equals(action)) {

                String password = request.getParameter("password");

                int age = Integer.parseInt(request.getParameter("age"));

                User user = new User(username, password, age);

                userService.updateUser(user);

                response.sendRedirect("userList.jsp?message=用户 " + username + " 信息已成功保存。");

            }

        } catch (SQLException e) {

            e.printStackTrace();

            response.sendRedirect("userList.jsp?message=操作失败: " + e.getMessage());

        }

    }

}

package com.example.dao;

// UserDAO.java

import java.sql.*;

import java.util.ArrayList;

import java.util.List;

import com.example.entity.User;

public class UserDAO {

    private String jdbcURL = "jdbc:mysql://localhost:3306/user_management";

    private String jdbcUsername = "root";

    private String jdbcPassword = "123456";

    

    public void registerUser(User user) throws SQLException {

        String sql = "INSERT INTO users (username, password, age) VALUES (?, ?, ?)";

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             PreparedStatement ps = connection.prepareStatement(sql)) {

            ps.setString(1, user.getUsername());

            ps.setString(2, user.getPassword());

            ps.setInt(3, user.getAge());

            ps.executeUpdate();

        } catch (SQLException e) {

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

    }

    

    public List<User> getAllUsers() throws SQLException {

        List<User> users = new ArrayList<>();

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             Statement stmt = connection.createStatement();

             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            while (rs.next()) {

                String username = rs.getString("username");

                String password = rs.getString("password");

                int age = rs.getInt("age");

                users.add(new User(username, password, age));

            }

        } catch (SQLException e) {

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

        return users;

    }

    public void deleteUser(String username) throws SQLException {

        // 使用 try-with-resources 确保连接和语句被正确关闭

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             PreparedStatement statement = connection.prepareStatement("DELETE FROM users WHERE username=?")) {

            statement.setString(1, username);

            statement.executeUpdate();

        } catch (SQLException e) {

            // 记录异常信息

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

    }

    public User getUser(String username) throws SQLException {

        User user = null;

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             PreparedStatement ps = connection.prepareStatement("SELECT * FROM users WHERE username=?")) {

            ps.setString(1, username);

            ResultSet rs = ps.executeQuery();

            if (rs.next()) {

                String password = rs.getString("password");

                int age = rs.getInt("age");

                user = new User(username, password, age);

            }

        } catch (SQLException e) {

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

        return user;

    }

    public void updateUser(User user) throws SQLException {

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             PreparedStatement ps = connection.prepareStatement("UPDATE users SET password=?, age=? WHERE username=?")) {

            ps.setString(1, user.getPassword());

            ps.setInt(2, user.getAge());

            ps.setString(3, user.getUsername());

            ps.executeUpdate();

        } catch (SQLException e) {

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

    }

    public boolean validateUser(String username, String password) throws SQLException {

        try (Connection connection = DriverManager.getConnection(jdbcURL, jdbcUsername, jdbcPassword);

             PreparedStatement ps = connection.prepareStatement("SELECT * FROM users WHERE username=? AND password=?")) {

            ps.setString(1, username);

            ps.setString(2, password);

            ResultSet rs = ps.executeQuery();

            return rs.next();

        } catch (SQLException e) {

            e.printStackTrace();

            throw e; // 重新抛出异常以便上层处理

        }

    }

}

//数据访问层: 负责与数据库进行交互,执行SQL查询和更新操作。UserDAO类则实现了这一层的功能,通过JDBC与数据库进行交互。

package com.example.entity;

public class User {

    private String username;

    private String password;

    private int age;

    public User(String username, String password, int age) {

        this.username = username;

        this.password = password;

        this.age = age;

    }

    // Getters and Setters

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

}

package com.example.service;

import com.example.dao.UserDAO;

import com.example.entity.User;

import java.sql.SQLException;

import java.util.List;

public class UserService {

    private UserDAO userDAO = new UserDAO();

    

    public void registerUser(User user) throws SQLException {

        userDAO.registerUser(user); // 调用 UserDAO 的 registerUser 方法

    }

    

    public List<User> getAllUsers() throws SQLException {

        return userDAO.getAllUsers();

    }

    public void deleteUser(String username) throws SQLException {

        try {

userDAO.deleteUser(username);

} catch (Exception e) {

// TODO 自动生成的 catch 块

e.printStackTrace();

}

    }

    public User getUser(String username) throws SQLException {

        try {

return userDAO.getUser(username);

} catch (Exception e) {

// TODO 自动生成的 catch 块

e.printStackTrace();

}

return null;

    }

    public void updateUser(User user) throws SQLException {

        try {

userDAO.updateUser(user);

} catch (Exception e) {

// TODO 自动生成的 catch 块

e.printStackTrace();

}

    }

    public boolean validateUser(String username, String password) throws SQLException {

        return userDAO.validateUser(username, password);

    }

}

//服务层:负责业务逻辑的处理。你的UserService类实现了用户相关的业务逻辑,例如注册、删除和验证用户。