软件园学生在线

  • {{ item.name }}
  • 2023试用期

登录与注册

后端一 朱宣玮

  • FallenMoon
  • 2023-10-29
  • 0

基于 Spring Boot 的四则运算 API

一、产品说明

1. 简介

该四则运算API支持任意位数的数字之间的四则运算,支持小数运算。

它没有数据溢出或精度丢失问题。

(用它计算0.2+0.1,结果是0.3,Amazing!)

2. 使用方法

计算器界面

在计算器界面的输入框中输入符合运算法则的数字,点击“提交"即可在网页上得到运算结果。

以下是使用过程中会出现的一些特殊情况:

(1) 如果用户在输入框中输入的不是纯数字,或者什么也没输入,则会提醒用户“请输入数字捏”。

(2) 如果用户输入的除数为0,则会提醒用户“不能除以0哦”。

(非常的人性化,对吧)

二、学习历程

1. 基本功能实现

第一次培训上学习了加法的API,遂照葫芦画瓢写出了四则运算的API,完工!

当然,这样的API是不完美的,尤其是它计算0.2+0.1会得到0.30000000000000004,也就是说,它存在精度丢失问题。

通过查询资料,我找到了两种解决该问题的方式:

(1) 将可能出现误差的位舍去,简单粗暴。

(2) 使用java.math包中的BigDecimal类进行高精度运算。

后者不仅能提升精度,还能解决数据溢出问题,属于是一举两得,因此我选择了这种方式。

为避免double类型导致的数据精度丢失,BigDecimal类的构造方法最好用String类型的参数。于是,我把用户输入的数据类型改成了String。接下来的问题是,如果用户输入的不是纯数字或者根本没输东西,会出现异常。怎么能在页面上提示用户输入正确的数字呢?

一开始,我想用try catch实现这个功能,但我Controller里面的方法返回值类型是double,要catch异常并返回一句提示的话,返回值得是String才行。在我即将对我的代码进行大刀阔斧的改革的时候,我发现了这个东西:

@ExceptionHandler

