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

"Advanced articles" docker Development user Service EdgeService (13)

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

Original articles, welcome to reprint. Reprint please indicate: reproduced from IT Story Association, thank you!

Original link address: "Advanced article" docker development user service EdgeService (13)

In the previous section, we developed the user service, which is about to develop the user service EdgeService. From this invocation relationship, we can see that the user's EdgeService is a service, the first choice is to invoke the user service, the basic operation of the user information, the invocation of the information service to send text messages, send e-mail, and the need to achieve login and registration functions. And login is a single sign-on EdgeService that supports other systems and supports course login. The requirements for him are stateless and require a centralized cache redis. The concentration of so many services in one shows that it is a very complex service, but it doesn't matter, we developed it from beginning to end. Source code: https://github.com/limingios/msA-docker

Create a new maven module user-edge-service

Pom file org.springframework.boot spring-boot-starter-parent 1.5.3.RELEASE 4.0.0 com.idig8 user-edge-service 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.apache that introduces user-thrift-service-api and message-thrift-service-api .thrift libthrift 0.10.0 com.idig8 user-thrift-service-api 1.0-SNAPSHOT com.idig8 message-thrift-service-api 1.0-SNAPSHOT org.springframework.boot spring-boot -starter-data-redis commons-lang commons-lang 2.6 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot RELEASE compile

Utility class for redis, for stateless storage, userInfo for token information storage

RedisConfigpackage com.idig8.user.redis

Import org.springframework.beans.factory.annotation.Value

Import org.springframework.cache.CacheManager

Import org.springframework.cache.annotation.CachingConfigurerSupport

Import org.springframework.cache.annotation.EnableCaching

Import org.springframework.context.annotation.Bean

Import org.springframework.context.annotation.Configuration

Import org.springframework.data.redis.cache.RedisCacheManager

Import org.springframework.data.redis.connection.RedisConnectionFactory

Import org.springframework.data.redis.connection.jedis.JedisConnectionFactory

Import org.springframework.data.redis.core.RedisTemplate

Import org.springframework.data.redis.core.StringRedisTemplate

Import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer

Import com.fasterxml.jackson.annotation.JsonAutoDetect

Import com.fasterxml.jackson.annotation.PropertyAccessor

Import com.fasterxml.jackson.databind.ObjectMapper

/ * *

Redis cache configuration class * /

@ Configurationbr/ > * /

@ Configuration

Public class RedisConfig extends CachingConfigurerSupport {

@ Value ("${spring.redis.host}")

Private String host;@Value ("${spring.redis.port}") br/ > @ Value ("${spring.redis.port}") br/ > @ Value ("${spring.redis.timeout}") br/ > @ Value ("${spring.redis.password}")

/ / Cache Manager @ Beanbr/ > @ Bean

RedisCacheManager cacheManager = new RedisCacheManager (redisTemplate)

/ / set cache expiration time

CacheManager.setDefaultExpiration (10000)

Return cacheManager

}

@ Bean

Public JedisConnectionFactory redisConnectionFactory () {

JedisConnectionFactory factory = new JedisConnectionFactory ()

Factory.setHostName (host)

Factory.setPort (port)

Factory.setTimeout (timeout)

Factory.setPassword (password)

Return factory

}

@ Bean

Public RedisTemplate redisTemplate (RedisConnectionFactory factory) {

StringRedisTemplate template = new StringRedisTemplate (factory)

SetSerializer (template); / / set the serialization tool

Template.afterPropertiesSet ()

Return template

}

Private void setSerializer (StringRedisTemplate template) {

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer (Object.class)

ObjectMapper om = new ObjectMapper ()

Om.setVisibility (PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)

Om.enableDefaultTyping (ObjectMapper.DefaultTyping.NON_FINAL)

Jackson2JsonRedisSerializer.setObjectMapper (om)

Template.setValueSerializer (jackson2JsonRedisSerializer)

}

}

