课程设计报告

 

        201610411221101610411203           

                  吕晶、曹宣勇              

                 计科2班                   

                 网上书店                   

授课老师                 袁飞                    

 

 

 

 

 

 

 

目录

1章 概述 1

1.1 课程设计的核心任务 1

1.2 课程设计工作进程 1

2章 需求分析 2

2.1 用户需求 2

2.1.1 业务需求 2

2.1.2 商业需求 2

2.1.3 特殊需求 2

2.2 可行性分析 2

2.2.1 技术可行性 2

2.2.2 经济可行性 2

2.3 系统功能 3

3章 概要设计 4

3.1 系统设计思想 4

3.2 系统(或网络)总体结构 4

3.3 数据库设计 4

4章 详细设计 5

5章 课程设计总结 6

 

 

 

 

 

 

 

 

 

 

 

 

 

第1章 概述

1.1 课程设计的核心任务

(1)满足网站管理员对其小型书店能够查看书的库存、上架和下架书籍、管理客户订单、随时能更      改书籍信息的要求。

(2)网站中书籍购买者能够注册登陆账号、随意选购书籍、将书籍添加进购物车、购买购物车中选  中的商品、修改订单等。

(3)网站简介,界面布局合理,资源利用率高

 

 

1.2 课程设计工作进程

1.2.1 需求分析阶段:

415日——58日完成对项目的需求分析、可行性分析、经济分析、系统模型设计和持久层设计,并写入需求分析文档中。

1.2.2 开发阶段:

58日——530日进行代码的编写,实现项目的基本功能。

1.2.3 测试和部署阶段:

530日——618日将项目完成并部署到服务器上,进行测试;完成设计文档。

 

 

 

 

 

第2章 
需求分析

2.1 用户需求

2.1.1 业务需求

在实际的销售运营过程中,采购商或顾客只能通过上门咨询、电话沟通等方式进行各种产品信息的获取,而且时间与物理的局限性影响了图书的销售,并且在无形中提高了产品的销售成本。本系统可以改变这种现状,以少量的时间和资金建立企业商务网络,以此来使企业和消费者之间的经济活动变得更加灵活、主动。

2.1.2 特殊需求

管理员希望能够对书籍的库存有较方便的管理,在线下售出书也可以减库存。

2.2 可行性分析

2.2.1 技术可行性

本系统采用B/S架构、MVC设计模式,根据Java EE 标准开发,后端的数据库采用MySQLMySQL小巧高效的特点足以满足系统需求,通过JDBC驱动程序和数据库进行无缝连接。前端采用可以跨平台的HtmlCssJavaScriptAjax等技术进行开发。本系统采用intelliJ IDEA集成开发环境、Tomcat服务器进行程序开发和发布。本系统采用的技术和开发环境在实际的开发中应用非常广泛,充分说明本系统在技术方面可行。

2.2.2 经济可行性

本系统可以运行于现在市场上出售的各种个人电脑,系统成本主要集中在系统的开发上。当系统投入运行后,可以实现在网上销售图书及管理库存功能。所带来的效益远远大于系统软件的开发成本。在经济上是可行的。

2.3 系统功能

网上书店系统主要包括前台网站和后台管理两个部分。前台网站实现图书的动态展示、购物车管理、客户信息注册登陆管理、订单处理等功能模块,后台管理系统主要实现管理员对前台网站进行日常管理和信息发布,即对用户、图书、订单等的管理功能。经过综合分析,确定了网上书店系统主要包括以下功能。

2.3.1 用户登陆注册

用户需要有个账号来储存自己的个人信息、购物信息等。

2.3.2 浏览与搜索图书

用户在购买书籍前需要浏览上架的图书来进行选择。

2.3.3 购物车管理

用户对自己的购物车可以进行对书籍数量的添加和减少、移除等操作。

2.3.4 提交订单和订单管理

用户对挑选好要购买的商品可进行购买,购买后可查询自己的购买信息等。

2.3.5 后台管理

书店的管理人员要能处理用户提交的订单请求、能管理书店所发布的图书等。

第3章 概要设计

3.1 系统设计模式

3.1.1 用例图(Use case diagram):

 

3.2 系统总体结构

3.2.1 系统架构图:

 

3.3 持久层设计

3.3.1 数据库总体E-R图:

 

