Java 学习笔记·十二 —— Java 案例·网上商城系统

网上商城系统(控制台版)

全部代码 CSDN 下载链接

链接:全部代码 百度网盘链接
提取码:33ao
复制这段内容后打开百度网盘手机App,操作更方便哦

Java 程序开发

java1

java2

需求分析

项目需求

使用控制台作为用户交互界面,实现用户进入购物网站后,从首页到最终下单支付的流程中的一系列动作

分析出要开发的系统的模块,以及每个模块下的功能

本系统操作流程

caozuoliucheng

本系统功能模块

gongneng mokuai

用户角色

普通用户(买家)业务模块

yonghu yewu

管理员用户(商家)业务模块

shangjaiyewu

概要设计

对要开发的系统功能进行设计,包括以下方面:

  • 运行流程
  • 功能分配
  • 接口设计
  • 数据结构
  • 出错处理
  • 日志设计

商城系统的运行流程

图运行流程

一个 web 网站系统大体由三部分构成:客户端(浏览器、手机等移动端)、服务器、数据库

客户端 主要负责用户交互,向用户展示信息和数据,支持用户操作,并根据用户的操作进行动态响应;

服务器端 主要负责业务处理数据,进行业务逻辑的处理,并对客户端响应数据;

数据库 则是用来存储数据的,一般操作分为添、删、改、查四大类

客户端访问服务端,一般称为客户端向服务端发送 “请求”,反过来,服务端向客户端发消息时,我们称为向客户端 “响应”
请求和响应的过程,是用网络编程相关的技术实现的,涉及到很多网络相关的协议和过程

商城系统的功能分配

客户端(Client)

图客户端

  • Client 客户端页面的顶层父类
  • UserClient 用户(登录/注册)操作页面
  • GoodsClient 商品操作页面
  • CartClient 购物车操作页面
  • OrderClient 订单操作页面
服务端

图服务端

  • BaseAction 控制器基类(Controller)
    • UserAction 用户控制器类
    • GoodsAction 商品控制器类
    • CartAction 购物车控制器类
    • OrderAction 订单控制器类
  • Service 服务层
  • DAO 数据访问层(Data Access Object)
数据库
  • TXT 文件
  • JSON 格式存储
  • IO 流读写

商城系统的接口设计

Service 层的接口:可能向多个模块提供服务

图Srvice

  • BaseService 服务层的顶层接口,所有模块的服务层接口的父接口
  • UserService 用户模块的接口,处理所有与用户数据相关的业务逻辑
  • GoodsService 商品模块的接口,处理所有与商品数据相关的业务逻辑
  • CartService 购物车模块的接口,处理所有与购物车数据相关的业务逻辑
  • OrderService 订单模块的接口,处理所有与订单数据相关的业务逻辑
DAO 层的接口:可能向多个服务层提供数据

tu DAO

  • BaseDAO 数据访问层的顶层接口,所有模块的数据访问层接口的父接口
  • UserDAO 用户模块的接口,处理所有与用户相关的数据
  • GoodsDAO 商品模块的接口,处理所有与商品相关的数据
  • CartDAO 购物车模块的接口,处理所有与购物车数据相关的数据
  • O人的人DAO 订单模块的接口,处理所有与订单数据相关的数据
数据库的接口:可能操作不同的数据库

IDataAccess 定义数据的基本操作

日志模块的接口:支持控制台打印和写入本地文件

ISysLog 定义日志的基本操作

商城系统的数据结构设计

实体类:描述现实事物的类

图Entity

  • Entity 实体类,所有子模块的实体类的父类
    • id 数据的唯一标识,String
    • create Time 数据的创建时间,String
    • delete Time 数据的删除时间,String
    • isDel 数据的删除状态,String0 已删除, 1 正常, 默认 1
  • User 用户模块的实体类,用于描述用户的基本信息
  • Goods 商品模块的实体类,用于描述商品的基本信息
  • Cart 购物车模块的实体类,用于描述购物车的基本信息
  • Order 订单模块的实体类,用于描述订单的基本信息
数据文件:和每个实体类是一一对应的
  • User db_user.txt
  • Goods db_goods.txt
  • Cart db_cart.txt
  • Order db_order.txt

商城系统的出错处理和日志设计

出错处理:顶层调用者处理异常,其他抛出

图异常

  • Action 在控制器中捕获异常
  • Service 服务层的所有异常全部抛出
  • DAO 数据访问层的所有异常全部抛出
日志设计:支持控制台打印和写入本地文件
  • ISysLog 日治模块接口
    • info 普通信息
    • warn 警告信息
    • error 错误信息
  • ConsoleLog 实现类,打印日志信息到控制台
  • TxtLog 实现类,打印日志信息到 txt 文件

图小结

开发前的准备工作

项目模块和分包

创建项目 EShop,并添加如下模块
  • user 用户模块
  • log 日志模块
  • goods 商品模块
  • cart 购物车模块
  • order 订单模块
  • client 客户端模块
  • common 公共模块,存放所有顶层父类、接口,公共 bean、工具等
