Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case study of Redis+SpringBoot

2025-03-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "Redis+SpringBoot case study". In daily operation, I believe many people have doubts about Redis+SpringBoot case analysis. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubts of "Redis+SpringBoot case study". Next, please follow the editor to study!

Front-end technology stack: Vue-Cli

Front-end software: WebStorm 2020.3

Front-end style: Bootstrap

Back-end technology stack: SpringBoot

Back-end software: IntelliJ IEDA2019

JavaJDK:1.8

Server: Aliyun Centos 7

Other: MyBatis,Redis,MySql,Docker,Shiro

Project source code: shoppingProject01_pub: version6.0

Project reference: Project05; bad person _ Vue-Cli; bad person _ Redis; bad person _ Axios; still Silicon Valley _ Redis

Project functions:

1) Registration and login in mailbox:

After the user applies the mailbox to register and clicks to submit, the website will send the user an email with an activation code link, and the user clicks the link to realize the account activation portal.

2) sign in by SMS:

When the user registers with the mobile phone number, click the "get CAPTCHA" button, and the mobile phone will receive the SMS sent by the website with the CAPTCHA. Based on Redis, the CAPTCHA is valid for 5 minutes, and each mobile number can only get the SMS CAPTCHA transmission gate three times.

3) alipay payment:

By downloading the Android version of Alipay sandbox app users can scan the alipay code to buy goods on the site, the background MySql will record the order behavior portal, the web page is displayed as shown in figure 1.

Figure 1 Product display page

4) user rating:

When users scan the code to buy annual VIP members, all goods on the website are purchased at half price, and the background MySql records the changes in the user's role.

5) ranking of user points:

Users who buy goods will increase their own points, and the web page is shown in figure 2.

Figure 2 ranking display page

Big pits encountered in the project:

1) the local test of the mail sending function has passed, and the server side tests Bug frequently, so the solution.

2) after the server is deployed, the project cannot connect to the Redis on the server. Solution: (1) deploy Redis on the server instead of Docker; (2) change the Redis port to 7000; (3) release port 7000 of the server and Aliyun in the firewall active state; and (4) modify the Redis.conf file.

3) git uploads the local source code to gitee, and the misoperation causes the local source code to be overwritten by the old code on gitee, which is discovered the next day. Solution: because there is a jar package of source code on the server, half of your life is saved through the decompiler jd_gui. In addition, git upload file reference transfer gate.

1 Vue-Cli module description:

1.1 Overview of Vue-Cli:

1) characterized by the separation of front and rear ends and single-page web applications (SPA), Vue-Cli can create a Vue project with scaffolding specifications. The advantages of Vue-Cli are:

(1) the development based on the scaffolding specification will become very flexible.

(2) Vue-Cli is built based on webpack and has a reasonable default configuration, and the packaging tool webpack can aggregate single pages and various development components.

(3) Vue-Cli is a rich collection of official plug-ins that inherits the best tools in the front-end ecosystem.

2) installation process:

(1) install WebStorm (for development), install node.js, install vue-cli, install axios (for initiating cross-domain requests), and introduce bootstrap style.

3) deployment process:

Npm run build # executes on the WebStorm terminal and generates the dist folder docker pull nginx:1.19.10 # it is not recommended that the Vue-cli project be deployed to tomcat, because tomcat belongs to a dynamic server and requires a java environment to start, which is used to parse the dynamic language jsp; if it is purely static, it is deployed on the static server nginx. Mkdir html # to map data volumes inside and outside the docker container mv dist/ html/docker run-p 80:80-- name nginx01-d-v / root/html/dist/:/usr/share/nginx/html nginx:1.19.10 # data volume mapping # you can access http://120.79.133.235:80/index.html at this time

4) key points of Vue-Cli development:

(1) in WebStorm, the development process is mainly oriented to src files, as shown in figure 3:

Figure 3 WebStorm directory

[1] first master routing (router) and components (components [public component], views [private component]). Components are "pages". After the component is established, it needs to register with the route; [2] asserts encapsulates bootstrap style and is imported in main.js; [3] in order to send cross-domain requests, the axios instance is encapsulated in utils as follows:

Import axios from 'axios'// creates a default instance const instance = axios.create ({baseURL:' http://120.79.133.235:8989/eb', / / timeout: 10000,}); / / request interceptor instance.interceptors.request.use (config= > {console.log ("request interceptor"); return config;}) / / response interceptor instance.interceptors.response.use (response= > {console.log (response interceptor); return response) }, err= > {console.log ("interceptor entered in response to an error");}); / / expose instance instance object export default instance

In each component, the get and post request methods for the backend are as follows:

/ / Get request / / send the current page number to the backend interface to get the product Listinstance.get ("/ item/findAllItem?page=" + this.page) of the current page. Then (res= > {that.items = res.data.items; that.totalPage = res.data.totalPage; that.page = res.data.page;}) / / Post request / / send the current merchandise id and user id to the backend interface to get the purchase status instance.post ("/ order/alipay/callback", {itemId:this.itemid,userId:this.user.id}). Then (res= > {if (res.data.code = = 20000) {alert ("hint: you have purchased the item");} else {alert ("hint: you have not purchased the item") });}

