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

新浪微博网站建设许昌seo公司

新浪微博网站建设,许昌seo公司,潍坊信息网网站建设,设计师网站推荐家装利用自定义注解,解决问题 例1 自定义注解限制请求 场景:前端发起的频繁的请求,导致服务器压力过大。需要对后端接口进行限流处理,每个接口都需要做限流处理的话就会导致代码冗余,此时就可以利用注解进行解决 非注解形…

利用自定义注解,解决问题

例1 自定义注解限制请求

场景:前端发起的频繁的请求,导致服务器压力过大。需要对后端接口进行限流处理,每个接口都需要做限流处理的话就会导致代码冗余,此时就可以利用注解进行解决

非注解形式

这里是用于 某个用户点击的次数(结合radis)进行判断,也可以用请求的ip进行判断

核心代码:

        //限流,60秒5次ValueOperations valueOperations = redisTemplate.opsForValue();String uri = request.getRequestURI();//captcha = "0"; 这个用于测试Integer count =(Integer) valueOperations.get(uri+":"+user.getId());if(count == null){valueOperations.set(uri+":"+user.getId(),1,60,TimeUnit.SECONDS);} else if (count<5) {valueOperations.increment(uri+":"+user.getId());}else {return RespBean.error(RespBeanEnum.ACCESS_LIMIT_REAHCED);}

完整代码:

    @RequestMapping(value = "/path",method = RequestMethod.GET)@ResponseBodypublic RespBean getPath(User user,Long goodsId,String captcha,HttpServletRequest request){if(user == null){return RespBean.error(RespBeanEnum.SESSION_ERROR);}//限流,60秒5次ValueOperations valueOperations = redisTemplate.opsForValue();String uri = request.getRequestURI();log.info("uri====:{}",uri);log.info("qequestIp===={}",request.getRemoteAddr());log.info("LocalIp===={}",request.getLocalAddr());//captcha = "0";Integer count =(Integer) valueOperations.get(uri+":"+user.getId());if(count == null){valueOperations.set(uri+":"+user.getId(),1,60,TimeUnit.SECONDS);} else if (count<5) {valueOperations.increment(uri+":"+user.getId());}else {return RespBean.error(RespBeanEnum.ACCESS_LIMIT_REAHCED);}boolean check= orderService.checkCaptcha(user,goodsId,captcha);if(!check){return RespBean.error(RespBeanEnum.ERROR_CAPTCHA);}String str = orderService.createPath(user,goodsId);return RespBean.success(str);}

注解形式

注解定义方式,以AcessLimit为例

  1. 定义注解  AccessLimit

  2. 创建拦截器 AccessLimitInterceptor

  3. 在WebConfig 中添加拦截器 addInterceptors

定义注解AccessLimit
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {//时间int second();//次数int maxCount();//这个用于判断是否需要登录,后续可用SpringSecurity + JWT 实现。boolean needLogin() default true;
}
创建拦截器 AccessLimitInterceptor

核心代码:

@Component
public class AccessLimitInterceptor implements HandlerInterceptor {@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if(handler instanceof HandlerMethod){HandlerMethod hm = (HandlerMethod) handler;AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if( accessLimit ==null){return true;}int second = accessLimit.second();int maxCount = accessLimit.maxCount();boolean needLogin = accessLimit.needLogin();String key = request.getRequestURI();ValueOperations valueOperations =redisTemplate.opsForValue();Integer count = (Integer) valueOperations.get(key);if(count == null){valueOperations.set(key,1,second, TimeUnit.SECONDS);} else if (count<maxCount) {valueOperations.increment(key);} else {render(response,RespBeanEnum.ACCESS_LIMIT_REAHCED);return false;}}return true;}

完整代码:

package com.xxx.seckilldemo.annotation;import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxx.seckilldemo.config.UserContext;
import com.xxx.seckilldemo.pojo.User;
import com.xxx.seckilldemo.service.IUserService;
import com.xxx.seckilldemo.utils.CookieUtil;
import com.xxx.seckilldemo.vo.RespBean;
import com.xxx.seckilldemo.vo.RespBeanEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;/** 接口限流拦截器* @author Adzc* @date 2023/11/15 15:40*/
@Component
public class AccessLimitInterceptor implements HandlerInterceptor {@Autowiredprivate IUserService userService;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if(handler instanceof HandlerMethod){User user = getUser(request,response);UserContext.setUser(user);HandlerMethod hm = (HandlerMethod) handler;AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if( accessLimit ==null){return true;}int second = accessLimit.second();int maxCount = accessLimit.maxCount();//此处是登录相关boolean needLogin = accessLimit.needLogin();String key = request.getRequestURI();if(needLogin){if (user == null){render(response, RespBeanEnum.SESSION_ERROR);return false;}key+=":"+user.getId();}//在有效时间内,次数的判断ValueOperations valueOperations =redisTemplate.opsForValue();Integer count = (Integer) valueOperations.get(key);if(count == null){valueOperations.set(key,1,second, TimeUnit.SECONDS);} else if (count<maxCount) {valueOperations.increment(key);} else {//返回对象的定义render(response,RespBeanEnum.ACCESS_LIMIT_REAHCED);return false;}}return true;}/*** 获取当前用户* @param request* @param response* @return*/private User getUser(HttpServletRequest request,HttpServletResponse response){String ticket = CookieUtil.getCookieValue(request,"userTicket");if (StringUtils.isEmpty(ticket)){System.out.println("没有获取到用户");return null;}return userService.getUserByCookie(ticket,request,response);}/*** 构建返回对象* @param response* @param respBeanEnum*/private void render(HttpServletResponse response,RespBeanEnum respBeanEnum) throws IOException {response.setContentType("application/json");response.setCharacterEncoding("utf-8");PrintWriter out = response.getWriter();RespBean respBean = RespBean.error(respBeanEnum);out.write(new ObjectMapper().writeValueAsString(respBean));out.flush();out.close();}
}

返回对象用到了枚举

/*** 公共返回对象* @author Adzc* @date 2023/9/25 23:19*/@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class RespBean {private long code;private String message;private Object obj;/*** 成功返回结果* @return*/public static RespBean success(){return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(),null);}public static RespBean success(Object obj){return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(),obj);}/*** 失败返回结果* @param respBeanEnum* @return*/public static RespBean error(RespBeanEnum respBeanEnum){return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(),null);}public static RespBean error(RespBeanEnum respBeanEnum,Object obj){return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(),obj);}
}
@Getter
@ToString
@AllArgsConstructor
public enum RespBeanEnum {SUCCESS(200,"SUCCESS"),ERROR(500,"服务端异常"),//登录模块LOGIN_ERROR(500210,"用户名或密码不正确"),MOBILE_ERROR(500211,"非法手机号"),BIND_ERROR(500212,"参数校验异常"),MOBILE_NOT_EXIST(500213, "手机号不存在"),PASSWORD_UPDATE_FAIL(500214,"密码更新失败"),SESSION_ERROR(500215,"用户不存在"),ACCESS_LIMIT_REAHCED(500504,"访问过于频繁请稍后在尝试");private final Integer code;private final String message;
}
在WebConfig 中添加拦截器 addInterceptors

