本章内容涉及 redis 接口Aspect签名 swagger2
1,Linux centOS服务器安装redis 相关安装命令去网上具体找一下,比较简单 我使用了 config set maxmemory-policy volatile-lru 策略
2,创建一个空的module项目
添加pom依赖
<dependencies> <dependency> <groupId>org.jetbrains</groupId> <artifactId>annotations</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </exclusion> </exclusions> </dependency> <!--注册中心依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.1.2.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.dixintong</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
向注册中心注册自己,并且可被admin发现
创建一个启动类
@SpringBootApplication @RestController public class RedisapiApplication extends SpringBootServletInitializer { public static void main(String[] args) throws IOException { SpringApplication.run(RedisapiApplication.class, args); } }
配置文件
server: port: 9101 spring: application: name: redisapi eureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka instance: status-page-url-path: /actuator/info metadata-map.management: context-path: /actuator health-check-url-path: /actuator/health management: endpoints: web: exposure: include: '*' health: show-details: ALWAYS info: version: 1.0.0
向注册中心注册,check-url-path 被admin发现
创建一个Swagger2Config类 后面会使用
@EnableSwagger2 @Configuration public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) //.host("本地访问注释即可,线上访问写域名地址") .select() .apis(RequestHandlerSelectors.basePackage("com.xxxx.redisapi.controller")) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("swagger-api文档") .description("swagger接入教程") //服务条款网址 .termsOfServiceUrl("http://www.xxxx.com/privacy.aspx") .version("1.0") .contact(new Contact("xxx", "http://www.xxx.com", "xx@xxx.com")) .build(); } }
创建SignAspect
@Aspect @Component public class SignAspect { @Around("@annotation(你的项目目录.aspect文件夹.Sign)") public Object doAccessCheck(ProceedingJoinPoint pjp) throws Throwable { System.out.println("---start sign"); Sign aspect = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Sign.class); boolean verify = false; if (pjp.getArgs().length > 0 && aspect.type() == SignType.SIGN_MD5) { Object params = pjp.getArgs()[0]; JSONObject jsonParam = JSON.parseObject(params.toString()); String timeStamp = jsonParam.getString("timeStamp"); String[] value = aspect.value().split(","); String tmpValue = ""; JSONObject data = jsonParam.getJSONObject("data"); for (String val : value) { tmpValue += val + data.getString(val); } String md5keyapp = CommonKey.REDISKEY; String sign = jsonParam.getString("sign").toLowerCase(); String pjSign = MD5.getMD5(md5keyapp + timeStamp + tmpValue, 32).toLowerCase(); verify = pjSign.equals(sign); } if (verify) { Object object = pjp.proceed(); return object; } else { ResponseModel model = new ResponseModel(); model.setAPIState(APIState.KeysFail); return model; } } }
我的接口是post请求 参数是json //{"data":{"op":"get","key":"username"},"sign":"md5加密","timeStamp":1581992205704}
我使用了此类型的加密方式
创建 Sign
@Target(METHOD) @Retention(RUNTIME) @Documented public @interface Sign { String desc() default "开始校验签名..."; SignType type() default SignType.SIGN_MD5; String value() default ""; }
创建 SignType
public enum SignType { /** * MD5加密 */ SIGN_MD5; }
创建一个类
@RestController @RequestMapping("/redis") @Api(tags = "redisapi文档", hidden = true) public class managerHelper { //加密在这里面看一下 就能明白了 @ApiOperation(value = "redis操作接口 POST请求 JSON参数 op目前有5种操作 set,get,del,append,lset", notes = "默认参数 {"data":{"op":"get","key":"test5"},"sign":"md5加密","timeStamp":1581992205704}") @RequestMapping(value = "/opRedis", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") @Sign(value = "op,key") public @ResponseBody ResponseModel getRedis(@RequestBody JSONObject jsonParam) { ResponseModel model = new ResponseModel(); Jedis jedis = RedisUtil.getJedis(); try { //保留了set操作 String op = jsonParam.getJSONObject("data").getString("op"); String key = jsonParam.getJSONObject("data").getString("key"); if (op.equals("set")) { String value = jsonParam.getJSONObject("data").getJSONObject("value").toJSONString(); if (value != "" && value != null) { Integer expdatesec = jsonParam.getJSONObject("data").getInteger("expdatesec"); int secLong = 0; if(expdatesec==null){ expdatesec=0; } if (expdatesec > 0) { secLong = expdatesec; } else { int max = 14400, min = 7200;//最小2小时 最长4小时 secLong = (int) (Math.random() * (max - min) + min); } jedis.setex(key, secLong, value); model.setAPIState(APIState.Success); } else { model.setAPIState(APIState.NoMoreData); } } } catch (Exception ex) { model.setAPIState(APIState.Fail); } finally { RedisUtil.returnResource(jedis); } return model; } }
创建一个Redis类
public class RedisUtil { //服务器IP地址 private static String ADDR = "redisIP地址"; //端口 private static int PORT = 6379; //密码 private static String AUTH = "redis访问密码"; //连接实例的最大连接数 private static int MAX_ACTIVE = 1024; //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。 private static int MAX_IDLE = 200; //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException private static int MAX_WAIT = 10000; //连接超时的时间 private static int TIMEOUT = 10000; // 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的; private static boolean TEST_ON_BORROW = true; private static JedisPool jedisPool = null; //数据库模式是16个数据库 0~15 public static final int DEFAULT_DATABASE = 0; /** * 初始化Redis连接池 */ static { try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWaitMillis(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT,AUTH,DEFAULT_DATABASE); } catch (Exception e) { e.printStackTrace(); } } /** * 获取Jedis实例 */ public synchronized static Jedis getJedis() { try { if (jedisPool != null) { Jedis resource = jedisPool.getResource(); System.out.println("redis--服务正在运行: "+resource.ping()); return resource; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } /*** * * 释放资源 */ public static void returnResource(final Jedis jedis) { if(jedis != null) { jedis.close(); } } }
调用步骤 启动eureka 启动gateway 启动admin 启动redisapi 使用postman请求