当前位置: 首页 > news >正文

wordpress设置cdn缓存重庆关键词seo排名

wordpress设置cdn缓存,重庆关键词seo排名,做网站开发没有人带,深圳网站设计公司哪个看本篇博客前应当先看完前面三篇,这一篇是基于前面三篇的知识点的整合。所以很多重复的代码这里就不写出了 后台通过拦截器和redis实现防重复提交,避免因为网络原因导致多次请求同时进入业务系统,导致数据错乱,也可以防止对外暴露…

看本篇博客前应当先看完前面三篇,这一篇是基于前面三篇的知识点的整合。所以很多重复的代码这里就不写出了
后台通过拦截器和redis实现防重复提交,避免因为网络原因导致多次请求同时进入业务系统,导致数据错乱,也可以防止对外暴露给第三方的接口在业务尚未处理完的情况下重复调用。

首先引入fastjson

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.35</version>
</dependency>

 新增一个幂等校验的注解

package com.xxx.util.core.annotation;import javax.ws.rs.NameBinding;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@NameBinding
public @interface Idempotent
{/*** 是否把body数据用来计算幂等key。如果没有登录信息,请设置这个值为true。主要用于第三方接入。** @return*/boolean body() default false;/*** body里的哪些字段用来计算幂等key。body()为true时才有生效。如果这个为空,则计算整个body。主要用于第三方接入。<br/>* <p>* 字段命名规则:<br/>* path: Like xpath, to find the specific value via path. Use :(Colon) to separate different key name or index.* For example:* 	JSON content:* 		{* 			"name": "One Guy",* 			"details": [* 				{"education_first": "xx school"},* 				{"education_second": "yy school"},* 				{"education_third": "zz school"},* 				...* 			],* 			"loan": {"loanNumber":"1234567810","loanAmount":1000000},* 		}** To find the value of "name", the path="name".* To find the value of "education_second", the path="details:0:education_second".* To find the value of "loanNumber"  , the path="loan:loanNumber".* To find the value of "name" and "loanNumber"  , the path="name","loan:loanNumber".** @return*/String[] bodyVals() default {};/*** idempotent lock失效时间,in milliseconds。一些处理时间较长或者数据重复敏感的接口,可以适当设置长点时间。** @return*/int expiredTime() default 60000;}

默认不去读取body中的内容去做幂等,可以@Idempotent(body = true) 将body设为true开启

实现拦截器

