收银台系统设计(B/S架构)

收银台系统设计(B/S架构)


核心需求:

  • 上架商品
  • 浏览商品
  • 更新商品信息
  • 购买商品
  • 浏览订单

重点知识:Servlet使用,Java类集使用,前端知识运用,数据库的库表设计,JDBC编程。

Ⅰ 数据库的库表设计

一个订单对应多个商品,一个商品也对应多个订单。此时在将E-R图转化为关系模型时,需要引入中间表(订单项表)。在订单项表中,必须含有的属性有商品号和订单号。
在这里插入图片描述
注意:
一个订单可能有多个货物,一个货物可能在多个订单里,订单和货物是多对多的关系。所以需要创建一个中间表,即关系表。这个关系表按理说只需要包括订单号和商品id就可以了,知道这两项,就可以通过sql查询语句进行查询具体的订单信息了。但是考虑到实际情况,货物可能会下架,从而导致查询不到,所以为了保存完整的订单信息,我们在关系表中不仅存入了订单号和商品id,还将所有的商品信息保存了下来,这样即使某商品下架了,我们也可以在关系表中,查询到具体的订单信息,保证了订单不丢失。

(0)创建数据库

-- 数据库
drop database if exists `cash`;
create database if not exists `cash` character set utf8;

-- 使用数据库
use `cash`;

(1) 用户

drop table if exists `account`;
create table if not exists `account`
(
    id             int primary key auto_increment comment '帐号编号',
    username       varchar(12)   not null comment '帐号',
    password       varchar(128)  not null comment '密码'
);

(2)商品

drop table if exists `goods`;
create table if not exists `goods`
(
    id        int primary key auto_increment comment '商品编号',
    name      varchar(128)              not null comment '商品名称',
    introduce varchar(256) default '暂无' not null comment '商品简介',
    stock     int                       not null comment '商品库存',
    unit      varchar(12)               not null comment '库存单位',
    price     int                       not null comment '商品价格,单位:分',
    discount  int          default 100  not null comment '商品折扣,[0,100]'
);

(3)订单

drop table if exists `order`;
create table if not exists `order`
(
    id            varchar(32) primary key comment '订单编号',
    account_id    int         not null comment '帐号编号',
    account_name  varchar(12) not null comment '帐号',
    create_time   datetime    not null comment '创建时间',
    finish_time   datetime default null comment '完成时间',
    actual_amount int         not null comment '实际金额,单位:分',
    total_money   int         not null comment '总金额,单位:分',
    order_status  int         not null comment '支付状态 1 待支付 2 完成'
);

(4)订单项(关系表)

drop table if exists `order_item`;
create table if not exists `order_item`
(
    id              int primary key auto_increment comment '订单条目编号',
    order_id        varchar(32)               not null comment '订单编号',
    goods_id        int                       not null comment '商品编号',
    goods_name      varchar(128)              not null comment '商品名称',
    goods_introduce varchar(256) default '暂无' not null comment '商品简介',
    goods_num       int                       not null comment '商品数量',
    goods_unit      varchar(12)               not null comment '库存单位',
    goods_price     int                       not null comment '商品价格,单位:分',
    goods_discount  int          default 100  not null comment '商品折扣,[0,100]'
);

注意

  • 为了避免价格会出现小数,在存入数据库时,需要转化为整数,这样能有效避免精度的丢失,取出时再转换为小数。
  • 在实体类中用枚举类型记录订单状态。
Ⅱ Maven项目搭建
(1)项目整体框架

在这里插入图片描述
客户端和服务器通信方式——Servlet:
Servlet 是服务器端程序,主要用来交互式地浏览和修改数据,生成动态web内容。web服务器接收到客户端的Servlet 请求后,如果检查到已经装载并创建了该Servlet的实例对象,则会创建一个用于封装HTTP请求消息的HttpServletRequest 对象和一个代表Http响应消息的HttpServletResponse 对象,然后调用Servlet的service()方法,将请求和响应对象作为参数传递进去,这样客户端通过HttpServletRequest 对象将请求发送给服务器,服务
器通过HttpServletResponse 对象将响应传递给客户端,达到通信的目的。