3.3.2 实体E-R图:

1) 用户实体的E-R图,如图3.3.2.1所示:

 

 

3.3.2.1 用户实体的E-R图

 

2) 订单实体的E-R图,如图3.3.2.2所示:

 

3.3.2.2 订单实体的E-R

 

3) 订单条目实体的E-R图,如图3.3.2.3所示:

 

3.3.2.3 订单条目实体的E-R

 

4) 图书实体的E-R图,如图3.3.2.4所示:

 

3.3.2.4 图书实体的E-R

 

5) 类别实体的E-R图,如图3.3.2.5所示:

 

3.3.2.5 类别实体的E-R

 

6) 购物车实体的E-R图,如图3.3.2.6所示:

 

3.3.2.6 购物车实体的E-R

 

 

 

 

 

 

 

第4章 
详细设计与系统实现

4.1 业务逻辑设计与实现

4.1.1 业务逻辑的设计:

 

4.1.2 业务逻辑层的实现:

用户相关操作、图书管理、订单处理以及购物车相关操作:

 

 

4.2 表现层设计与实现

4.2.1 首页:

 

 

4.2.2 管理员登陆后显示选项:

 

4.2.3 管理员工作台界面:

 

4.2.4 管理员添加图书界面:

 

4.2.5 普通用户登陆后显示选项:

 

4.2.6 购物车界面:

 

4.2.7 订单界面:

 

4.3 项目难点及解决方案

4.3.1 添加图书时,一个图书信息既有图片文件又有普通表单项,此时普通表单不能满足要求,后台对含有文件输入的表单也要特殊处理。

解决:设置form表单中的enctype属性multipart/form-data,在后台对表单的文件项和普通项分别处理

4.4 典型代码片段与设计过程

4.4.1 添加图书(处理enctype属性为multipart/form-data的表单):

 

