后端第一次作业
1.产品说明
使用方式
直接通过postman进行使用,选择post类型后输入localhost:8080/此处输入可变
来进行使用,其中可变处可以有四种输入方式,
输入add代表加法
输入multiply代表乘法
输入substract代表减法
输入divide代表除法
其中a和b分别为两个变量,进行四则运算时a永远在b之前
如果输入不为数字或除法时除数为0,则会报错。
可能会出现的问题
1.Java运算中常出现的1.8 - 1.6 = 0.20000004问题和数据溢出问题
通过更换Double为BigDecimal可以进行解决
2.保证输入的只能是数字问题
通过<code class="prettyprint" >try-catch
函数以及String类转化成double类时会出现的
NumberFormatException e
报错保证输入的只能是数字。
3.保证除法中除数不为0的问题
通过除数为0时产生的<code class="prettyprint" >ArithmeticException e
报错保证除数一定不为0.
2.学习历程
1.学习的心路历程
我认为我本次的学习分为三个部分也是我自己去实践的三个部分。
第一个部分首先是我跟着培训里的内容自己粗略地写了一个可以实现加减乘除的API,但在运行的过程中首先我发现了我通过double去定义的函数无法解决数据溢出的问题,于是通过csdn上的一些解决方式,我将double更换成了BigDecimal,成功解决了数据溢出的问题。
第二个部分是我开始意识到我无法解决输入的字符一定是数字,同时分母不能为0的问题,在这个问题上我做了很多的挣扎,我尝试了try-catch函数进行处理使我能够在输入的量是字符或字符串时能够进行正确的报错,但当我输入数字时出现了报错(后面发现是我调用函数的时候写漏了一个东西导致死循环,谢谢大佬们帮我解决问题),因此我开始尝试@Digit等方式重新编程,最后由于我不会CSDN上写的代码的配置方式,他的文章里也没说最后不了了之。
第三个部分略微有点尴尬,在尝试了十八般武艺还没有解决我的问题并且死线要来了的时候我最后选择了求助群里的大佬,然后我就发现是个乌龙,只是少了一串字就导致成了死循环,是教训也给我上了一课,以后写代码的时候一定要理清思路,仔细检查一些问题。
2.学习到的拓展部分
拓展
虽然我找了一堆有的没的最后都没用上,但我还是想在这里写一个拓展
BigDecimal
这是一个十分有用的数据类型,它能够完美地解决数据溢出的问题,同时用它来计算也能够保证绝对的精度,但它也不是没有缺点
首当其冲的就是它在任何情况下都不能够用 A + B 这种传统方式进行计算,取而代之的是A.add(B),这虽然无伤大雅,但也是一个需要注意的点。
第二就是不能够用BigDecimal类构造方法传入double类,它会使计算后的数字变的误差较大。
第三就是用BigDecimal进行除法的编程时有一个特殊的格式:
<code class="prettyprint" >a.divide(b,此处写最大小数位数,此处写四舍五入等取整方式)
;
一些常用的注解
@Null
限制只能为null
@NotNull
限制必须不为null
@AssertFalse
限制必须为false
@AssertTrue
限制必须为true
@DecimalMax(value)
限制必须为一个不大于指定值的数字
@DecimalMin(value)
限制必须为一个不小于指定值的数字
@Digits(integer,fraction)
限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future
限制必须是一个将来的日期
@Max(value)
限制必须为一个不大于指定值的数字
@Min(value)
限制必须为一个不小于指定值的数字
@Past
限制必须是一个过去的日期
@Pattern(value)
限制必须符合指定的正则表达式
@Size(max,min)
限制字符长度必须在min到max之间
@Past
验证注解的元素值(日期类型)比当前时间早
@NotEmpty
验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank
验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
try-catch函数
try-catch函数是一个利用Java中的报错机制来实现某些目的的函数
它的大概格式如下:
try {
// 可能发生异常的语句
} catch(ExceptionType e) {
// 处理异常语句
}
这是一个简单的try-catch函数,在try后面跟着的代码块存放可能出现报错的代码,而catch后面的代码块则存放报错后的措施,它可以有很多个catch分别存放不同问题的处理方式,但要注意的是它优先执行错误对应的第一个catch。
try {
// 可能发生异常的语句
} catch(ExceptionType e) {
// 处理异常语句
}finally{
//无论try后面的代码块是否出现问题都会执行的代码块
}
要注意的是finally后面跟的代码块不是一定会执行的,某些时候出现问题它依然不会执行,但是它执行与否绝对与try后面的代码块无关。
3.下面是我的代码
Maincontroler部分
package com.example.demo.controller;
import ch.qos.logback.classic.spi.PackagingDataCalculator;
import com.example.demo.service.Calculate;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Data
@RestController
public class MainController {
@Autowired
Calculate calculate;//导入四则运算文件
@PostMapping("/add")
public Object add(@RequestParam String a,@RequestParam String b){
try {
double num1 = Double.parseDouble(a);
double num2 = Double.parseDouble(b);
return calculate.add(a,b);
}catch (NumberFormatException e){
return "错误,请输入数字";//利用String无法转为double确保输入一定为数字,下同
}
}
@PostMapping("/substract")
public Object substract(@RequestParam String a,@RequestParam String b){
try {
double num1 = Double.parseDouble(a);
double num2 = Double.parseDouble(b);
return calculate.substract(a,b);
}catch (NumberFormatException e){
return "错误,请输入数字";//利用String无法转为double确保输入一定为数字,下同
}
}
@PostMapping("/multiply")
public Object multiply(@RequestParam String a,@RequestParam String b) {
try {
double num1 = Double.parseDouble(a);
double num2 = Double.parseDouble(b);
return calculate.multiply(a, b);
} catch (NumberFormatException e) {
return "错误,请输入数字";//利用String无法转为double确保输入一定为数字,下同
}
}
@PostMapping("/divide")
public Object divide(@RequestParam String a,@RequestParam String b){
try {
double num1 = Double.parseDouble(a);
double num2 = Double.parseDouble(b);
return calculate.divide(a,b);
}catch (NumberFormatException e){
return "错误,请输入数字";//利用String无法转为double确保输入一定为数字,下同
}
catch (ArithmeticException e){
return "错误,除数不能为0";//利用除数为0时产生的报错确保除数输入不为0
}
}
}
calculate service部分
package com.example.demo.service;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.math.RoundingMode;
@Service
public class Calculate {
public Object add(String a ,String b){ //先用String承接MainController中的a和b
BigDecimal c = new BigDecimal(a);
BigDecimal d = new BigDecimal(b);//然后将其直接转化为BigDecimal避免精度损失
return c.add(d);
}
public Object substract(String a ,String b){ //先用String承接MainController中的a和b
BigDecimal c = new BigDecimal(a);
BigDecimal d = new BigDecimal(b);//然后将其直接转化为BigDecimal避免精度损失
return c.subtract(d);
}
public Object divide(String a ,String b){ //先用String承接MainController中的a和b
BigDecimal c = new BigDecimal(a);
BigDecimal d = new BigDecimal(b);//然后将其直接转化为BigDecimal避免精度损失
return c.divide(d,10, RoundingMode.HALF_UP);
//为了避免无限小数的问题,我设置了小数位最多为10位,多的四舍五入。
}
public Object multiply(String a ,String b){ //先用String承接MainController中的a和b
BigDecimal c = new BigDecimal(a);
BigDecimal d = new BigDecimal(b);//然后将其直接转化为BigDecimal避免精度损失
return c.multiply(d);
}
}