温泉水电工培训学校,温泉电工速成培训
专注于水电工培训、为温泉地区水电工的求学者提供专业的水电工培训课程和充电平台!
主页 > 技术文章 > 电脑技术 >

温泉水电工培训学校,温泉电工速成培训

  • 课程介绍

  • 参考资料

  • 2020-05-18 21:20
湖南阳光水电工培训学校常年面向温泉招生!
【推荐】温泉快速学水电工技术,从湖南阳光水电工培训学校开始。温泉水电工培训学校、温泉水电工培训班,首选湖南阳光水电工培训学校!电话:0731-85579057,0731-85569651

【温馨提示】湖南阳光水电工培训学校地址:湖南省长沙市雨花区车站南路红花坡路176号。目前没有在温泉地区设立分校。热忱欢迎温泉的学员来湖南阳光水电工培训学校长沙总校区参加学习!

温泉水电工培训学校,温泉电工速成培训

详情请进入 湖南阳光电子学校 已关注: 咨询电话:0731-85579057 微信号:yp941688, yp94168

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训班

温泉水电工学校

温泉水电工培训学校招生详情:为您提供专业的温泉学水电工的学校,温泉水电工培训哪里好,温泉水电工培训学校,温泉水电工短期培训班,温泉水电工培训学校地址,温泉学水电工培训,温泉水电工培训哪里好,温泉水电工培训班,温泉水电工技术培训信息以及温泉水电工培训学校和温泉水电工培训班最新资讯,湖南阳光水电工培训学校,常年面向温泉地区开设水电工培训班,是专业的温泉水电工学校,常年面向温泉地区招生,热忱欢迎温泉地区的水电工技术求学者来我校学习最专业的水电工技术。温泉水电工培训学校,温泉水电工培训班,温泉水电工学校,温泉水电工培训学校,温泉水电工培训班哪家好,电工速成培训。

温泉水电工培训学校,温泉电工速成培训

温泉水电工培训学校,温泉电工速成培训

温泉水电工培训班文章内容:

深圳光明区测试仪器测量工具计量校准一、概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次

比如:

订单接口, 不能多次创建订单支付接口, 重复支付同一笔订单只能扣一次钱支付宝回调接口, 可能会多次回调, 必须处理重复回调普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次等等二、常见解决方案唯一索引 -- 防止新增脏数据token机制 -- 防止页面重复提交悲观锁 -- 获取数据的时候加锁(锁表或锁行)乐观锁 -- 基于版本号version实现, 在更新数据那一刻校验数据分布式锁 -- redis(jedis、redisson)或zookeeper实现状态机 -- 状态变更, 更新数据时判断状态三、本文实现本文采用第2种方式实现, 即通过redis + token机制实现接口幂等性校验

四、实现思路为需要保证幂等性的每一次请求创建一个唯一标识token, 先获取token, 并将此token存入redis, 请求接口时, 将此token放到header或者作为请求参数请求接口, 后端接口判断redis中是否存在此token:

如果存在, 正常处理业务逻辑, 并从redis中删除此token, 那么, 如果是重复请求, 由于token已被删除, 则不能通过校验, 返回请勿重复操作提示如果不存在, 说明参数不合法或者是重复请求, 返回提示即可五、项目简介springbootredis@ApiIdempotent注解 + 拦截器对请求进行拦截@ControllerAdvice全局异常处理压测工具: jmeter说明:本文重点介绍幂等性核心实现, 关于springboot如何集成redis、ServerResponse、ResponseCode等细枝末节不在本文讨论范围之内, 有兴趣的小伙伴可以查看我的Github项目:

https://github.com/wangzaiplus/springboot/tree/wxw六、代码实现pom

<!-- Redis-Jedis -->

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.9.0</version>

</dependency>

<!--lombok 本文用到@Slf4j注解, 也可不引用, 自定义log即可-->

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<version>1.16.10</version>

</dependency>JedisUtil

@Component

@Slf4j

public class JedisUtil {

@Autowired

private JedisPool jedisPool;

private Jedis getJedis() {

return jedisPool.getResource();

}

/**

* 设值

*

* @param key

* @param value

* @return

*/

public String set(String key, String value) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.set(key, value);

} catch (Exception e) {

log.error("set key:{} value:{} error", key, value, e);

return null;

} finally {

close(jedis);

}

}

/**

* 设值

*

* @param key

* @param value

* @param expireTime 过期时间, 单位: s

* @return

*/

public String set(String key, String value, int expireTime) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.setex(key, expireTime, value);

} catch (Exception e) {

log.error("set key:{} value:{} expireTime:{} error", key, value, expireTime, e);

return null;

} finally {

close(jedis);

}

}

/**

* 取值

*

* @param key

* @return

*/

public String get(String key) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.get(key);

} catch (Exception e) {

log.error("get key:{} error", key, e);

return null;

} finally {

close(jedis);

}

}

/**

* 删除key

*

* @param key

* @return

*/

