第二次作业

发布时间 2023-11-26 19:59:13作者: lzufe_slj

一、作业目的

       1.掌握软件开发的基本流程

       2.掌握常用的软件开发方式和工具。

二、作业内容

        设计一个包含登录界面的计算器软件,该软件可以实现第一次作业中的全部功能,同时使用数据库可以保存用户的历史计算记录和时间。

三、实现的功能

     1.计算器的实现

     2.登录功能的实现

     3.进行加减乘除运算并用数据库对这些数据进行保存

在对数据库的操作上用mybatis取代了传统的jdbc链接数据库和sql语句的操作.

 

四、流程图

 五、功能界面展示

 

用户登录页面

 计算器页面

 

 数据库页面

 

 六、代码部分

SaveResultServlet类

package com.lzufe.controller;

import com.lzufe.entity.vo.MessageModel;
import com.lzufe.service.UserService;
import com.lzufe.entity.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "SaveResultServlet", urlPatterns = {"/save"})
public class SaveResultServlet extends HttpServlet {
    
    private UserService userService = new UserService();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理GET请求的逻辑,或者留空
        System.out.println("Received GET request to /SaveResultServlet");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // 获取计算结果参数
            String calculatorExpression = request.getParameter("result");

            // session 用于存储已登录的用户信息
            User loggedInUser = (User) request.getSession().getAttribute("user");

            
// 检查 calculatorExpression 是否为 null
            if (calculatorExpression != null) {
                try {
                    // 调用 UserService 的方法保存计算结果
                    MessageModel saveResultModel = userService.saveCalculatorResult(loggedInUser.getUserName(), calculatorExpression);

                    // ...
                } catch (Exception e) {
                    e.printStackTrace();
                    // 处理其他异常
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.getWriter().write("{\"error\": \"Internal Server Error\"}");
                }
            } else {
                // 如果 calculatorExpression 为 null,可以返回一个错误响应
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"error\": \"calculatorExpression is null\"}");
            }
        } catch (Exception e) {
            e.printStackTrace(); // 将异常信息打印到控制台
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("{\"error\": \"Internal Server Error\"}");
        }
    }
}

  UserServlet类

package com.lzufe.controller;

import com.lzufe.entity.vo.MessageModel;
import com.lzufe.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/login")
public class UserServlet extends HttpServlet {


    //实例化UserService对象
    private UserService userService = new UserService();

    /**
     * 用户登录
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.接受客户端的请求(接受参数,姓名,密码)
        String uname = request.getParameter("uname");
        String upwd = request.getParameter("upwd");
        //2.调用service层的方法,返回消息模型对象
        MessageModel messageModel = userService.userLogin(uname,upwd);
        //3.判断消息模型的状态码
        if(messageModel.getCode()==1)
        {
            //成功
            request.getSession().setAttribute("user",messageModel.getObject());
            response.sendRedirect("index.jsp");
        }
        else{
            //失败
            //将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
            request.setAttribute("messageModel",messageModel);
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }

    }
}

MessageModel类

package com.lzufe.entity.vo;

/**
 * 消息模型对象(数据响应)
 * 状态码
 *  1=成功 2=失败
 *  提示信息
 *      字符串
 *  回显数据
 *      object对象
 */
public class MessageModel {
    private Integer code = 1;//状态码,1=成功 2=失败
    private String msg;//提示信息
    private  Object object;//回显对象(基本数据类型,字符串类型,list,map等)
    private boolean operationSuccess;  // 新增属性,表示数据库操作是否成功

    public boolean isOperationSuccess() {
        return operationSuccess;
    }

    public void setOperationSuccess(boolean operationSuccess) {
        this.operationSuccess = operationSuccess;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
}

CalculatorResult类

package com.lzufe.entity;

public class CalculatorResult {

    String uname;

    String result;// 新增用户名字段


    public CalculatorResult(String uname, String result) {
        this.result = result;
        this.uname = uname;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }
}

User类

package com.lzufe.entity;

/**
 * User实体类
 */
public class User {

    private String userName;//用户姓名
    private String pwd;//用户密码

