本文共 12341 字,大约阅读时间需要 41 分钟。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here
package com.learn.controller;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.learn.entity.OrderEntity;import com.learn.ext.ExtApiIdempotent;import com.learn.ext.ExtApiToken;import com.learn.mapper.OrderMapper;import com.learn.utils.ConstantUtils;@Controllerpublic class OrderPageController { @Autowired private OrderMapper orderMapper; @RequestMapping("/indexPage") @ExtApiToken public String indexPage(HttpServletRequest req) { return "indexPage"; } @RequestMapping("/addOrderPage") @ExtApiIdempotent(type = ConstantUtils.EXTAPIFORM) @ResponseBody public MapaddOrder(OrderEntity orderEntity) { Map map = new HashMap (); int addOrder = orderMapper.addOrder(orderEntity); String msg = addOrder > 0 ? "success" : "fail"; map.put("msg", msg); return map; }}
package com.learn.controller;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.learn.entity.OrderEntity;import com.learn.ext.ExtApiIdempotent;import com.learn.mapper.OrderMapper;import com.learn.utils.ConstantUtils;import com.learn.utils.RedisToken;@RestControllerpublic class OrderController { @Autowired private OrderMapper orderMapper; @Autowired private RedisToken redisToken; // @Autowired // private RedisTokenUtils redisTokenUtils; // // 从redis中获取Token @RequestMapping("/redisToken") public String RedisToken() { return redisToken.getToken(); }// @RequestMapping(value = "/addOrderExtApiIdempotent", produces ="application/json; charset=utf-8")// @ExtApiIdempotent(type = ConstantUtils.EXTAPIHEAD)// public MapaddOrder(@RequestBody OrderEntity orderEntity, HttpServletRequest request) {// Map map = new HashMap ();// // 代码步骤:// // 1.获取令牌 存放在请求头中// String token = request.getHeader("token");// String msg = null;// if (StringUtils.isEmpty(token)) {// msg = "参数错误!";// map.put("msg", msg);// return map;// }// // 3.接口获取对应的令牌,如果能够获取该(从redis获取令牌)令牌(将当前令牌删除掉) 就直接执行该访问的业务逻辑// boolean isToken = redisToken.findToken(token);// // 4.接口获取对应的令牌,如果获取不到该令牌 直接返回请勿重复提交// if (!isToken) {// msg = "请勿重复提交!";// map.put("msg", msg);// return map;// }// int result = orderMapper.addOrder(orderEntity);// msg = result > 0 ? "添加成功" : "添加失败" + "";// map.put("msg", msg);// return map;// } @RequestMapping(value = "/addOrderExtApiIdempotent", produces = "application/json; charset=utf-8") @ExtApiIdempotent(type = ConstantUtils.EXTAPIHEAD) public Map addOrderExtApiIdempotent(@RequestBody OrderEntity orderEntity, HttpServletRequest request) { Map map = new HashMap (); int result = orderMapper.addOrder(orderEntity); String msg = null; msg = result > 0 ? "添加成功" : "添加失败" + ""; map.put("msg", msg); return map; }}
package com.learn.aop;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.StringUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.learn.ext.ExtApiIdempotent;import com.learn.ext.ExtApiToken;import com.learn.utils.ConstantUtils;import com.learn.utils.RedisToken;@Aspect@Componentpublic class ExtApiAopIdempotent { @Autowired private RedisToken redisToken; // 1.使用AOP环绕通知拦截所有访问(controller) @Pointcut("execution(public * com.learn.controller.*.*(..))") public void rlAop() { } // 前置通知 @Before("rlAop()") public void before(JoinPoint point) { MethodSignature signature = (MethodSignature) point.getSignature(); ExtApiToken extApiToken = signature.getMethod().getDeclaredAnnotation(ExtApiToken.class); if (extApiToken != null) { // 可以放入到AOP代码 前置通知 getRequest().setAttribute("token", redisToken.getToken()); } } // 环绕通知 @Around("rlAop()") public Object doBefore(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { // 2.判断方法上是否有加ExtApiIdempotent MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); ExtApiIdempotent declaredAnnotation = methodSignature.getMethod().getDeclaredAnnotation(ExtApiIdempotent.class); // 3.如何方法上有加上ExtApiIdempotent if (declaredAnnotation != null) { String type = declaredAnnotation.type(); // 如何使用Token 解决幂等性 // 步骤: String token = null; HttpServletRequest request = getRequest(); if (type.equals(ConstantUtils.EXTAPIHEAD)) { token = request.getHeader("token"); } else { token = request.getParameter("token"); } Mapmap = new HashMap (); String msg = null; if (StringUtils.isEmpty(token)) { msg = "参数错误!"; map.put("msg", msg); return map; } // 3.接口获取对应的令牌,如果能够获取该(从redis获取令牌)令牌(将当前令牌删除掉) 就直接执行该访问的业务逻辑 boolean isToken = redisToken.findToken(token); // 4.接口获取对应的令牌,如果获取不到该令牌 直接返回请勿重复提交 if (!isToken) { msg = "请勿重复提交!"; map.put("msg", msg); return map; } } // 放行 Object proceed = proceedingJoinPoint.proceed(); return proceed; } public HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); return request; } public void response(String msg) throws IOException { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletResponse response = attributes.getResponse(); response.setHeader("Content-type", "text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); try { writer.println(msg); } catch (Exception e) { } finally { writer.close(); } }}
package com.learn.ext;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;// 执行该请求的时候 需要生成令牌 转发到页面进行展示@Target(value = ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface ExtApiToken {}
package com.learn.utils;public interface ConstantUtils { static final String EXTAPIHEAD = "head"; static final String EXTAPIFORM = "form";}
package com.learn.utils;import java.util.UUID;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;// 如何生成token@Componentpublic class RedisToken { @Autowired private BaseRedisService baseRedisService; private static final long TOKENTIMEOUT = 60 * 60; public String getToken() { // 生成token 规则保证 临时且唯一 不支持分布式场景 分布式全局ID生成规则 String token = "token" + UUID.randomUUID(); // 如何保证token临时 (缓存)使用redis 实现缓存 baseRedisService.setString(token, token, TOKENTIMEOUT); return token; } // 1.在调用接口之前生成对应的令牌(Token), 存放在Redis // 2.调用接口的时候,将该令牌放入的请求头中 // 3.接口获取对应的令牌,如果能够获取该令牌(将当前令牌删除掉) 就直接执行该访问的业务逻辑 // 4.接口获取对应的令牌,如果获取不到该令牌 直接返回请勿重复提交 public synchronized boolean findToken(String tokenKey) { // 3.接口获取对应的令牌,如果能够获取该(从redis获取令牌)令牌(将当前令牌删除掉) 就直接执行该访问的业务逻辑 String tokenValue = (String) baseRedisService.getString(tokenKey); if (StringUtils.isEmpty(tokenValue)) { return false; } // 保证每个接口对应的token 只能访问一次,保证接口幂等性问题 baseRedisService.delKey(tokenValue); return true; }}
package com.learn.utils;import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Component;@Componentpublic class BaseRedisService { @Autowired private StringRedisTemplate stringRedisTemplate; public void setString(String key, Object data, Long timeout) { if (data instanceof String) { String value = (String) data; stringRedisTemplate.opsForValue().set(key, value); } if (timeout != null) { stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS); } } public Object getString(String key) { return stringRedisTemplate.opsForValue().get(key); } public void delKey(String key) { stringRedisTemplate.delete(key); }}
package com.learn.mapper;import org.apache.ibatis.annotations.Insert;import com.learn.entity.OrderEntity;public interface OrderMapper { @Insert("insert order_info values (null,#{orderName},#{orderDes})") public int addOrder(OrderEntity OrderEntity);}
spring.mvc.view.prefix=/WEB-INF/jsp/spring.mvc.view.suffix=.jspspring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.jdbc.Driver###########################################################Redis (RedisConfiguration)########################################################spring.redis.database=0spring.redis.host=localhostspring.redis.port=6379spring.redis.password=123456spring.redis.pool.max-idle=8spring.redis.pool.min-idle=0spring.redis.pool.max-active=8spring.redis.pool.max-wait=-1spring.redis.timeout=5000
package com;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;@MapperScan(basePackages = { "com.learn.mapper" })@SpringBootApplication@ServletComponentScanpublic class AppB { public static void main(String[] args) { SpringApplication.run(AppB.class, args); }}
4.0.0 com.learn springboot-web2 0.0.1-SNAPSHOT war org.springframework.boot spring-boot-starter-parent 1.5.12.RELEASE org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 mysql mysql-connector-java org.projectlombok lombok org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.apache.tomcat.embed tomcat-embed-jasper org.springframework.boot spring-boot-starter-log4j 1.3.8.RELEASE org.springframework.boot spring-boot-starter-aop commons-lang commons-lang 2.6 org.apache.httpcomponents httpclient com.alibaba fastjson 1.2.47 org.springframework.boot spring-boot-starter-data-redis javax.servlet jstl taglibs standard 1.1.2
转载地址:http://tbkzb.baihongyu.com/