@WebServlet("/AddBookServlet")
public class AddBookServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //将表单提交的数据放在Book类中
        Book b = new Book();

        //判断前端form表单是否为enctype="multipart/form-data"属性
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        //如果前端传过来的表单不是enctype="multipart/form-data"属性
        if(!isMultipart){
            throw new RuntimeException("该请求不支持文件上传");
        }

        //创建一个DisFileItemFactory对象
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //创建ServletFileUpload的对象,该对象是上传的核心组件
        ServletFileUpload sfu = new ServletFileUpload(factory);

        //使用解析器解析上传的表单数据,每个FileItem对应一个表单项
        List<FileItem> fileItemList = null;
        try {
            fileItemList = sfu.parseRequest(request);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        //遍历表单项集合
        for (FileItem item : fileItemList) {
            if (item.isFormField()){
                //普通表单项
                String fieldName = item.getFieldName();//字段名
                String fieldValue = item.getString("utf-8");//字段值

                if(fieldName.equals("bookname")){
                    b.setBookname(fieldValue);
                }else if(fieldName.equals("inventory")){
                    if(fieldValue != null && !fieldValue.equals("")){
                        b.setInventory(Integer.parseInt(fieldValue));
                    }
                }else if(fieldName.equals("depict")){
                    b.setDepict(fieldValue);
                }else if(fieldName.equals("price")){
                    if(fieldValue != null && !fieldValue.equals("")){
                        b.setPrice(new BigDecimal(fieldValue));
                    }
                }else  if(fieldName.equals("sellingPrice")){
                    if(fieldValue != null && !fieldValue.equals("")){
                        b.setSellingPrice(new BigDecimal(fieldValue));
                    }
                }else  if(fieldName.equals("recommend")){
                    if(fieldValue != null && !fieldValue.equals("")){
                        b.setRecommend(Integer.parseInt(fieldValue));
                    }
                }else  if(fieldValue != null && !fieldValue.equals("")){
                    if(fieldName.equals("onSale")){
                        b.setOnSale(Integer.parseInt(fieldValue));
                    }
                }
            }else{
                //不是普通的表单项,即是上传的是文件

                //获取文件保存路径,判断是否存在该目录如果不存在创建
                String path = path = this.getServletContext().getRealPath("/img");
                File file0 = new File(path);
                //判断文件是否存在,不存在就创建
                if (!file0.exists() && !file0.isDirectory()) {
                    file0.mkdirs();
                }

                //获取文件名称
                String fileName = item.getName();
                fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                fileName = UUID.randomUUID() + "_" + fileName;
                if (fileName.isEmpty()) {
                    //如果文件名为空
                    continue;
                }
                //获取输入流
                InputStream is = item.getInputStream();
                //创建输出流
                File file = new File(path, fileName);
                FileOutputStream fos = new FileOutputStream(file);

                byte[] bytes = new byte[1024];
                int len = -1;
                while((len = is.read(bytes)) != -1){
                    fos.write(bytes, 0, len);
                }
                String imgAdd = "/img/" + fileName;
                System.out.println(imgAdd);
                b.setImgAddress(imgAdd);
            }
        }

        if(b.getBookname() == null || b.getBookname().equals("")){
            response.getWriter().write("书名不能为空!1秒后重新添加");
            response.setHeader("refresh", "1;url=" + request.getContextPath()
                    + "/addBook.html");
        } else {
            //调用业务逻辑
            BookService bs = new BookServiceImpl();
            try {
                //执行添加操作
                bs.addBook(b);
                //分发转向
                String path="/WEB-INF/admin/backstage.html";
                request.getRequestDispatcher(path).forward(request, response);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

 

4.4.2 数据交互(根据请求参数的不同向html返回不同的Json格式数据):

 

@WebServlet("/NewsServlet")
public class NewsServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String id = request.getParameter("id");
        HttpSession session = request.getSession();

        if(id.equals("reg")){//返回用户名是否为空或重复
            String username = request.getParameter("username");
            String result = "";
            //将表单提交的数据放在User类中
            User u = new User();
            u.setUsername(username);
            //调用业务逻辑
            UserService us = new UserServiceImpl();
            try {
                result = us.judgeUsername(u);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if(result.equals("null")){
                out.print("null");
            }else {
                    if(result.equals("true")){   //用户名重复
                        out.print(true);
                    }else if(result.equals("false")){
                        //用户名不重复时
                        out.print(false);
                    }
            }
        }else if(id.equals("book")){//返回用户信息和findOnSaleBooks的集合
            BookService bs = new BookServiceImpl();
            try {
                List bookList = bs.findOnSaleBooks();
                Object userS = session.getAttribute("user");
                //把集合中的数据转换为字符串返回到页面
                String newsJ = "";

                List news = new ArrayList();
                news.add(userS);

                for(int i = 0;i < bookList.size(); i++) {
                    news.add(bookList.get(i));
                }

                //使用json格式进行数据传输
                newsJ = JSONArray.toJSONString(news);
                //将数据响应到客户端
                response.getWriter().write(newsJ);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if(id.equals("shop")){ //返回用户和购物车信息
            User user = (User)session.getAttribute("user");
            List<ShopCart> shopCartList = new ArrayList<>();
            if(user != null){
                //用户登陆
                //获取该用户购物车List
                ShopCartService shopCartService = new ShopCartServiceImpl();
                try {
                    shopCartList = shopCartService.findByUserId(String.valueOf(user.getId()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //获取用户session
                Object userS = session.getAttribute("user");
                //将session和购物车打包
                List news = new ArrayList();
                news.add(userS);
                if(shopCartList!=null){
                    for(int i = 0;i < shopCartList.size(); i++) {
                        news.add(shopCartList.get(i));
                    }
                }

                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                //将数据响应到客户端
                response.getWriter().write(newsJ);


            }else if(user == null){
                //未登录
                //获取用户session
                Object userS = session.getAttribute("user");
                List news = new ArrayList();
                news.add(userS);
                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                //将数据响应到客户端
                response.getWriter().write(newsJ);
            }

        }else if(id.equals("myOrder")){ //返回用户和订单和订单详情
            User user = (User)session.getAttribute("user");

            if(user != null){
                List news = new ArrayList();
                news.add(user);
                OrderService orderService = new OrderServiceImpl();
                //获取用户订单
                List<Order> orders = orderService.findOrdersByUserId(user.getId());
                System.out.println(orders);
                //获取迭代器遍历List
                Iterator iter = orders.iterator();
                while(iter.hasNext()) {
                    //向下转型
                    Order order = (Order) iter.next();
                    news.add(order);
                    //获取订单详情
                    List<OrderItem> orderItems = orderService.findOrderItems(order.getId());
                    for(int i = 0;i < orderItems.size(); i++) {
                        news.add(orderItems.get(i));
                    }
                    news.add("stop");

                }
                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                System.out.println(newsJ);
                //将数据响应到客户端
                response.getWriter().write(newsJ);

            }else{
                //未登录
                //获取用户session
                Object userS = session.getAttribute("user");
                List news = new ArrayList();
                news.add(userS);
                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                //将数据响应到客户端
                response.getWriter().write(newsJ);
            }

        }else if(id.equals("allOrder")){//返回用户和所有订单
            User user = (User)session.getAttribute("user");

            if(user != null){
                List news = new ArrayList();
                news.add(user);
                OrderService orderService = new OrderServiceImpl();
                //获取所有订单
                List<Order> orders = orderService.findAllOrders();
                //获取迭代器遍历List
                Iterator iter = orders.iterator();
                while(iter.hasNext()) {
                    //向下转型
                    Order order = (Order) iter.next();
                    news.add(order);
                    //获取订单详情
                    List<OrderItem> orderItems = orderService.findOrderItems(order.getId());
                    for(int i = 0;i < orderItems.size(); i++) {
                        news.add(orderItems.get(i));
                    }
                    news.add("stop");

                }
                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                System.out.println(newsJ);
                //将数据响应到客户端
                response.getWriter().write(newsJ);

            }else{
                //未登录
                //获取用户session
                Object userS = session.getAttribute("user");
                List news = new ArrayList();
                news.add(userS);
                //使用json格式进行数据传输
                String newsJ = "";
                newsJ = JSONArray.toJSONString(news);
                //将数据响应到客户端
                response.getWriter().write(newsJ);
            }
        }
    }
}

 

 

第5章 
测试与部署

5.1 系统测试

5.1.1 Pc端测试:

用电脑对目标网站进行访问,对网站的功能模块进行逐一的测试,并在测试中发现书店的购物车为空时点击购买会出现页面错误,经过修改代码修复了这个bug

5.1.2 移动端测试:

使用手机对网站进行访问并经过,注册、登陆、添加购物车、查看订单逐步对网站进行了测试,未发现漏洞。

 

 

 

5.2 系统部署

服务器镜像:windows server 2016

  • ftp站点用来传输文件
  • 安装MySQL
  • 安装Tomcat
  • maven打包项目
  • 部署项目到服务器Tomcat

第6章 课程设计总结

6.1 系统基本软件度量数据

1. LOC(Line Of Code)

LOC2776
CLOC (注释行数): 345
BLOC(空白行数): 482

Requirement: >600

 

  1. Function Point = UFC * VAF

 

Factor

count

Weight
simple Common Complex

Note

Input

5

16%

 

Output

5

16%

 

Transaction

9

60%

 

Domain model

5

16%

 

Query

20

38%

 

file

46

100%

 

Interface

8

38%

 

 

Requirement: >=3 Function Points

 

6.2 课程设计项目的收获与展望

通过这次课程设计,我更加深入地了解了Java SEJava EE的许多功能与原理,提高了实践能力。在课程设计过程中,我遇到了很多问题,如在上传文件的表单的处理、Json传输数据的封装等,最终在小组的共同努力下,这些问题都一一得到圆满解决,系统还有以下部分有待完善:

(1) 数据库安全性还有待加强。

(2) 功能还可以更完善,如可以增加顾客对自己信息的修改权限,例如联系方式、住址等的更改。

(3) 代码的优化也还有进步空间,许多方便快捷的第三方框架也还未使用。

这次课程设计使我们更加熟悉的掌握了Java语言和SQL语句的运用,帮助我们熟悉了更多IDEAMysal8.0的功能,提高了我们的动手能力,在实践中能够及时的发现问题、解决问题,学到了许多解决实际问题的宝贵经验.同时也挖掘出了我们潜在的能力,使我们对自己更有自信,对编程也更有兴趣。

最后,衷心感谢袁老师的悉心指导,感谢这次课程设计的机会,使我们得到了很好的锻炼,学无止境,我们现在了解的东西还很少,还不能很好地掌握自己的专业知识,我们要谦虚的积极认真学习,不断的增强自身的能力,提高个人素质,向一个真正的IT人士发展。

posted @ 2019-06-19 23:47  夏前波大帅B  阅读(577)  评论(0编辑  收藏  举报