public Long del(String key) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.del(key.getBytes());

} catch (Exception e) {

log.error("del key:{} error", key, e);

return null;

} finally {

close(jedis);

}

}

/**

* 判断key是否存在

*

* @param key

* @return

*/

public Boolean exists(String key) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.exists(key.getBytes());

} catch (Exception e) {

log.error("exists key:{} error", key, e);

return null;

} finally {

close(jedis);

}

}

/**

* 设值key过期时间

*

* @param key

* @param expireTime 过期时间, 单位: s

* @return

*/

public Long expire(String key, int expireTime) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.expire(key.getBytes(), expireTime);

} catch (Exception e) {

log.error("expire key:{} error", key, e);

return null;

} finally {

close(jedis);

}

}

/**

* 获取剩余时间

*

* @param key

* @return

*/

public Long ttl(String key) {

Jedis jedis = null;

try {

jedis = getJedis();

return jedis.ttl(key);

} catch (Exception e) {

log.error("ttl key:{} error", key, e);

return null;

} finally {

close(jedis);

}

}

private void close(Jedis jedis) {

if (null != jedis) {

jedis.close();

}

}

}自定义注解@ApiIdempotent

/**

* 在需要保证 接口幂等性 的Controller的方法上使用此注解

*/

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

public @interface ApiIdempotent {

}ApiIdempotentInterceptor拦截器

/**

* 接口幂等性拦截器

*/

public class ApiIdempotentInterceptor implements HandlerInterceptor {

@Autowired

private TokenService tokenService;

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

if (!(handler instanceof HandlerMethod)) {

return true;

}

HandlerMethod handlerMethod = (HandlerMethod) handler;

Method method = handlerMethod.getMethod();

ApiIdempotent methodAnnotation = method.getAnnotation(ApiIdempotent.class);

if (methodAnnotation != null) {

check(request);// 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示

}

return true;

}

private void check(HttpServletRequest request) {

tokenService.checkToken(request);

}

@Override

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}TokenServiceImpl

@Service

public class TokenServiceImpl implements TokenService {

private static final String TOKEN_NAME = "token";

@Autowired

private JedisUtil jedisUtil;

@Override

public ServerResponse createToken() {

String str = RandomUtil.UUID32();

StrBuilder token = new StrBuilder();

token.append(Constant.Redis.TOKEN_PREFIX).append(str);

jedisUtil.set(token.toString(), token.toString(), Constant.Redis.EXPIRE_TIME_MINUTE);

return ServerResponse.success(token.toString());

}

@Override

public void checkToken(HttpServletRequest request) {

String token = request.getHeader(TOKEN_NAME);

if (StringUtils.isBlank(token)) {// header中不存在token

token = request.getParameter(TOKEN_NAME);

if (StringUtils.isBlank(token)) {// parameter中也不存在token

throw new ServiceException(ResponseCode.ILLEGAL_ARGUMENT.getMsg());

}

}

if (!jedisUtil.exists(token)) {

throw new ServiceException(ResponseCode.REPETITIVE_OPERATION.getMsg());

}

Long del = jedisUtil.del(token);

if (del <= 0) {

throw new ServiceException(ResponseCode.REPETITIVE_OPERATION.getMsg());

}

}

}TestApplication

@SpringBootApplication

@MapperScan("com.wangzaiplus.test.mapper")

public class TestApplication extends WebMvcConfigurerAdapter {

public static void main(String[] args) {

SpringApplication.run(TestApplication.class, args);

}

/**

* 跨域

* @return

*/

@Bean

public CorsFilter corsFilter() {

final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

final CorsConfiguration corsConfiguration = new CorsConfiguration();

corsConfiguration.setAllowCredentials(true);

corsConfiguration.addAllowedOrigin("*");

corsConfiguration.addAllowedHeader("*");

corsConfiguration.addAllowedMethod("*");

urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

return new CorsFilter(urlBasedCorsConfigurationSource);

}

@Override

public void addInterceptors(InterceptorRegistry registry) {

// 接口幂等性拦截器

registry.addInterceptor(apiIdempotentInterceptor());

super.addInterceptors(registry);

}

@Bean

public ApiIdempotentInterceptor apiIdempotentInterceptor() {

return new ApiIdempotentInterceptor();

}

}OK, 目前为止, 校验代码准备就绪, 接下来测试验证

七、测试验证1、获取token的控制器TokenController

@RestController

@RequestMapping("/token")

public class TokenController {

@Autowired

private TokenService tokenService;

@GetMapping

public ServerResponse token() {

return tokenService.createToken();

}

}2、TestController, 注意@ApiIdempotent注解, 在需要幂等性校验的方法上声明此注解即可, 不需要校验的无影响

@RestController

@RequestMapping("/test")

@Slf4j

public class TestController {

@Autowired

private TestService testService;

@ApiIdempotent

@PostMapping("testIdempotence")

public ServerResponse testIdempotence() {

return testService.testIdempotence();

}

}3、获取token