Maven项目的pom.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.glp</groupId>
    <artifactId>myCashier</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 打包方式是 war 包,一种用于 web 应用的包,原理类似 jar 包 -->
    <packaging>war</packaging>

    <!-- 指定属性信息 -->
    <properties>
        <encoding>UTF-8</encoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- 加入 servlet 依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <!-- servlet 版本和 tomcat 版本有对应关系,切记 -->
            <version>3.1.0</version>
            <!-- 这个意思是我们只在开发阶段需要这个依赖,部署到 tomcat 上时就不需要了 -->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.11</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.9</version>
        </dependency>
    </dependencies>

    <build>
        <!-- 指定最终 war 包的名称 -->
        <finalName>hello-bit-idea</finalName>

        <!-- 明确指定一些插件的版本,以免受到 maven 版本的影响 -->
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.6.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

关于web.xml生成,编码设置,数据库连接设置,tomcat启动项设置等,请
参考博客:Maven项目的IDEA配置

Ⅲ 登录注册

在这里插入图片描述

(1)注册:
在这里插入图片描述

(2)登录:
在这里插入图片描述
登录成功后将用户信息写入session中。

注意:
从前端读取的参数都是字符串。

Ⅳ 商品上架

主页:
在这里插入图片描述
商品上架
在这里插入图片描述

在这里插入图片描述

Ⅴ商品浏览

在这里插入图片描述

只要进入浏览商品页面就会触发ajax
在这里插入图片描述

使用goodsList保存goods信息。

while(rs.next()){
    Goods goods = new Goods();
    goods.setId(rs.getInt("id"));
    goods.setName(rs.getString("name"));
    goods.setIntroduce(rs.getString("introduce"));
    goods.setStock(rs.getInt("stock"));
    goods.setUnit(rs.getString("unit"));
    goods.setPrice(rs.getInt("price"));
    goods.setDiscount(rs.getInt("discount"));
    goodsList.add(goods);
}
System.out.println("列表:");
System.out.println(goodsList);

ObjectMapper objectMapper = new ObjectMapper();
//将goodsList写到流writer中
objectMapper.writeValue(writer,goodsList);
//转为字符串,推到前端
writer.write(writer.toString());

注意:
我们存入数据库时的price是以整数存入的,当我们使用good中的price时,默认调用的是getPrice(),返回的是整数,所以我们需要重写getPrice()以返回商品的真实价格。

public double getPrice(){
    return price*1.0/100;
}
public int getPriceInt(){
    return price;
}

前端js部分:

<script>
    //进入此页面 该函数立即执行
    $(function () {
        $.ajax({
            url:"goods",
            type:"get",
            dataType:"json",
            success:function (data) {
                console.log(data);
                var s = "";
                for(var i=0;i<data.length;i++){
                    s+="<tr>";
                    s+="<td>"+data[i].id+"</td>";
                    s+="<td>"+data[i].name+"</td>";
                    s+="<td>"+data[i]["introduce"]+"</td>";
                    s+="<td>"+data[i].stock+"</td>";
                    s+="<td>"+data[i].unit+"</td>";
                    s+="<td>"+(data[i].price)+"</td>";
                    s+="<td>"+data[i].discount+"</td>";
                    s+="<td class =\"delete\"><button οnclick=\"deleteInfo('"+data[i].id +" ')\" class=\"icon-trash bigger-120\"></button>下架</button></td>";
                    s+="</tr>";
                }
                $("#tbRecord>tbody").html(s);
            }
        })

    });

</script>

将查询到的商品信息,以json的形式推给前端。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(writer,goodsList);
writer.write(writer.toString());
Ⅵ 商品下架

在这里插入图片描述
前端js:

浏览商品页面的下架按钮。
在这里插入图片描述
当点击下架按钮时,会将商品id作为参数传给deleteInfo函数。

s+="<td class =\"delete\"><button οnclick=\"deleteInfo('"+data[i].id +" ')\" class=\"icon-trash bigger-120\"></button>下架</button></td>";
s+="</tr>";

deleteInfo函数中,obj为浏览页面按钮中对应的商品id.

    function deleteInfo(obj) {
        console.log(obj);
        if(obj!=null){
            $.ajax({
                url:"delGoods",
                type:"post",
                data:{"id":obj},
                success:function () {
                    alert("删除成功");
                    window.location.reload();
                },
                error:function () {
                    alert("请求失败");
                },
                dataType:"text"
            });
        }
    }
Ⅶ 更新商品

在这里插入图片描述

在这里插入图片描述
提交表单之后,需要先通过id进行查询该商品是否存在,存在更新数据库,不存在更新失败。

Ⅷ 购物

这里直接采用手动输入的方式进行处理,真正的购物操作需要扫码机来采集信息。
在这里插入图片描述

在这里插入图片描述
因为购买商品采用的是1-3,2-9,id加数量的形式,所以goods类中需再加入一个属性buyGoodsNum.