各模块下的包
  • cn.itcast.eshop.user
  • cn.itcast.eshop.log
  • cn.itcast.eshop.goods
  • cn.itcast.eshop.cart
  • cn.itcast.eshop.order
  • cn.itcast.ehsop.client
  • cn.itcast.eshop.common

公共模块的基类和顶层接口

common 模块下的基类和接口
  • cn.itcast.eshop.common.action.BaseAction
  • cn.itcast.eshop.common.service.BaseService
  • cn.itcast.eshop.common.dao.BaseDAO
  • cn.itcast.eshop.common.dao.IDataAccess
  • cn.itcast.eshop.common.entity.Entity
client 模块下的基类
  • cn.itcast.eshop.client.Client

数据交换格式 - JSON 技术简介

JSON 概念

JSON(JavaScript Object Notation) 是一种使用文本存储和表示数据的格式

  • JSON 格式的数据其实就是一个字符串
JSON 格式数据的表现形式
  • {} : 对象
  • [] : 数组
  • 对象的数据表示为键值对
  • 数据之间使用逗号隔开
JSON 支持的数据类型(任意组合)
  • 数值:整数对应 int,浮点数对应 double
  • boolean :布尔型,truefalse
  • 字符串:如 “案例”
  • nullJava 中的 null
  • array : 数组 []
  • object : 对象 {}
{
	"dates":{
		"date":[{
			"id":1,
			"name":"JSON",
			"abb":"JavaScript Object Notation"
			},
			{
			"id":2,
			"name":"XML",
			"abb":"eXtensible Markup Language"
			},
			{
			"id":3,
			"name":"HTML",
			"abb":"HyperText Markup Language"
			}
		]
	}
}
JSONUtil 工具类封装

导入 jar 包,例如,fastjson-1.2.53.jar

// 把对象转为 JSON 格式的字符串
public static String entity2JSON(Object entity)
// 把实体对象列表转换成 JSON 字符串
public static String entityList2JSON(List<?> entityList)
// 将 JSON 字符串转换成指定类型对象
public static <T> T JSON2Entity(String json, Class<T> clazz)
public static Object JSON2Entity(String json, Class<?> clazz)
// 将 JSON 数组转换成指定类型对象列表
public static <T> List<T> JSONArray2List(String json, Class<T> clazz)
public static List<?> JSONArray2List(String json, Class<?> clazz)

用户管理

用户登录模块主要功能

用户登录

输入用户名、密码,并根据用户名、密码获取用户,若该用户存在,则登录成功,否则登录失败

yonghu denglu

用户注册

提示用户输入用户信息和个人基本信息,封装成用户对象,向数据库添加一条数据

用户实体类

username, password, role (NORMAL, ADMIN)

yonghushiti

Person 实体类

name, sex, phone, address

登录功能分析

denglugongneng

客户端登录页面

分析步骤:

  1. 使用控制台提示用户输入用户名、密码
  2. 向服务器发送请求,并接收返回消息字符串,使用 setter 方法把数据传递给 Action;调用 Action 的登录功能
  3. 解析消息字符串,提示用户信息
  4. 页面跳转:使用字符串常量作为跳转标记
    • 成功:返回上一次操作的页面
    • 失败:返回登录页面
      图UserClient
package cn.itcast.eshop.client;

import cn.itcast.eshop.common.entity.Msg;
import cn.itcast.eshop.common.util.JSONUtil;
import cn.itcast.eshop.user.UserAction;

import java.util.Scanner;

/**
 * <用户操作界面>
 *     处理所有用户的后台操作,并返回 JSON 格式的字符串信息
 */
public class UserClient extends Client {

    /**
     * 用户登录操作页面
     *  1. 使用控制台提示用户输入用户名和密码
     *  2. 向服务器发送请求,并接收返回消息字符串
     *      使用 setter 方法把数据传递给 Action
     *      调用 Action 的登录功能
     *  3. 解析消息字符串,提示用户信息
     *  4. 页面跳转,使用字符串常量作为跳转标记
     *      成功,返回上一次操作的页面
     *      失败,返回登录页面
     * @return
     * */
    public String showLogin() {
        System.out.println("========欢迎登录========");
        // 1. 使用控制台提示用户输入用户名和密码
        Scanner sc = new Scanner(System.in);
        System.out.println("Please input UserName: ");
        String username = sc.nextLine();
        System.out.println("Please input Password: ");
        String password = sc.nextLine();

        // 2. 向服务器发送请求,并接收返回消息字符串
        UserAction userAction = new UserAction();
        // 使用 setter 方法把数据传递给 Action
        userAction.setUsername(username);
        userAction.setPassword(password);
        // 调用 Action 的登录功能
        String result = userAction.login();

        // 3. 解析消息字符串,提示用户信息
        Msg msg = JSONUtil.JSON2Entity(result, Msg.class);
        if(msg.getType().equals(Msg.SUCCESS)) {
            // 登录成功
            System.out.println("登录成功");
            // 4 成功,返回上一次操作的页面
            return HISTORY;
        } else {
            System.out.println("登录失败");
            // 4 失败,返回登录页面
            return LOGIN;
        }
    }
}
服务端登录 - Controller 层的实现