package com.xxx.core.filter;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xxx.common.exception.FastRuntimeException;
import com.xxx.core.annotation.Idempotent;
import com.xxx.core.filter.request.HttpHelper;
import com.xxx.core.filter.request.RequestReaderHttpServletRequestWrapper;import com.xxx.util.core.utils.SpringContextUtil;
import com.xxx.util.redis.SimpleLock;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import redis.clients.jedis.JedisCluster;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.regex.Pattern;public class IdempotentFilter extends HandlerInterceptorAdapter {private final Logger logger = LoggerFactory.getLogger(IdempotentFilter.class);private static final String IDEMPOTENT = "idempotent.info";private static final String NAMESPACE = "idempotent";private static final String NAMESPACE_LOCK = "idempotent.lock";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {logger.info("request请求地址path[{}] uri[{}]", request.getServletPath(),request.getRequestURI());HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();Idempotent ra = method.getAnnotation(Idempotent.class);if (Objects.nonNull(ra)) {logger.debug("Start doIdempotent");int liveTime = getIdempotentLockExpiredTime(ra);String key = generateKey(request, ra);logger.debug("Finish generateKey:[{}]",key);JedisCluster jedisCluster = getJedisCluster();//上分布式锁 避免相同的请求同时进入调用jedisCluster.get(key) 都为null的情况new SimpleLock(NAMESPACE_LOCK + key,jedisCluster).wrap(new Runnable() {@Overridepublic void run() {//判断key是否存在,如存在抛出重复提交异常,如果不存在 则新增if (jedisCluster.get(key) == null){jedisCluster.setex(key,liveTime,"true");request.setAttribute(IDEMPOTENT, key);}else {logger.debug("the key exist : {}, will be expired after {} mils if not be cleared", key, liveTime);throw new FastRuntimeException(20001,"请勿重复提交");}}});}return true;}private int getIdempotentLockExpiredTime(Idempotent ra){return ra.expiredTime();}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {try{//业务处理完成 删除redis中的keyafterIdempotent(request);}catch (Exception e){// ignore it when exceptionlogger.error("Error after @Idempotent", e);}}private void afterIdempotent(HttpServletRequest request) throws IOException{Object obj = request.getAttribute(IDEMPOTENT);if (obj != null){logger.debug("Start afterIdempotent");String key =  obj.toString();JedisCluster jedisCluster = getJedisCluster();if (StringUtils.isNotBlank(key) && jedisCluster.del(key) == 0){logger.debug("afterIdempotent error Prepared to delete the key:[{}] ",key);}logger.debug("End afterIdempotent");}}/*** generate key** @param request* @param ra* @return*/public String generateKey(HttpServletRequest request, Idempotent ra){String requestURI = request.getRequestURI();String requestMethod = request.getMethod();StringBuilder result = new StringBuilder(NAMESPACE);String token = request.getHeader("H-User-Token");append(result, requestURI);append(result, requestMethod);append(result, token);appendBodyData( request, result, ra);logger.debug("The raw data to be generated key: {}", result.toString());return DigestUtils.sha1Hex(result.toString());}private void appendBodyData(HttpServletRequest request,  StringBuilder src,Idempotent ra){if (Objects.nonNull(ra)){boolean shouldHashBody = (boolean) ra.body();logger.debug("Found attr for body in @Idempotent, the value is {}", shouldHashBody);if (shouldHashBody){String data = null;try {data = HttpHelper.getBodyString(new RequestReaderHttpServletRequestWrapper(request));} catch (IOException e) {logger.warn("Found attr for body in @Idempotent, but the body is blank");return;}if (StringUtils.isBlank(data)){logger.warn("Found attr for body in @Idempotent, but the body is blank");return;}String[] bodyVals = ra.bodyVals();// bodyVals优先if (Objects.nonNull(bodyVals) && bodyVals.length != 0){logger.debug("Found attr for bodyVals in @Idempotent, the value is {}", Arrays.asList(bodyVals));final String finalData = data;Arrays.asList(bodyVals).stream().sorted().forEach(e -> {String val = getEscapedVal(finalData, e);append(src, val);});}else{append(src, data);}}}}private String getEscapedVal(String json, String path){String[] paths = path.split(":");JSONObject jsonObject = null;JSONArray jsonArray = null;String nodeVal = json;for (String fieldName : paths){if (isInteger(fieldName)){try {jsonArray = JSONObject.parseArray(nodeVal);nodeVal= jsonArray.get(Integer.parseInt(fieldName)).toString();} catch (JSONException e) {//如果无法转为jsonArray 则说明不是数组尝试转为jsonObject去取值logger.warn("getEscapedVal JSONObject.parseArray error nodeVal:[{}] fieldName:[{}]",nodeVal,nodeVal);jsonObject = JSONObject.parseObject(nodeVal);nodeVal = jsonObject.get(fieldName).toString();}}else {jsonObject = JSONObject.parseObject(nodeVal);nodeVal = jsonObject.get(fieldName).toString();}}return nodeVal;}public static boolean isInteger(String str) {Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");return pattern.matcher(str).matches();}private void append(StringBuilder src, String str){if (!StringUtils.isBlank(str)){src.append("#").append(str);}}//手动注入public JedisCluster getJedisCluster() {return SpringContextUtil.getBean(JedisCluster.class);}
}

新建SpringContextUtil工具类

package com.xxx.util.core.utils;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext; // Spring应用上下文环境public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtil.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}@SuppressWarnings("unchecked")public static <T> T getBean(String name) throws BeansException {return (T) applicationContext.getBean(name);}@SuppressWarnings("unchecked")public static <T> T getBean(Class<?> clz) throws BeansException {return (T) applicationContext.getBean(clz);}
}

使用方式异常简单,如果可以根据请求头的内容做区分是否重复提交则直接使用@Idempotent
即可,如果是提供给第三方的接口 请求头无法哦按段需要指定body则@Idempotent(body = true,bodyVals = {“loan:loanNumber”})即可

 

  • 案例代码如下
  • 	@Idempotent(body = true,bodyVals = {"loan:loanNumber"})@PostMapping(Urls.Test.V1_ADD)@ResponseBody@ApiOperation(value = Urls.UserProfiles.V1_GET_USER_PROFILES_BY_PAGE_DESC)public Response add(@RequestBody Test test) {return null;}
    

http://www.yayakq.cn/news/940112/

相关文章:

  • 项目网站开发js放的位置四川省住房和城乡建设局网站
  • 青海网站seo郑州建设高端网站
  • php网站开发 学习计划网站制作报价单模板
  • 国内网站免费服务器做检索网站
  • 营销网站建设解决方案linux wordpress 下载文件
  • 漯河专业做网站的公司宁夏网站建设费用
  • 做网站需要学会些什么个人网站建设实训目的
  • 做婚恋网站赚钱吗如何推广自己的公司官网
  • 石家庄站布局图北碚网站建设
  • 鞍山网站建设工作室装饰设计素描的秩序化构成包括
  • 网站上360 旋转的图是怎么做的wordpress如何设置头像
  • 免费cms建站网站建设 锋云科技
  • vue做网站导航江桥做网站
  • 网站维护工程师华为邮箱登录入口
  • 网站建设的目的分析网页界面设计遵循的原则
  • 万网制作网站wordpress主题绝对路径怎么修改
  • 万象园网站建设与开发平台制作网站公司
  • 建设了网站要维护吗甘肃网络推广技巧
  • 做影视类短视频的资源网站永川做网站
  • 沈阳网站建设 网络服务手机端网站自动弹出营销qq
  • 金融集团网站模板网页设计的代码
  • 网站模块绿色环保材料网站模板下载
  • 陕西网站建设公司排名网站分析设计做的项目的过程
  • 昆明商城网站建设中交路桥建设有限公司是国企还是央企
  • 网站建立的流程网站psd模板
  • 牡丹江建设网站公众号微信小程序是什么
  • 东莞网络营销代运营搜狗seo优化
  • aps网站服务建设住房和城乡建设部办公厅
  • 打开网站提示建设中wordpress 单一商品主题
  • 网站开发培训费网络app制作网站有哪些内容