解析字符串,额外记录商品的数目,都封装到good中,然后将所有的good都加入到goodList中,用于后续得操作。

1 创建订单

id、account_id、account_name、create_time、finish_time、actual_amoun、total_money、 order_status。
订单分为支付前和支付后两个状态。

(1)支付前,需要获取id、account_id、account_name、create_time、actual_amoun、total_money,而 order_status、finish_time的更新需要等到支付完成后再进行封装。

需要注意:
1)通过时间戳生成订单id

order.setId(String.valueOf(System.currentTimeMillis()));

2)通过session获取账户信息(登录的时候,已经将session写入到Session中了)

HttpSession session =req.getSession();
Account account = (Account) session.getAttribute("user");
order.setAccount_id(account.getId());
order.setAccount_name(account.getUsername());

3)设置创建时间

		Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss"
        );
        String createTime = format.format(date);
        order.setCreate_time(createTime);

4)计算总金额和实际花费,并顺便封装关系表类(订单项类)
订单项类(OrderItem):id 、order_id、goods_id、goods_name、goods_introduce、goods_num、goods_unit、goods_price、goods_discount。

打印订单信息,需要打印订单和商品信息,多个商品信息(订单项类:一个订单号对应一个商品)需要在Order类中单独定义一个List保存订单项public List<OrderItem> orderItemList = new ArrayList<>();

		int totalMoney =0;
        int actualMoney =0;
        for (Goods goods:goodsList){
            OrderItem orderItem = new OrderItem();
            orderItem.setOrder_id(order.getId());
            orderItem.setGoods_id(goods.getId());
            orderItem.setGoods_discount(goods.getDiscount());
            orderItem.setGoods_name(goods.getName());
            orderItem.setGoods_introduce(goods.getIntroduce());
            orderItem.setGoods_unit(goods.getUnit());
            orderItem.setGoods_num(goods.getBuyGoodsNum());
            orderItem.setGoods_price(goods.getPriceInt());
            order.orderItemList.add(orderItem);

            int currentMoney = goods.getBuyGoodsNum()*goods.getPriceInt();
            totalMoney +=currentMoney;  //totalMoney取整了,用于存入数据库
            actualMoney += currentMoney*goods.getDiscount()/100;//除100是折扣,
        }
        order.setTotal_money(totalMoney);
        order.setActual_amount(actualMoney);
        order.setOrder_status(OrderStatus.PLAYING);

至此,未支付的订单信息更新完成。

将订单和商品信息写入到session中用于后序数据库的写入:

//将订单写到session中
HttpSession session2 = req.getSession();
session2.setAttribute("order",order);

//将goods存入Session中
HttpSession session3 = req.getSession();
session3.setAttribute("goodsList",goodsList);

5)打印未支付订单信息:
在这里插入图片描述

//如果是跳转到另一个网页的话,对应的数据不好拿到,
//所以在这里直接进行打印网页
//通过响应体对前端传入数据。
resp.getWriter().println("<html>");
resp.getWriter().println("<p>"+"【用户名称】:"+order.getAccount_name()+"</p>");
resp.getWriter().println("<p>"+"【订单编号】:"+order.getId()+"</p>");
resp.getWriter().println("<p>"+"【订单状态】:"+order.getOrder_statusDesc()+"</p>");
resp.getWriter().println("<p>"+"【创建时间】:"+order.getCreate_time()+"</p>");

resp.getWriter().println("<p>"+"编号  "+"名称   "+"数量  "+"单位  "+"单价(元)   "+"</p>");
resp.getWriter().println("<ol>");
for (OrderItem orderItem  : order.orderItemList) {
    resp.getWriter().println("<li>" + orderItem.getGoods_name() +" " + orderItem.getGoods_num()+ " "+
            orderItem.getGoods_unit()+" " + orderItem.getGoods_price()+"</li>");
}
resp.getWriter().println("</ol>");
resp.getWriter().println("<p>"+"【总金额】:"+order.getTotal_money() +"</p>");
resp.getWriter().println("<p>"+"【优惠金额】:"+order.getDiscount() +"</p>");
resp.getWriter().println("<p>"+"【应支付金额】:"+order.getActual_amount() +"</p>");
//这个标签<a href = > 只会以get方式请求,所以buyGoodsServlet的 doGet方法
resp.getWriter().println("<a href=\"buyGoodsServlet\">确认</a>");
//resp.getWriter().println("<form action=\"buyGoodsServlet\" method=\"post\"><button type=\"submit\">确认</button></form>");
resp.getWriter().println("<a href= \"index.html\">取消</a>");
resp.getWriter().println("</html>");