分析步骤:

  1. 封装数据到 User 对象
  2. 调用 UserService 处理逻辑
    User login(User user) throws Exception;
  3. 异常处理
  4. 根据服务层返回结果生成消息
    消息实体类 Msg
  5. 记录日志(待开发)
  6. 响应消息到客户端

controller

    /**
     * 用户登录功能
     *  1. 封装数据到 user 对象
     *  2. 调用 UserService 处理逻辑,并抛出异常
     *  3. 异常处理
     *  4. 根据服务层返回结果生成消息
     *  5. 记录日志(待开发)
     *  6. 响应消息到客户端
     * @return
     * */
    public String login() {
        Msg msg = new Msg();
        try {
            // 1. 封装数据到 user 对象
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            // 2. 调用 UserService 处理逻辑,并抛出异常
            UserService userService = new UserServiceImpl();
            user = userService.login(user);
            // 3. 异常处理
            // 4. 根据服务层返回结果生成消息
            if (user != null) {
                msg.setType(Msg.SUCCESS);  // 登录成功
                msg.setMsg("登录成功");
            } else {
                msg.setType(Msg.FAIL);  // 登录成功
                msg.setMsg("用户名或者密码不正确");
            }
            // 5. 记录日志(待开发)
            // 6. 响应消息到客户端
            return JSONUtil.entity2JSON(msg);
        } catch (Exception e) {
            e.printStackTrace();
            msg.setType(Msg.FAIL);  // 登录成功
            msg.setMsg("登录失败,捕获异常");
            return JSONUtil.entity2JSON(msg);
        }
    }
服务端登录 - Service 层的实现

分析步骤:

  1. 调用 UserDAO 获取用户列表数据
    List getEntityList() throws Exception;
  2. 遍历用户列表,逐个与给定用户对象的用户名、密码进行匹配
  3. 匹配成功则返回该用户对象,失败则返回 null

service

注意事项:
实际环境中,使用操作数据库的语言 SQL 将用户名、密码作为条件进行查询

服务端登录 - DAO 层的实现

分析步骤:

  1. 创建 IDataAccess 子类 TXTDataAccess 的对象
    IDataAccess dataAccess = new TXTDataAccess();
  2. 调用该对象的方法获取所有用户数据并返回
    List userList = dataAccess.getList(User.class);

getList() 方法定义分析:

  • 作用:获取全部用户数据
  • 返回值:List 用户对象列表
  • 参数:Class (JSON 转换需要)

getList() 方法实现步骤:

  1. 根据实体类的字节码文件对象获取类名
  2. 根据类名获取用户数据文件名
  3. 合成数据文件路径
  4. 使用文件操作工具类读取文件中的字符串数据
  5. 将字符串数据转换成 List 对象并返回

日志管理

日志是记录系统操作或者消息的数据文件,具有处理历史数据、诊断问题等作用

  • 常见的日志级别(level

    • info 普通信息
    • warn 警告信息
    • error 错误信息
  • 实体类 Log

    • String msg :日志内容
    • String level :日志级别
    • String time : 日志发生时间

ISysLog 接口定义

级别常量:

public static final String INFO = "INFO";
public static final String WARN = "WARN";
public static final String ERROR = "ERROR";

方法定义:

void info(String msg)
void warn(String msg)
void error(String msg)

日志操作步骤:

  1. 封装日志对象
  2. 打印日志数据到控制台

商品管理

商城首页

shangpinshouye

GoodsClient 步骤分析:

  1. 向后台发送请求,获取商品数据
  2. 解析响应消息字符串
  3. 展示商品列表

GoodsAction 步骤分析:

  1. 获取所有商品的对象列表
  2. 将商品对象转换成字符串并返回
  3. 异常处理
  4. 记录日志
  5. 响应消息到客户端

公共用户操作:

String userOperate(String msg, String... oprs)

msg : 提示信息,如“请根据序号…”
oprs : 用户操作,可变参数,本质是一个数组
返回值: 用户录入的操作

查看商品详情

思路:
商品列表页→输入商品编号→根据编号从 Map 中获取商品对象→展示商品详细信息

购物车管理

添加购物车

思路分析:
在实际开发中,购物车的实现大致有两种情况:

  • 第一,以 Map 集合作为购物车对象,将相关数据临时存储在系统中(内存)
  • 第二,将用户添加到购物车中的商品,以购物车实体类对象的形式存储到数据库中

本系统实现第一种方式

购物车 Map 集合:
key : 商品 ID
value : 商品数量

我的购物车

展示购物车中商品列表,包含每种商品的数量

订单管理

生成订单

生成订单的过程,实际就是封装订单实体类的过程

生成订单前,要验证是否登录

将订单基本信息如收货人姓名、收货地址、联系方式等封装到订单对象中,根据购物车中商品列表和数量计算出订单总金额。

生成订单后展示订单基本信息

去支付,订单详情

去支付,根据订单总金额,提示用户输入对应数值,输入数值大于等于总金额则支付成功,否则则支付失败,提示余额不足

订单详情,打印订单信息和订单状态

  • 10
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值