    public User( String userName, String pwd) {
        this.userName = userName;
        this.pwd = pwd;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

CalculatorResultMapper接口类

package com.lzufe.mapper;

import com.lzufe.entity.CalculatorResult;
public interface CalculatorResultMapper {
    void saveResult(CalculatorResult result);
}

CalculatorResultMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lzufe.mapper.CalculatorResultMapper">

    <insert id="saveResult" parameterType="com.lzufe.entity.CalculatorResult">
        INSERT INTO calculator_results (result, uname) VALUES (#{result}, #{uname})
    </insert>
</mapper>

UserMapper接口类

package com.lzufe.mapper;

import com.lzufe.entity.User;

/**
 * 用户接口类
 */
public interface UserMapper {
    public User queryUserByName(String username);

    public void addUser(User user);

}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lzufe.mapper.UserMapper">
    <select id="queryUserByName" parameterType="String" resultType="com.lzufe.entity.User">
        select * from tb_user where username = #{username}
    </select>

</mapper>

CalculatorService类

package com.lzufe.service;

import com.lzufe.entity.CalculatorResult;
import com.lzufe.entity.vo.MessageModel;
import com.lzufe.mapper.CalculatorResultMapper;
import com.lzufe.util.GetSqlSession;
import com.lzufe.util.StringUtil;
import org.apache.ibatis.session.SqlSession;

public class CalculatorService {
    /**
     * 保存计算结果
     *
     * @param uname  用户名
     * @param result 计算结果
     * @return
     */
    public MessageModel saveCalculatorResult(String uname, String result) {
        MessageModel messageModel = new MessageModel();

        // 参数的非空判断
        if (StringUtil.isEmpty(uname) || result == null) {
            messageModel.setCode(0);
            messageModel.setMsg("用户名和计算结果不能为空");
            return messageModel;
        }

        // 创建 CalculatorResult 对象
        CalculatorResult calculatorResult = new CalculatorResult(uname,result);
        calculatorResult.setUname(uname);
        calculatorResult.setResult(result);

        // 保存计算结果到数据库
        try (SqlSession session = GetSqlSession.createSqlSession()) {
            CalculatorResultMapper resultMapper = session.getMapper(CalculatorResultMapper.class);
            resultMapper.saveResult(calculatorResult);
            session.commit();
            messageModel.setOperationSuccess(true);
            messageModel.setObject(calculatorResult);
        } catch (Exception e) {
            e.printStackTrace();
            messageModel.setCode(0);
            messageModel.setMsg("保存计算结果时发生错误");
            messageModel.setOperationSuccess(false);
            // 记录日志
            // Logger.getLogger(CalculatorService.class.getName()).log(Level.SEVERE, null, e);
        }

        return messageModel;
    }

}

UserService类

package com.lzufe.service;

import com.lzufe.entity.User;
import com.lzufe.entity.vo.MessageModel;
import com.lzufe.mapper.UserMapper;
import com.lzufe.util.GetSqlSession;
import com.lzufe.util.StringUtil;
import org.apache.ibatis.session.SqlSession;

/**
 * 业务逻辑
 */
public class UserService {
    /**
     * 用户登录
     * @param uname
     * @param upwd
     * @return
     */
    public MessageModel userLogin(String uname, String upwd) {
        MessageModel messageModel = new MessageModel();
        //回显数据
//        User u = new User();
//        u.setUserName(uname);
//        u.setPwd(upwd);
//        messageModel.setObject(u);

        //1.参数的非空判断
        if (StringUtil.isEmpty(uname) ||StringUtil.isEmpty(upwd))
        {
            messageModel.setCode(0);
            messageModel.setMsg("用户姓名和密码不能为空");
            return messageModel;
        }
        //2.调用dao层的查询方法,通过用户名查询用户对象
        SqlSession session = GetSqlSession.createSqlSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.queryUserByName(uname);

        //3.判断用户对象是否为空
        if(user ==null)
        {
            messageModel.setCode(0);
            messageModel.setMsg("用户不存在");
            return messageModel;
        }

        //4.比较密码
        if (!upwd.equals(user.getPwd()))
        {
            System.out.println(user.getPwd());
            messageModel.setCode(0);
            messageModel.setMsg("用户密码不正确");
            return messageModel;
        }

        //5.登录成功,将用户信息设置到消息模型中
        messageModel.setObject(user);

        return  messageModel;
    }



        private CalculatorService calculatorService = new CalculatorService();


        public MessageModel saveCalculatorResult(String uname, String result) {
            return calculatorService.saveCalculatorResult(uname, result);

        }

}

GetSqlSession类(工具类)

package com.lzufe.util;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.io.Resources;

import java.io.IOException;
import java.io.InputStream;

public class GetSqlSession {
    public static SqlSession createSqlSession() {

        SqlSessionFactory sqlSessionFactory =null;
        InputStream input = null;
        SqlSession session = null;

        try {
            //获得mybatis的环境配置文件
            String resource = "mybatis-config.xml";
            //以流的方式获取resource(mybatis的环境配置文件)
            input = Resources.getResourceAsStream(resource);
            //创建会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
            //通过工厂得到SqlSession
            session = sqlSessionFactory.openSession();
            return session;
        }catch (IOException e) {
            e.printStackTrace();
            return null;

        }

    }

    public static void main(String[] args) {
        System.out.println(createSqlSession());
    }
}

StringUtil(工具类)

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户登录</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f4f4f4;
            text-align: center;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        form {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        input {
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            box-sizing: border-box;
        }

        #msg {
            font-size: 14px;
            color: red;
            margin-bottom: 10px;
            display: block;
        }

        button {
            background-color: #4caf50;
            color: #fff;
            border: none;
            padding: 10px 20px;
            cursor: pointer;
            border-radius: 4px;
            font-size: 16px;
        }

        button:hover {
            background-color: #45a049;
        }

        button + button {
            margin-left: 10px;
        }
    </style>
</head>
<body>
<form action="login" method="post" id="loginForm">
    <h2>用户登录</h2>
    <label for="uname">姓名:</label>
    <input type="text" name="uname" id="uname" value="${messageModel.object.userName}"><br>
    <label for="upwd">密码:</label>
    <input type="password" name="upwd" id="upwd" value="${messageModel.object.pwd}"><br>
    <span id="msg">${messageModel.msg}</span><br>
    <button type="button" id="loginBtn">登录</button>
    <button type="button" id="regiterBtn" >注册</button>
</form>

<%-- 引入 jQuery 的 js 文件 --%>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
    $("#loginBtn").click(function () {
        // 获取用户姓名和密码
        var uname = $("#uname").val();
        var upwd = $("#upwd").val();

        if (isEmpty(uname)) {
            $("#msg").html("用户姓名不可为空");
            return;
        }

        if (isEmpty(upwd)) {
            $("#msg").html("用户密码不可为空");
            return;
        }

        $("#loginForm").submit();
    });

    /**
     * 判断字符串是否为空,
     * 如果为空,返回 true,否则返回 false
     * @param str
     * @returns {boolean}
     */
    function isEmpty(str) {
        return str == null || str.trim() === "";
    }
</script>
</body>
</html>

index.jsp(计算器)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单计算器</title>
    <style>
        html, body {
            height: 100%;
            margin: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .calculator {
            width: 400px;
            border: 2px solid #3498db;
            text-align: center;
            background-color: #ecf0f1;
            border-radius: 10px;
        }

        .result {
            height: 100px;
            background: #e74c3c;
            line-height: 100px;
            font-size: 48px;
            color: white;
            text-align: right;
            font-weight: bold;
        }

        .buttons {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 5px;
            justify-content: flex-end; /* 将按钮容器右对齐 */
        }

        button {
            height: 80px;
            font-size: 36px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        .operators {
            color: #3498db;
            font-weight: bold;
        }

        .equal {
            background-color: #2ecc71;
            color: white;
            font-weight: bold;
        }

        .Dot {
            font-size: 24px;
            color: #3498db;
            font-weight: bold;
        }

        .number {
            font-size: 20px;
        }
    </style>
<head>
<body>
<div class="calculator">
    <div class="result">0</div>
    <div class="buttons">
        <button class="AC">AC</button>
        <button>+/-</button>
        <button>%</button>
        <button class="operators">/</button>
        <button class="number">7</button>
        <button class="number">8</button>
        <button class="number">9</button>
        <button class="operators">*</button>
        <button class="number">4</button>
        <button class="number">5</button>
        <button class="number">6</button>
        <button class="operators">-</button>
        <button class="number">1</button>
        <button class="number">2</button>
        <button class="number">3</button>
        <button class="operators">+</button>
        <button class="number" style="flex: 2;">0</button>
        <button class="Dot">.</button>
        <button class="equal" style="width: 100%;" id="equalBtn">=</button>
    </div>
</div>
<script>
    // 选择所有数字和运算符按钮
    let numbers = document.querySelectorAll('.number');
    let operators = document.querySelectorAll('.operators');
    let result = document.querySelector('.result');
    let AC = document.querySelector('.AC');
    let Dot = document.querySelector('.Dot');
    let equal = document.querySelector('.equal');
    let isDot = true;
    let displays = "";

    // 遍历数字按钮并添加点击事件处理程序
    numbers.forEach(function (number) {
        number.onclick = function () {
            displays += this.innerHTML;
            result.innerHTML = displays;
        };
    });

    // 遍历运算符按钮并添加点击事件处理程序
    operators.forEach(function (operator) {
        operator.onclick = function () {
            displays += this.innerHTML;
            result.innerHTML = displays;
            isDot = true;
        };
    });

    // AC 按钮点击事件处理程序
    AC.onclick = function () {
        displays = "";
        result.innerHTML = '0';
    };

    // 小数点按钮点击事件处理程序
    Dot.onclick = function () {
        if (displays == "") {
            displays += '0.';
        } else if (isDot) {
            displays += '.';
            isDot = false;
        }
        result.innerHTML = displays;
    };

    equal.onclick = function () {
        // 发送AJAX请求
        let xhr = new XMLHttpRequest();
        xhr.open("POST", "/lp/save", true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

        // 将计算结果作为参数发送
        xhr.send("result=" + encodeURIComponent(displays));

        // 处理服务器响应
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    console.log("Success:", xhr.responseText);
                } else {
                    console.error("Error:", xhr.status, xhr.statusText, xhr.responseText);
                }
            }
        };

        // 更新显示结果
        displays = eval(displays);
        result.innerHTML = displays;
    };


</script>


</script>
</body>

链接数据库时所用到的配置和数据库的设置

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="mysql.properties"/>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>


    <mappers>
        

    <package name="com.lzufe.mapper"/>


    </mappers>




</configuration>

mysql.properties

driver= com.mysql.cj.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/java_test?serverTimezone=UTC&useSSL=false&characterEncoding=UTF-8
username = root
password = 123456