[4] the methods of jumping and passing values between components are as follows:

/ / Jump to MailReg component this.$router.push ({name: "MailReg"}); / / Jump to item component and pass the idthis.$router.push of the current product ({path: "/ item", query: {ItemId:myid}}); / / item component receiving method: this.itemid = this.$route.query.ItemId;//. In addition, different components can obtain login user information based on token. Redis is required, as detailed below.

2 user points ranking module description:

1.1 Overview of Reids:

1) Redis is a memory-based data storage NoSql

2) Redis supports rich data types (String, List, Set, ZSet, Hash)

3) Redis has two persistence methods: (1) snapshot (snapshot) storage, also known as rdb persistence, to save the current data state; (2) AOF (append only file) storage, all redis write commands are recorded in the log file. Redis supports persistence interval of one second at the fastest, so it is transaction insecure, that is, data may be lost.

4) Application scenarios of Redis:

The main contents are as follows: (1) using Redis string to realize the storage of mobile CAPTCHA in the project. -this project adopts

(2) use Redis string type to complete timely business functions, such as orders will be closed in 40 minutes.

(3) using Redis to realize Session sharing in distributed cluster system.

(4) realize the ranking function by using the ZSet data type of Redis (sortable set type: element + score). -this project adopts

(5) using Redis to complete distributed cache. -this project implements data caching in MySql

(6) using Redis to store token information after authentication. -very convenient, adopted in this project.

(7) using Redis to solve the problem of distributed lock in distributed cluster system.

1.2 implement the front-end component to obtain user information from the back-end based on Redis:

Step1: the API for user input login information submission in the frontend Login.vue component is as follows:

/ / the backend / user/login interface is called here to obtain the token of the currently logged in user and store it in the localStorage of Session. The tokeninstance.post ("/ user/login", this.user) .then (res= > {if (res.data.state) {alert (res.data.msg+ ", click OK to enter the home page") can be accessed at any time during subsequent web browsing. / / the front end stores token information localStorage.setItem ("token", res.data.token); that.$router.push ({path: "/ itemList"});} else {alert (res.data.msg); that.user = {};}})

Step2: the backend / user/login interface is implemented as follows:

/ / Controller layer @ PostMapping ("login") public Map loginAccount (@ RequestBody User user, HttpSession session) {return userService.loginAccount (user, session);} / / Service layer / / case 3: get the principal object try {Subject subject = SecurityUtils.getSubject () when a user is queried; subject.login (new UsernamePasswordToken (user.getName (), user.getPassword (); User userDB = userListDB.get (0); String token = session.getId () If (userDB.getScore () = = null) {userDB.setScore (0.0); userDAO.updateUserScore (userDB);} redisTemplate.opsForValue (). Set ("TOKEN_" + token, userDB, 30, TimeUnit.MINUTES); redisTemplate.opsForZSet (). Add ("userRank", userDB, userDB.getScore ()); map.put ("token", token); map.put ("state", true) Map.put ("msg", "login successful"); return map;...

There are two kinds of Template for Redis integration SpringBoot, namely RedisTemplate and StringRedisTemplate. StringRedisTemplate is a subclass of RedisTemplate, and the two methods are basically the same, except that the two generics in RedisTemplate are of different data types. Both generics in RedisTemplate are Object, which means that both key and value stored can be an object, while both generics of StringRedisTemplate are String, which means that both key and value of StringRedisTemplate can only be strings.

In Step2, I bind token to the user information userDB in the database and store them in Redis. The following code is used for the following front-end components to obtain login user information:

/ / get tokenlet token= localStorage.getItem from localStorage ("token"); let that = this;// send an axios request to obtain user information instance.get ("/ user/token?token=" + token) according to token. Then (res= > {that.user = res.data;console.log (that.user);})

The interfaces of backend / user/token are as follows:

@ GetMapping ({"token"}) public User findUser (String token) {System.out.println ("received token message:" + token); return (User) redisTemplate.opsForValue () .get ("TOKEN_" + token);}

Step3: when a user logs out and logs in, the corresponding token in the browser should be eliminated. The backend API code is as follows:

/ / log in to @ DeleteMapping ({"logout"}) public Map logout (String token) {Map map = new HashMap (); try {redisTemplate.delete ("TOKEN_" + token); Subject subject = SecurityUtils.getSubject (); subject.logout (); map.put ("state", true) Map.put ("msg", "prompt: exit account successfully"); return map;} catch (Exception e) {e.printStackTrace (); map.put ("state", false); map.put ("msg", "prompt: exit account failed"); return map;}}

1.3 implementation of user score ranking based on Redis:

The user information in MySql is shown in figure 4:

Figure 4 user information in MySql

The UserRank in Redis is shown in figure 5:

Figure 5 UserRank in Redis

Step1: when a user logs in, his first task is to access the information corresponding to UserRank. The backend code is as follows:

If (userDB.getScore () = = null) {userDB.setScore (0.0); userDAO.updateUserScore (userDB);} redisTemplate.opsForValue () .set ("TOKEN_" + token, userDB, 30, TimeUnit.MINUTES); redisTemplate.opsForZSet () .add ("userRank", userDB, userDB.getScore ())

UserDB is the information of the currently logged-in user in the database (there must be some, you signed up, right? If a user logs in for the first time, I set his score to 0.0 in the database, and then I add this user to Redis's ZSet, you know, the Set collection does not store elements with duplicate key values, so the same user will not appear in UserRank twice. The two template complete the process of binding the token User,User to the Score in the UserRank, and the subsequent score update process repeatedly uses these two template implementations.

Step2: when the user information is updated, the corresponding two template related to the user information will change. The code is as follows:

/ / key value serializes redisTemplate.setKeySerializer (new StringRedisSerializer ()); / / current user's information is obtained by current user's token User firstUser = (User) redisTemplate.opsForValue () .get ("TOKEN_" + token); / / delete current user redisTemplate.opsForZSet (). Remove ("userRank", firstUser) in zSet; / / generate new current user (nickname change) List userListDB = this.userDAO.selectUserByName (user.getName ()); User secondUser = userListDB.get (0) / / update the information of the current user in token redisTemplate.opsForValue (). Set ("TOKEN_" + token, secondUser, 30, TimeUnit.MINUTES); / / generate the current user in zSet redisTemplate.opsForZSet (). Add ("userRank", secondUser, secondUser.getScore ())

Step3: when you scan the code to pay, the backend controller that you enter for the first time is as follows:

/ pay for single item @ GetMapping ("payForItem") public byte [] alipay (String itemid,String userid, String token) {this.token = token; log.info ("itemid= >" + itemid); log.info ("userid= >" + userid); PayVo payVo = new PayVo (); payVo.setItemId (itemid); payVo.setUserId (userid); System.out.println (payVo.getUserId ()) Return alipayService.alipay (payVo);}

There is a small user rating in alipayService, that is, the purchase price of vip users is halved:

/ / 1: the paid user String userId = payVo.getUserId (); / / my 1: query the user User user = userService.selectUserById (Integer.valueOf (userId)) based on the user id; / / query the commodity Item item = itemService.getItemById (payVo.getItemId ()) based on the commodity id / / my 1: query user if (item = = null) return null; / / 2 based on user id: payment amount String tempMoney = item.getPrice (). ToString (); String money = ""; if (user.getRole (). Equals ("normal")) {money = tempMoney } if (user.getRole (). Equals ("vip")) {Double tempMoney2 = Double.valueOf (tempMoney) * 0.5; money = String.valueOf (tempMoney2);}

Under the same payForItem file, payCommonService is called, where the user credit update and user level update are implemented:

PayCommonService.payUserPublic (bodyJsonObject, userId, user.getName (), orderNumber, tradeno, "alipay", this.token)

Set the id of the item "VIP" to "666". When the user buys the product, the current user update process is as follows:

If (itemId.equals ("666")) {int myuserId = Integer.valueOf (userId); User userDB = userService.selectUserById (myuserId); / / key value serialization this.redisTemplate.setKeySerializer (new StringRedisSerializer ()); / / current user information User firstUser = (User) redisTemplate.opsForValue (). Get ("TOKEN_" + token) / / delete the current user zSet redisTemplate.opsForZSet () .remove ("userRank", firstUser) from the current user information; / / update the current user information identity userDB.setRole ("vip"); / / update the current user's new identity score userService.updateUserRole (userDB) List userListDB = this.userDAO.selectUserByName (userDB.getName ()); / / get the complete information of the current new identity user User secondUser = userListDB.get (0); / / update the current user corresponding to the current token redisTemplate.opsForValue () .set ("TOKEN_" + token, secondUser, 30, TimeUnit.MINUTES) / / set the current user's zSet redisTemplate.opsForZSet () .add ("userRank", secondUser, secondUser.getScore () .doubleValue ());}

The current update process for user credits is as follows:

/ / update current user's score double tempScore = Double.valueOf (orderDetail.getPrice ()) * 0.3; String key1 = "TOKEN_" + token; / / get current user User user = (User) redisTemplate.opsForValue (). Get (key1); / / update current user's zSet score redisTemplate.opsForZSet (). IncrementScore ("userRank", user, tempScore) / / get the zSet score of the current user double newScore = redisTemplate.opsForZSet () .score ("userRank", user); / / delete the zSet of the current user (synchronize the score of the current user in the database to update the information of the current user) redisTemplate.opsForZSet () .remove ("userRank", new Object [] {user}); user.setScore (newScore) UserDAO.updateUserScore (user); / / update the information of the current user corresponding to token redisTemplate.opsForValue (). Set (key1, user); / / add the current user's zSet redisTemplate.opsForZSet (). Add ("userRank", user, newScore); at this point, the study of "Redis+SpringBoot case study" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report