您好,登錄后才能下訂單哦!
本篇內容介紹了“如何自定義guava cache存儲token”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
項目主要分為七大模塊:用戶模塊、商品模塊、訂單模塊、分類模塊、購物車模塊、收貨地址模塊以及支付模塊。
高復用的服務響應對應的設計思想和封裝
解決橫向越權和縱向越權的問題,用戶密碼使用MD5明文加密,guava緩存實現信息的存儲,用戶功能主要包括:注冊、登錄、檢測用戶名是否有效,密碼的重置,更新用戶信息等等...
當用戶忘記密碼需要重置密碼的時候,需要輸入注冊時設置的密碼提示問題和問題答案,比如:你的生日是什么時候? 1996-08-28,修改密碼的時候需要校驗密保問題和答案時候相一致,shopping-mall_v1.0的時候,我們采用guava cache來存儲一個forgetToken,比設置token的有效期為30分鐘(可根據項目場景選擇),在重置密碼的時候需要傳遞參數有:username,password,forgetToken三個參數,這時候需要判斷在guava獲取tokenCache里面的token和傳進來的forgetToken是否一致,滿足一致條件才能重置密碼成功!
public class TokenCache { //創建logback的logger private static Logger logger = LoggerFactory.getLogger(TokenCache.class); //生成token的前綴 public static final String TOKEN_PREFIX = "token_"; //聲明一個靜態的內存塊,guava里面的本地緩存 public static LoadingCache<String,String> localCache = //構建本地緩存,調用鏈的方式,initialCapacity是緩存的初始化容量, // maxSize是緩存設置的最大內存容量,expireAfterAccess設置緩存的有效期為12個小時 CacheBuilder.newBuilder() .initialCapacity(1000) .maximumSize(10000) .expireAfterAccess(12, TimeUnit.HOURS) //build里面要實現一個匿名內部類 .build((new CacheLoader<String, String>() { //這個方法是默認的數據加載實現,當get的時候,如果key沒有對應的值,就調用這個方法進行加載 @Override public String load(String key) throws Exception { //為什么要把return的null值寫成字符串,因為到時候用null去.equal的時候,會報空指針異常 return "null"; } })); //添加本地緩存 public static void setKey(String key,String value){ localCache.put(key,value); } //得到本地緩存 public static String getValue(String key){ String value =null; try { value = localCache.get(key); if ("null".equals(value)){ return null; } return value; }catch (ExecutionException e){ logger.error("獲取緩存getKey()方法錯誤",e); } return null; } }
POJO、VO抽象模型的設計,高效的分頁以及動態排序,使用FTP服務對接,富文本上傳商品圖片信息,商品模塊比較重要的就是商品的搜索以及動態排序和商品分頁,比如:根據關鍵字后臺進行模糊查詢,根據價格升序/降序排列,商品的分頁主要集成 pagehelper 分頁插件來完成,改分頁插件實現數據分頁相對高效,實用起來也比較簡單,我們只需要使用PageHelper.startPage(pageNum,pageSize) 即可實現
安全漏洞解決方案,考慮電商商品訂單號的生成規則,訂單狀態的分析和訂單枚舉常量的設計,訂單的超時關單處理(延時隊列)
創建訂單OrderVO類的封裝,封裝返回創建訂單的所有信息,包括:訂單信息,訂單明細信息(List<OrderItemVO>),地址信息,創建訂單時需要校驗購物車商品的狀態/數量,比如是否已下架,是否庫存不足,校驗成功才允許下單,下單成功之后需要減庫存操作,需要遍歷每一個訂單Item,通過orderItem的productId獲取到對應商品,執行product.getStock() - product.getQuantity();操作;
/** * orderNo生成方式 * * @return */ private long generateOrderNo() { //獲取當前時間戳 long currentTime = System.currentTimeMillis(); //時間+[0,1000)之間的數即[0,999] return currentTime + new Random().nextInt(1000); }
相關實現邏輯:首先先獲取前hour小時的訂單,查詢出這些訂單里面為付款的訂單,查詢到這些訂單之后,拿到即將關閉訂里的商品和數量,取消訂單時候庫存需要加上商品數量(也就是庫存還原),最后再設置訂單狀態。
@Override public void closeOrder(int hours) { //前hour小時的訂單 Date closeDateTime = DateUtils.addHours(new Date(), -hours); List<Order> orderList = orderMapper.selectOrderStatusByCreateTime(Constant.OrderStatusEnum.NO_PAY.getCode(), dateToStr(closeDateTime)); for (Order order : orderList) { List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(order.getOrderNo()); for (OrderItem orderItem : orderItemList) { //拿到即將要被關閉商品的和數量:一定要用主鍵where條件,防止鎖表,同時必須支持MySQL的InnoDB引擎 Integer stock = productMapper.selectStockByProductId(orderItem.getProductId()); //考慮到已生成訂單里的商品已被刪除,這時候就不必更新了 if (stock == null) { continue; } Product product = new Product(); product.setId(orderItem.getProductId()); product.setStock(stock + orderItem.getQuantity()); productMapper.updateByPrimaryKeySelective(product); } orderMapper.closeOrderByOrderId(order.getId()); log.info("關閉訂單orderNo:{}", order.getOrderNo()); } }
采用遞歸算法,復雜對象的排重,無限層級的樹狀結構的設計
獲取分類子節點(平級):當父及分類parentId傳0的時候,查找的是跟節點的子分類
獲取分類id及遞歸子節點分類id(返回本身以及它下面的子節點,假設0->10->100->1000,0的下一級子孩子節點為10,10的下一級節點為100,100的下一級節點為1000,業績是返回:0(本身)->10->100->100),設計到遞歸查詢算法,算法設計如下:
/** * 遞歸查詢本節點的id以及孩子節點的id邏輯實現 * * @param categoryId * @return */ @Override public ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId) { Set<Category> categorySet = Sets.newHashSet(); this.findChildCategoryRecursive(categorySet, categoryId); //最后是返回categoryId List<Integer> categoryIdList = Lists.newArrayList(); if (categoryId != null) { for (Category categoryItem : categorySet) { categoryIdList.add(categoryItem.getId()); } } return ServerResponse.createBySuccess(categoryIdList); } /** * 遞歸查詢算法,自己調自己,我們使用Set集合做返回,可以排重,這里要重寫Category的HashCode和equals * 的兩個方法為什么呢?當兩個對象相同,即equals返回true,則他們的hashCode一定相同,但是當兩個對象的 * hashCode相同,兩個對象不一定相同,所以,得出結論當使用Set集合的時候,注意要重寫equals和hashCode * 兩個方法。 */ private Set<Category> findChildCategoryRecursive(Set<Category> categorySet, Integer categoryId) { Category category = categoryMapper.selectByPrimaryKey(categoryId); if (category != null) { categorySet.add(category); } //遞歸算法,查找子節點 List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId); for (Category categoryItem : categoryList) { //自己調用自己 findChildCategoryRecursive(categorySet, categoryItem.getId()); } return categorySet; } //mapper <select id="selectCategoryChildrenByParentId" parameterType="int" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from tb_category where parent_id = #{parentId} </select>
購物車模塊核高復用的邏輯方法的封裝,商品總價的計算復用和封裝,使用BigDecimal類型解決商業運算丟失精度的問題,購物車的單選/反選,全選/全反選功能,一個購物車里面包括多個商品,添加購物車時需要校驗購買的每個商品數量是否超過庫存,超過庫存這時候,購買的數量不能設為用戶選擇的數量,而是選擇庫存數量,計算價格的時候也只能按照現有庫存數量乘以單價的方式計算總額。
數據綁定和對象綁定,越權問題的升級個鞏固,刪除地址的時候為了防止橫向越權我們不能只傳一個shippingId,因此不能世界使用mybatis生成的deleteByPrimaryKey()的方法來刪除,試想:當用戶處于登陸狀態的時候,如果只需要傳一個shippingId就能實現刪除的時候,那當傳的不是個人的shippingId就會產生越權問題,也就是所謂的橫向越權,為了防止橫向越權我們需要自定義一個方法將收獲地址和用戶綁定,比如:自定義deleteByUserIdAndShippingId()方法來實現。(地址的更新也是一樣的道理)
支付寶SDK源碼解析,分析了支付寶支付Demo的支付流程,將支付寶集成到項目中,包括:支付二維碼的生成,掃碼支付,支付的邏輯是:
第一步:查看訂單的支付狀態,如果order.getStatus()<=Constant.OrderStatusEnum.PAID.getCode()時,才滿足支付條件
第二步:支付,采用支付寶當面付,需要生成支付二維碼,其實這一步的關鍵就是創建掃描支付的請求biulder,通過builder來設置請求參數,首先會調用需下單的接口,判斷預下單是否生成,如果預下單成功之后,需要將訂單的狀態修改為已支付,接著下單成功之后,會返回支付二維碼,這是集成支付的比較關鍵的一步,我們需要做的就是保存這個支付二維碼并上傳到ftp服務器,最后返回一個二維碼訪問地址qrUrl給前端展示給用戶,用戶掃描對應的支付二維碼即可支付訂單,支付完成之后需要作支付寶回調處理,更新對應的訂單狀態為已支付,更新訂單的支付方式。
支付寶官方支付場景過程說明:
1. 用戶掃碼
2.調用alipay.trade.precreate()請求生成二維碼連接 -> 將二維碼連接轉二維碼圖片
3. 輸入支付密碼完成支付 -> 返回支付成功信息 -> 若支付成功,則返回異步信息(商戶返回success)
4.調用alipay.trade.query()查詢訂單狀態 -> 但會查詢結果 -> 若返回支付成功(code=10000),則流程結束
5.若未在指定時間內未完成支付 -> 調用alipay.trade.cancel進行交易關閉
“如何自定義guava cache存儲token”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。