核心代码

@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(accessLimitInterceptor);}}

完整代码

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate AccessLimitInterceptor accessLimitInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(accessLimitInterceptor);}
}

例2 利用@JsonSerialize注解+自定义类进行手机号脱敏处理

场景:很多手机号之类的信息需要在前端页面需要进行脱敏处理

public class PhoneJsonSerializer extends JsonSerializer {@Overridepublic void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {if (value != null && value instanceof String){if (!Objects.equals(value,"") && value.toString().length() > 5){String phone = value.toString();phone = phone.substring(0, 3) + "******" + phone.substring(phone.length() - 2);gen.writeString(phone);} else {gen.writeObject(value);}} else {gen.writeObject(value);}}}

在返回的对象中使用

@JsonSerialize(using = PhoneJsonSerializer.class)private String phone;

http://www.fp688.cn/news/143724.html

相关文章:

  • 做外汇最好的财经网站百度网盘资源链接入口
  • i岗网站建设最新社会舆情信息
  • 200万做网站云南网站建设快速优化
  • 做网贷中介网站赚钱吗做销售找客户渠道
  • 海淀深圳网站建设公司长沙官网网站推广优化
  • 利用店铺网站做灰色优化百度app下载
  • 怎样用模板建一个网站运营推广计划怎么写
  • 运用.net做网站怎么创建自己的游戏网站
  • 成都哪个公司做网站郑州seo排名第一
  • 网站开发全程设计推广恶意点击软件怎样使用
  • 太原网站建外链怎么发
  • 网易企业邮箱免费和收费区别培训机构优化
  • 创建网站的流程有哪些如何在互联网上做推广
  • 最牛的手机视频网站建设建站模板免费下载
  • 模板网站什么意思品牌营销推广策划方案
  • 专业武汉网站建设公司排名app推广渠道有哪些
  • 北京网站建设及优化打广告的免费软件
  • 济南市章丘区建设局网站足球比赛今日最新推荐
  • 郑州做网站建设公司互联网营销顾问
  • 东莞网站优化方法如何推广自己的网站
  • 电商平台如何搭建网站seo视频
  • 南京小程序开发费用seo链接优化建议
  • 网站做文件检查房地产最新消息
  • 北京网站开发不限年龄网址收录查询
  • 网站分析一般要重点做哪几项内容适合交换友情链接的是
  • wordpress评论不要地址邮箱如何结合搜索检索与seo推广
  • 网站开发工作好不好便宜的seo官网优化
  • 建设银网站推广手段
  • 第一次和别人女友做网站成都网站建设公司排名
  • 建设一个电商网站的步骤哈尔滨关键词优化报价