注意:

  • 同样,获取总金额和优惠金额时,需要重写一下getter;
public double getTotal_money(){
    return total_money*1.0/100;
}
public int getTotal_moneyInt(){
    return total_money;
}

public double getActual_amount(){
    return total_money*1.0/100;
}
public int getActual_amountInt(){
    return total_money;
}

public double getDiscount(){
    return (this.total_money-this.actual_amount)*1.00/100;
}
  • 拿到订单状态的描述“待支付”字样

枚举类:

package comment;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public enum OrderStatus {
    PLAYING(1,"待支付"),OK(2,"支付完成");
    private int flg;
    private String desc;

    OrderStatus(int flg, String desc) {
        this.flg = flg;
        this.desc = desc;
    }
}
  • 重写Getter方法,在订单中使用order_status.getDesc()获取“待支付”字样。
@Data
public class Order {

private OrderStatus order_status;
//保存订单项
public List<OrderItem> orderItemList = new ArrayList<>();

public String getOrder_status(){
    return order_status.getDesc();
}
public OrderStatus getOrder_statusDesc(){
    return order_status;
}
}

订单状态获取:

resp.getWriter().println("<p>"+"【订单状态】:"+order.getOrder_status()+"</p>");
  • 通过<a href = > 标签确认支付,只会以get方式发起请求。
resp.getWriter().println("<a href=\"buyGoodsServlet\">确认</a>");
2 确认支付后

(1) 获取订单和商品信息
因为支付成功后需要更新库存,所以我们需要获取goods中的商品库存信息,所以只有Order中的订单项信息(orderItemList)是不够的,还需要商品信息goodsList。

//拿到订单session
HttpSession session = req.getSession();
Order order = (Order)session.getAttribute("order");
System.out.println(order);

//拿到goodList
List<Goods> goodsList = (List<Goods>)session.getAttribute("goodsList") ;
System.out.println(goodsList);

(2)更改支付完成后的订单状态:

		//更改订单信息
		order.setOrder_status(OrderStatus.OK);
		//设置完成时间
		Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss"
        );
        String finishTime = format.format(date);
        order.setFinish_time(finishTime);

(3)将订单和订单项信息写入数据库
订单:

ps.setInt(3,order.getActual_amountInt());
ps.setInt(4,order.getTotal_moneyInt());
ps.setInt(5,order.getOrder_status().getFlg());

订单项:

String insertOrderItemSql = "insert into order_item(order_id, goods_id, goods_name," +
                    "goods_introduce, goods_num, goods_unit," +
                    " goods_price, goods_discount) " +
                    "values (?,?,?,?,?,?,?,?)";
            ps = connection.prepareStatement(insertOrderItemSql);

            for (OrderItem orderItem : order.getOrderItemList()) {
                ps.setString(1,orderItem.getOrder_id());
                ps.setInt(2,orderItem.getGoods_id());
                ps.setString(3,orderItem.getGoods_name());
                ps.setString(4,orderItem.getGoods_introduce());
                ps.setInt(5,orderItem.getGoods_num());
                ps.setString(6,orderItem.getGoods_unit());
                ps.setInt(7,orderItem.getGoods_priceInt());
                ps.setInt(8,orderItem.getGoods_discount());
                ps.addBatch();// 缓存
            }

            int[] effect = ps.executeBatch();//批量的插入
            for ( int i : effect) {
                if(i == 0) {
                    throw new RuntimeException("插入订单明细失败!");
                }
            }
            //批量插入没有发生任何的异常
            connection.commit();
        }catch (Exception e) {
            e.printStackTrace();
            //判断链接是否断开
            if(connection != null) {
                try {
                    //回滚
                    connection.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
            return false;
        }finally {
            DBUtil.close(connection,ps,null);
        }

在批量插入时,为了避免数据出错,需要先插入到缓存中。

若发生异常则全部回滚:

    //判断链接是否断开
    if(connection != null) {
        try {
            //回滚
            connection.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
    }

插入数据库成功后,开始更新库存,更新库存成功后跳转到buyGoodsSuccess.html。

Ⅷ 浏览订单

在这里插入图片描述

和浏览商品类似,只不过这里涉及到了多表查询。
在这里插入图片描述

public class OrderBrowse {
    public List<Order> orderBrowse(Integer id) {
        Connection con= null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<Order> orders = new ArrayList<>();
        try{
            String sql = "select o1.id              as order_id,\n" +
                    "       o1.account_id      as account_id,\n" +
                    "       o1.create_time     as create_time,\n" +
                    "       o1.finish_time     as finish_time,\n" +
                    "       o1.actual_amount   as actual_amount,\n" +
                    "       o1.total_money     as total_money,\n" +
                    "       o1.order_status    as order_status,\n" +
                    "       o1.account_name    as account_name,\n" +
                    "       o2.id              as item_id,\n" +
                    "       o2.goods_id        as goods_id,\n" +
                    "       o2.goods_name      as goods_name,\n" +
                    "       o2.goods_introduce as goods_introduce,\n" +
                    "       o2.goods_num       as goods_num,\n" +
                    "       o2.goods_unit      as goods_unit,\n" +
                    "       o2.goods_price     as goods_price,\n" +
                    "       o2.goods_discount  as goods_discount\n" +
                    "from `order` as o1\n" +
                    "         left join order_item as o2 on\n" +
                    "          o1.id = o2.order_id\n" +
                    "where o1.account_id = ? order by order_id;";
            con = DBUtil.getConnection(true);
            ps = con.prepareStatement(sql);
            ps.setInt(1,id);
            rs =  ps.executeQuery();

            Order order = null;

            while(rs.next()){
                if(order==null){
                    //为每个订单添加订单信息
                    order= new Order();
                    extractOrder(order,rs);
                    orders.add(order);
                }

                //一个订单有多个订单项,需要将多个相同的订单进行整合
                //如果order_id不相同了,说明上一个订单已经处理完,此时需要新建一个新的订单
                String order_ID = rs.getString("order_id");
                if(!order.getId().equals(order_ID)){
                    //为每个订单添加订单信息
                    order= new Order();
                    extractOrder(order,rs);
                    orders.add(order);
                }

                //为每个订单中加入订单项信息(商品信息),一个订单有多个订单项
                OrderItem orderItem = extractOrderItem(rs);
                order.getOrderItemList().add(orderItem);
            }
        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            DBUtil.close(con,ps,rs);
        }
        return orders;
    }

    public OrderItem extractOrderItem(ResultSet resultSet) throws SQLException {

        OrderItem orderItem = new OrderItem();
        orderItem.setId(resultSet.getString("item_id"));
        orderItem.setGoods_id(resultSet.getInt("goods_id"));
        orderItem.setGoods_name((resultSet.getString("goods_name")));
        orderItem.setGoods_introduce(resultSet.getString("goods_introduce"));
        orderItem.setGoods_num(resultSet.getInt("goods_num"));
        orderItem.setGoods_unit(resultSet.getString("goods_unit"));
        orderItem.setGoods_price(resultSet.getInt("goods_price"));
        orderItem.setGoods_discount(resultSet.getInt("goods_discount"));
        return orderItem;
    }

    private void extractOrder(Order order,ResultSet rs) throws SQLException {
        order.setId(rs.getString("order_id"));
        order.setAccount_id(rs.getInt("account_id"));
        order.setAccount_name(rs.getString("account_name"));
        order.setCreate_time(rs.getString("create_time"));
        order.setFinish_time(rs.getString("finish_time"));
        order.setActual_amount(rs.getInt("actual_amount"));
        order.setTotal_money(rs.getInt("total_money"));
        order.setOrder_status(OrderStatus.valueOf(rs.getInt("order_status")));
    }
}

订单项表:
在这里插入图片描述
由上图可知,一个订单号对应多个订单项。我们在使用联表查询时,实际上查到的也是多个相同的订单号,比如一个订单有5个订单项(买了5种商品),那么查到的就是5条相同的订单信息,这时我们需要将其整合到一张订单中。所以才有了下面的判断:

当前查询到的订单id和上个id订单不同时,就说明上个订单的所有订单项都处理完了,开始处理下一个订单。

         //一个订单有多个订单项,需要将多个相同的订单进行整合
         //如果order_id不相同了,说明上一个订单已经处理完,此时需要新建一个新的订单
                String order_ID = rs.getString("order_id");
                if(!order.getId().equals(order_ID)){
                    //为每个订单添加订单信息
                    order= new Order();
                    extractOrder(order,rs);
                    orders.add(order);
                }

注意:
浏览订单时报错,主要是在向前端传json数据时,有I/O操作,且没有对其捕获异常,因此不知错误出现在哪。当不知道错误在哪时,要学会用try catch捕捉错误信息,尤其是有I/O的地方

错误处理:浏览器页面及后端页面都没报错,但是不显示内容?

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值