查看redis

4、测试接口安全性: 利用jmeter测试工具模拟50个并发请求, 将上一步获取到的token作为参数

5、header或参数均不传token, 或者token值为空, 或者token值乱填, 均无法通过校验, 如token值为"abcd"

温泉水电工培训学校,温泉水电工培训班,温泉水电工学校,温泉学水电工的学校,温泉水电工培训哪里好,温泉水电工培训学校,温泉水电工短期培训班,温泉水电工培训学校地址,温泉学水电工培训,温泉水电工培训哪里好,温泉水电工培训班,温泉水电工技术培训.(编辑:hnygdzxx888)

温泉水电工培训学校

温泉水电工学校延伸阅读:
电脑主机正常启动,可是显示屏没反应,有时候碰巧可以打开。-宝鸡手机维修培训学校 全国最好的电工学校 初学电工技巧 阿拉尔家电维修培训学校再谈cad转pdf怎样用批量转换 锡林郭勒电工培训班在哪里有-分享:汽车故障灯亮了意味着什么应该怎么办 - 保养维护 R467笔记本电脑不开机故障维修-周口手机维修培训学校 电脑开不了机《出现红三角英语字母。怎么办?-河池手机维修培训学校 学电工哪里最好 岳阳电工培训班在哪里有-分享:天猫承认锤子手机预约数造假;魅族多款手机爆发失灵门;中移动新媒体公司命名“咪咕” 电工培训要多少钱 【台式机开机无显示】电脑开机后,屏幕显示无信号输入。这是怎么-邢台手机维修培训学校 学电工哪里最好 德阳技工学校职高职业学校哪家好【分享】成都技校都有哪些 电工技术学校 神农架电工培训班在哪里有-分享:汽车常见故障原因分析-传动轴 电工资为什么高 电脑死机,然后屏幕显示无信号-合肥手机维修培训学校 阿勒泰技工学校职高职业学校哪家好【分享】武汉海事中等职业技术学校 滨州电工培训学校_滨州电工培训班哪家好:当手机变成钱包时 手机支付九大安全须防范 哪里可以培训电工

(整理:温泉水电工培训学校)


温泉水电工培训学校

湖南阳光电子学校教学特色

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

温泉水电工培训学校

  • 温泉水电工培训学校,温泉电工速成培训
  • 扫码分享
  • 最新资讯
  • 热点资讯
    在温泉想学水电工去哪里学,在温泉学水电工真的好吗,温泉到哪里学水电工,温泉哪里能学水电工,温泉在哪里学水电工,温泉温泉水电工学校哪家好,温泉学水电工哪里好,温泉学水电工要多久能拿证,温泉学水电工要多长时间,温泉学水电工多久可以学会,温泉学水电工要多少钱,温泉哪有学水电工的学校,温泉哪有水电工学校,温泉一般水电工学校学费,温泉水电工学校学多久,温泉学水电工学费多少钱,温泉学水电工多少钱,温泉报个水电工速成班多少钱,温泉最好的水电工学校,温泉水电工培训速成班,温泉学水电工速成班,温泉学水电工一般要多长时间,温泉水电工短期培训多长时间,温泉水电工短期培训学校,温泉培训水电工多少钱,温泉有水电工培训班,温泉哪里有水电工培训,温泉水电工培训多少钱,温泉水电工培训要多少钱,温泉水电工培训费用,温泉水电工培训中心在哪里,温泉水电工培训中心电话是多少,温泉水电工技术培训中心,温泉水电工培训哪家学校最好,温泉哪家水电工学校最好,温泉水电工技术学校,温泉水电工学校收费标准,温泉水电工培训怎么收费,温泉水电工培训班能相信吗,温泉哪家水电工短期培训好,温泉水电工技术培训学校,温泉学水电工哪家好,温泉学水电工要多久,温泉哪里可以培训水电工,温泉水电工培训班多少钱,温泉水电工培训,温泉温泉哪有学水电工的地方,温泉学水电工的学校,温泉水电工学校哪里好,温泉学水电工多少钱学费,温泉学水电工哪里最好,温泉学水电工培训班多少钱,温泉水电工速成培训,温泉水电工培训哪个好,温泉水电工培训班,温泉有名的水电工培训中心,温泉短期水电工培训学校,温泉学水电工到哪里比较好,温泉水电工培训中心,温泉水电工培训哪里好,温泉水电工速成班学费,温泉水电工短期培训,温泉水电工培训学校
电工培训学校 电动车维修学校 摩托车维修学校 手机维修培训学校 水电工培训学校 电脑维修培训学校 电动工具维修培训学校 液晶电视维修培训学校 安防监控培训学校 空调维修培训学校 电焊培训学校 手机维修培训学校 电工培训学校 摩托车维修培训学校 电器维修培训学校 家电维修学校 焊工培训学校 电工培训学校 木工培训学校 瓦工培训学校 摩托车维修学校 电工培训学校 木工培训学校 电器维修学校 电工培训学校