RedisClient``javapackage com.idig8.user.redis;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/** * Created by liming * / @ Componentpublic class RedisClient {@ Autowired private RedisTemplate redisTemplate; public T get (String key) {return (T) redisTemplate.opsForValue () .get (key) } public void set (String key, Object value) {redisTemplate.opsForValue (). Set (key, value);} public void set (String key, Object value, int timeout) {redisTemplate.opsForValue (). Set (key, value, timeout, TimeUnit.SECONDS);} public void expire (String key, int timeout) {redisTemplate.expire (key, timeout, TimeUnit.SECONDS);}}

Response and LoginResponse return string uniformly

Response

Package com.idig8.user.response;import java.io.Serializable;/** * Created by liming * / public class Response implements Serializable {public static final Response USERNAME_PASSWORD_INVALID = new Response ("1001", "username or password invalid"); public static final Response MOBILE_OR_EMAIL_REQUIRED = new Response ("1002", "mobile or email is required"); public static final Response SEND_VERIFYCODE_FAILED = new Response ("1003", "send verify code failed") Public static final Response VERIFY_CODE_INVALID = new Response ("1004", "verifyCode invalid"); public static final Response SUCCESS = new Response (); private String code; private String message; public Response () {this.code = "0"; this.message = "success";} public Response (String code, String message) {this.code = code; this.message = message } public static Response exception (Exception e) {return new Response ("9999", e.getMessage ());} public String getCode () {return code;} public void setCode (String code) {this.code = code;} public String getMessage () {return message;} public void setMessage (String message) {this.message = message;}}

LoginResponse

Package com.idig8.user.response;/** * Created by liming * / public class LoginResponse extends Response {private String token; public LoginResponse (String token) {this.token = token;} public String getToken () {return token;} public void setToken (String token) {this.token = token;}}

Client access communicates over the same protocol as the server package com.idig8.user.thrift;import com.idig8.thrift.message.MessageService;import com.idig8.thrift.user.UserService;import org.apache.thrift.TServiceClient;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.protocol.TProtocol;import org.apache.thrift.transport.*;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component @ Componentpublic class ServiceProvider {@ Value ("${thrift.user.ip}") private String serverIp; @ Value ("${thrift.user.port}") private int serverPort; @ Value ("${thrift.message.ip}") private String messageServerIp; @ Value ("${thrift.message.port}") private int messageServerPort Private enum ServiceType {USER, MESSAGE} public UserService.Client getUserService () {return getService (serverIp, serverPort, ServiceType.USER);} public MessageService.Client getMessasgeService () {return getService (messageServerIp, messageServerPort, ServiceType.MESSAGE);} public T getService (String ip, int port, ServiceType serviceType) {TSocket socket = new TSocket (ip, port, 3000); TTransport transport = new TFramedTransport (socket) Try {transport.open ();} catch (TTransportException e) {e.printStackTrace (); return null;} TProtocol protocol = new TBinaryProtocol (transport); TServiceClient result = null; switch (serviceType) {case USER: result = new UserService.Client (protocol); break Case MESSAGE: result = new MessageService.Client (protocol); break;} return (T) result;}

Controller introduces thrift's service method and redis's operation tool class for redis operation.

Because userInfo is automatically upgraded through thrift, many of the methods are too troublesome for developers to view the data content. The best way to create an object is to automatically upgrade to userInfo into custom UserDTO,USerDTO. The best way is carried out in the project of thrift. If multiple projects, more convenient, a single user's edgeservice DTO, only his own use of the business is not clear.

Package com.idig8.user.controller;import com.idig8.thrift.user.UserInfo;import com.idig8.thrift.user.dto.UserDTO;import com.idig8.user.redis.RedisClient;import com.idig8.user.response.LoginResponse;import com.idig8.user.response.Response;import com.idig8.user.thrift.ServiceProvider;import org.apache.commons.lang.StringUtils;import org.apache.thrift.TException;import org.apache.tomcat.util.buf.HexUtils;import org.springframework.beans.BeanUtils;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.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import java.security.MessageDigest;import java.util.Random;@Controllerpublic class UserController {@ Autowired private ServiceProvider serviceProvider; @ Autowired private RedisClient redisClient RequestMapping (value = "/ login", method = RequestMethod.POST) @ ResponseBody public Response login (@ RequestParam ("username") String username, @ RequestParam ("password") String password) {/ / 1. Verify username password UserInfo userInfo = null; try {userInfo = serviceProvider.getUserService () .getUserByName (username);} catch (TException e) {e.printStackTrace (); return Response.USERNAME_PASSWORD_INVALID;} if (userInfo = = null) {return Response.USERNAME_PASSWORD_INVALID } if (! userInfo.getPassword (). EqualsIgnoreCase (md5 (password) {return Response.USERNAME_PASSWORD_INVALID;} / / 2. Generate token String token = genToken (); / / 3. Cache users / / because userInfo is automatically upgraded through thrift, many of the methods are too troublesome for developers to view data content / / the best way to create an object is to automatically upgrade to userInfo and convert it to custom UserDTO redisClient.set (token,toDTO (userInfo)); return new LoginResponse (token) } @ RequestMapping (value= "/ sendVerifyCode", method = RequestMethod.POST) @ ResponseBody public Response sendVerifyCode (@ RequestParam (value= "mobile", required = false) String mobile, @ RequestParam (value= "email", required = false) String email) {String message = "Verify code is:"; String code = randomCode ("0123456789", 6); try {boolean result = false If (StringUtils.isNotBlank (mobile)) {result = serviceProvider.getMessasgeService (). SendMobileMessage (mobile, message+code); redisClient.set (mobile, code);} else if (StringUtils.isNotBlank (email)) {result = serviceProvider.getMessasgeService (). SendEmailMessage (email, message+code); redisClient.set (email, code) } else {return Response.MOBILE_OR_EMAIL_REQUIRED;} if (! result) {return Response.SEND_VERIFYCODE_FAILED;}} catch (TException e) {e.printStackTrace (); return Response.exception (e);} return Response.SUCCESS } @ RequestMapping (value= "/ register", method = RequestMethod.POST) @ ResponseBody public Response register (@ RequestParam ("username") String username, @ RequestParam ("password") String password, @ RequestParam (value= "mobile", required = false) String mobile, @ RequestParam (value= "email", required = false) String email @ RequestParam ("verifyCode") String verifyCode) {if (StringUtils.isBlank (mobile) & & StringUtils.isBlank (email)) {return Response.MOBILE_OR_EMAIL_REQUIRED } if (StringUtils.isNotBlank (mobile)) {String redisCode = redisClient.get (mobile); if (! verifyCode.equals (redisCode)) {return Response.VERIFY_CODE_INVALID;}} else {String redisCode = redisClient.get (email) If (! verifyCode.equals (redisCode)) {return Response.VERIFY_CODE_INVALID;}} UserInfo userInfo = new UserInfo (); userInfo.setUsername (username); userInfo.setPassword (md5 (password)); userInfo.setMobile (mobile); userInfo.setEmail (email); try {serviceProvider.getUserService () .regiserUser (userInfo) } catch (TException e) {e.printStackTrace (); return Response.exception (e);} return Response.SUCCESS;} private UserDTO toDTO (UserInfo userInfo) {UserDTO userDTO = new UserDTO (); BeanUtils.copyProperties (userInfo, userDTO); return userDTO;} private String genToken () {return randomCode ("0123456789abcdefghijklmnopqrstuvwxyz", 32) } private String randomCode (String s, int size) {StringBuilder result = new StringBuilder (size); Random random = new Random (); for (int ipositani0) {sb.append (new String (temp,0,len));} UserDTO userDTO = new ObjectMapper (). ReadValue (sb.toString (), UserDTO.class); return userDTO } catch (IOException e) {e.printStackTrace ();} finally {if (inputStreamstreams null) {try {inputStream.close ();} catch (Exception e) {e.printStackTrace ();} return null } public void destroy () {}}

Functions that need to be implemented by introducing a single sign-on module

PS: in fact, by combing, it is found that there is still a set of ways to communicate in multiple languages. The code of the corresponding language is created, and then through the server and the client of rpc, they communicate with each other before the protocol. The server completes its own business logic, and the client gets the returned results.

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

Servers

Wechat

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

12
Report