1.什么是接口冪等性?
接口程序多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同补履。
2.什么情況下要用到冪等性
在寫入數(shù)據(jù)時添坊,保證某個數(shù)據(jù)多次寫入而數(shù)據(jù)庫只插入一次數(shù)據(jù),比如支付問題箫锤,用戶支付一次就可完成商品交易贬蛙,當(dāng)網(wǎng)絡(luò)卡頓時,用戶多次點擊付款按鈕谚攒,最終只執(zhí)行一次支付阳准,避免重復(fù)支付給用戶帶來的經(jīng)濟(jì)損失。
3.使用攔截器實現(xiàn)接口冪等性
這里馏臭,模擬一個場景:在數(shù)據(jù)庫中添加商品(name)與編號(code)野蝇,code是商品的唯一標(biāo)識id,不可重復(fù)括儒,也就是說多次寫入某個商品時數(shù)據(jù)庫添加的數(shù)據(jù)只能有一個绕沈,避免了數(shù)據(jù)的重復(fù)性。
下面開始用攔截器實現(xiàn)功能:
首先帮寻,項目的代碼(springboot項目)如下:
mapper:
public interface MiMapper {
/*
* 插入數(shù)據(jù)
* */
? ? int insert(Mi mi);
/*
* 查詢
* */
? ? List find(String code);
}
MiMapper.xml:
<mapper namespace="com.example.mideng.mapper.MiMapper">
<insert id="insert" parameterType="com.example.mideng.pojo.Mi">
insert into t_mi(name,code) values (#{name},#{code})
</insert>
<select id="find" parameterType="String" resultType="com.example.mideng.pojo.Mi">
select code from t_mi where code=#{code}
</select>
</mapper>
service:
public interface MiService {
int insert(Mi mi);
/*
* 查詢
* */
? ? List find(String code);
}
serviceImpl:
@Service
public class MiServiceImplimplements MiService {
@Autowired
? ? private MiMappermiMapper;
@Override
? ? public int insert(Mi mi) {
return miMapper.insert(mi);
}
@Override
? ? public List find(String code) {
return miMapper.find(code);
}
}
controller:
@Controller
public class WelcomeController {
@RequestMapping("/welcome")
public String wel(){
return "welcome";
}
}
@Controller
@RequestMapping("/mideng")
public class MiController {
@Autowired
? ? private MiServicemiService;
@RequestMapping("/tijiao")
public String tijiao(Mi mi){
int insert =miService.insert(mi);
return "ok";
}
@RequestMapping("/tip")
public String tip(){
return "tip";
}
}
html文件就不特意寫出了乍狐,就是簡單的數(shù)據(jù)提交,記得加上th:標(biāo)簽固逗,因為我這是用的thymeleaf模板浅蚪。
添加攔截器實現(xiàn)冪等
(1)首先自定義攔截器藕帜,這里思路是獲取http中的code參數(shù),然后在調(diào)用MiService 查詢該code在數(shù)據(jù)庫中是否已經(jīng)寫入惜傲,返回的是list耘戚,如果list的容量為0,說明數(shù)據(jù)表還沒插入數(shù)據(jù)操漠,那么返回true收津,否則重定向到提示界面并且返回false,不讓程序往下執(zhí)行。
@Component
public class MiDengIntercepterimplements HandlerInterceptor {
@Autowired
? ? private MiService miService;
@Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
String code = request.getParameter("code");
List mi =miService.find(code);
if (mi.size()==0){
? ? ? ? ? ? return true;
}else {
response.sendRedirect("/mideng/tip");
return false;
}
}
}
(2)配置攔截器
攔截器寫好后記得配置浊伙,這里添加的攔截路徑只有一個撞秋,就是提交接口,提交接口實現(xiàn)的功能是將數(shù)據(jù)寫入數(shù)據(jù)表
@Configuration
public class TiJiaoConfigureimplements WebMvcConfigurer {
@Autowired
? ? private MiDengIntercepter miDengIntercepter;
@Override
? ? public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(miDengIntercepter).addPathPatterns("/mideng/tijiao");
}
}
演示:
運(yùn)行項目嚣鄙,訪問http://localhost:8080/welcome
先看下數(shù)據(jù)表吻贿,因為目前還沒添加數(shù)據(jù),所以是空的哑子。
開始寫入:
點擊添加:
查看數(shù)據(jù)庫:
數(shù)據(jù)成功寫入舅列。下面繼續(xù)添加,這時code仍是123
點擊添加:
會出現(xiàn)提示卧蜓,查看數(shù)據(jù)庫:
發(fā)現(xiàn)仍然只有一條數(shù)據(jù)帐要,現(xiàn)在換一下名稱看看效果:
點擊添加:
查看數(shù)據(jù)庫:
分析:因為是對code的攔截判斷弥奸,所以表中不能有重復(fù)的code榨惠。下面換一下code試試:
點擊添加:
查看數(shù)據(jù)庫:
繼續(xù):
點擊添加:
查看數(shù)據(jù)庫:
發(fā)現(xiàn)只要code不同就可插入數(shù)據(jù),如果插入的code相同盛霎,那么無論點擊多少次添加赠橙,都只能執(zhí)行一次,所以簡單的冪等實現(xiàn)也就完成了愤炸。