哦,我的上帝,这个注解真的太棒了,省去了我修改代码的时间,也让代码更简洁了。虽然我也不明白它是怎么让方法的返回值显示在屏幕上的,但我并不关心这个,好用就行(

至于用户输入的除数为0导致的异常,我决定先加一个判断除数是否为0的步骤,若除数不是0再进行除法。这样除数为0就不会抛异常,不会由@ExceptionHandler来处理。也就是说,除数为0时的提示语可以单独设置,这下更人性化了。

在我测试数据的时候,又发现了新的问题:

使用BigDecimal类的除法如果得到的是无限循环小数,会出现异常。

一开始,我并不知道异常产生的原因。有的测试数据得出的是正确的结果,有的数据则是异常,让我困惑不已。查询资料后才发现是无限循环小数的问题,解决方法是保留固定位数小数。在设置固定位数后,计算结果本身若没有精确到设定的小数位数,后面会跟一堆0,解决方法也很简单,stripTrailingZeros方法即可去除多余的0。

至此,基本功能已经实现的差不多了。探索更优解的道路上充满了曲折,其间遇见了一些我解决不了的问题,但在不断地尝试与搜集资料下,终于突破阻碍,拨云见日。

2. 稍微完善一下

首先,按照群里的模版写(抄)了一个前端,并用舍友传授给我的CSS知识美化了一下界面。(纯粹是我闲的,并没有在卷视觉效果)

然后,把页面上显示的运算结果改成了运算式,这样看起来会好一些,也许。

至于GET注入,在这个API里是不存在的,因为输入的数据如果不是纯数字就会抛异常并提醒用户。

最后,对于作业要求里的生成接口文档,我尝试了一下,链接在这:

四则运算API

显然,它并不完善。嗯,就这样吧,忙大作业去了。

Goodbye.

走之前把代码留下吧。

三、代码

1. MainController 类

package com.example.demo.controller;

import com.example.demo.service.MainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
public class MainController {
    @Autowired
    MainService mainService;
    private String str = "请输入数字捏";

    @ExceptionHandler(Exception.class)
    public String exceptionHandler() {
        return str;
    }
    // 若用户输入的不是纯数字或什么也没输入,提示用户输入数字

    @GetMapping("/add")
    public String add(@RequestParam String a, @RequestParam String b) {
        return mainService.add(a, b);
    }

    @GetMapping("/subtract")
    public String subtract(@RequestParam String a, @RequestParam String b) {
        return mainService.subtract(a, b);
    }
    // 用户输入的数据类型为String,方便BigDecimal函数的构造

    @GetMapping("/multiply")
    public String multiply(@RequestParam String a, @RequestParam String b) {
        return mainService.multiply(a, b);
    }

    @GetMapping("/divide")
    public String divide(@RequestParam String a, @RequestParam String b) {
        return mainService.divide(a, b);
    }
}

2. MainService 类

package com.example.demo.service;

import com.sun.jdi.event.ExceptionEvent;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;

@Service
public class MainService {
    public String add(String a, String b) {
        return a + "+" + b + "=" + new BigDecimal(a).add(new BigDecimal(b)).toString();
    }

    public String subtract(String a, String b) {
        return a + "-" + b + "=" + new BigDecimal(a).subtract(new BigDecimal(b)).toString();
    }

    public String multiply(String a, String b) {
        return a + "×" + b + "=" + new BigDecimal(a).multiply(new BigDecimal(b)).toString();
    }

    private String str = "不能除以0哦";

    public String divide(String a, String b) {
        BigDecimal valOfB = new BigDecimal(b);
        if (valOfB.compareTo(BigDecimal.ZERO) == 0) {
            return str;
            // 若用户输入的除数为0,提示用户不能除以0
        } else {
            BigDecimal result = new BigDecimal(a).divide(valOfB, 10, BigDecimal.ROUND_HALF_UP);
            // 保留10位小数,四舍五入。若无保留位数,运算结果出现无限循环小数时会报错
            return a + "÷" + b + "=" + result.stripTrailingZeros().toPlainString();
            // 去掉小数点后多余的0,toPlainString避免科学计数法
        }
    }
}

3. 前端页面

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <title>四则运算</title>
    <style>
        form,input {
            font-size: large;
        }

        h1 {
            margin: 20px 0px;
            display: inline-block;
        }

        #p1,
        #p2 {
            display: flex;
            justify-content: space-evenly;
        }

        #p1 {
            margin: 20px 0px;
        }

        input {
            margin-top: 20px;
        }

    </style>
</head>

<body>
    <div id="p1">
        <div>
            <h1>加法</h1>
            <form action="http://localhost:8080/add" method="get">
                第一个加数:<input type="text" name="a"><br>
                第二个加数:<input type="text" name="b"><br>
                <input type="submit" value="提交">
            </form>
        </div>
        <div>
            <h1>减法</h1>
            <form action="http://localhost:8080/subtract" method="get">
                被 减 数:<input type="text" name="a"><br>
                减   数:<input type="text" name="b"><br>
                <input type="submit" value="提交">
            </form>
        </div>
    </div>
    <div id="p2">
        <div>
            <h1>乘法</h1>
            <form action="http://localhost:8080/multiply" method="get">
                第一个乘数:<input type="text" name="a"><br>
                第二个乘数:<input type="text" name="b"><br>
                <input type="submit" value="提交">
            </form>
        </div>
        <div>
            <h1>除法</h1>
            <form action="http://localhost:8080/divide" method="get">
                被 除 数:<input type="text" name="a"><br>
                除   数:<input type="text" name="b"><br>
                <input type="submit" value="提交">
            </form>
        </div>
    </div>
</body>

</html>

Goodbye again.

FallenMoon
FallenMoon
© 2025 软件园学生在线
Theme by Wing