多商家入驻前后端分离商城源码 Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c之java版微信小程序

 @源码地址来源: https://minglisoft.cn/honghu2/business.html


微信小程序登录代码:

/**
 * Copyright &copy; 2012-2017 <a href="http://minglisoft.cn">HongHu</a> All rights reserved.
 */
package com.honghu.cloud.controller;
 
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
 
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
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.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import com.auth0.jwt.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.google.common.collect.Maps;
import com.honghu.cloud.bean.User;
import com.honghu.cloud.code.ResponseCode;
import com.honghu.cloud.constant.Globals;
import com.honghu.cloud.dto.AccessoryDto;
import com.honghu.cloud.dto.PaymentDto;
import com.honghu.cloud.dto.StoreDto;
import com.honghu.cloud.dto.SysConfigDto;
import com.honghu.cloud.dto.UserDto;
import com.honghu.cloud.feign.AccessoryFeignClient;
import com.honghu.cloud.feign.DistributionUserFeignClient;
import com.honghu.cloud.feign.FtpFileFeignClient;
import com.honghu.cloud.feign.PaymentFeignClient;
import com.honghu.cloud.feign.StoreFeignClient;
import com.honghu.cloud.feign.SysConfigFeignClient;
import com.honghu.cloud.feign.TencentIMFeignClient;
import com.honghu.cloud.redis.RedisUtil;
import com.honghu.cloud.service.IUserService;
import com.honghu.cloud.tools.SecurityUserHolder;
import com.honghu.cloud.tools.wx.WXCore;
import com.honghu.cloud.utils.CommUtil;
import com.honghu.cloud.utils.Exceptions;
import com.honghu.cloud.utils.HttpClientUtils;
import com.honghu.cloud.utils.JWT;
import com.honghu.cloud.utils.tools.Md5Encrypt;
 
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
 
/**
 * 微信小程序登录Controller
 * @author Administrator
 *
 */
@Slf4j
@RestController
@RequestMapping(value = "/weChat")
public class WeChatLoginController  {
 
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SysConfigFeignClient sysConfigFeignClient;
    @Autowired
    private DistributionUserFeignClient disUserFeignClient;
    @Autowired
    private FtpFileFeignClient ftpFileFeignClient;
    @Autowired
    private TencentIMFeignClient tencentIMFeignClient;
    @Autowired
    private StoreFeignClient storeFeignClient;
    @Autowired
    private PaymentFeignClient paymentFeignClient;
/*    @Autowired
    private AccessoryFeignClient accessoryFeignClient;*/
    
    private static final Logger logger = LoggerFactory.getLogger(WeChatLoginController.class);
    
    /***微信获取登录凭证url***/
    private static final String CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
    
    /**
     * 小程序登录
     * @param js_code 登录code
     * @param iv  加密算法的初始向量
     * @param encryptedData 敏感用户数据
     * @param share_uid 邀请注册用户
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public  Map<String, Object>  login(@RequestBody JSONObject json) {
        String js_code = json.optString("js_code");
        String iv = json.optString("iv");
        String encryptedData = json.optString("encryptedData");
        String share_uid = json.optString("share_uid");
        String source_type = json.optString("source_type");
        String nickName = json.optString("nickName");
        String userphoto = json.optString("photo");
        /*SysConfigDto sysConfigDto = sysConfigFeignClient.getSysConfig();
        String appid = sysConfigDto.getOpen_weixin_appId(); 
        String secret = sysConfigDto.getOpen_weixin_appSecret();*/ 
        // 微信APPID、微信密匙
        Map<String, Object> param = Maps.newHashMap();
        param.put("mark", "wx_miniprogram");
        List<PaymentDto> payments = paymentFeignClient.queryPageList(param);
        PaymentDto payment =null;
        if (payments.size() > 0) {
             payment = (PaymentDto) payments.get(0);
        }
        if (payment==null||StringUtils.isEmpty(payment.getWx_appid()) || StringUtils.isEmpty(payment.getWx_appSecret())) {
            return ResponseCode.buildCodeMap("40031", "获取微信配置信息有误!", null);
        }
        Map<String,String> params = new HashMap<String, String>();
        params.put("appid", payment.getWx_appid());
        params.put("secret", payment.getWx_appSecret());
        params.put("js_code", js_code);
        params.put("grant_type", "authorization_code");
        String jsonStr = HttpClientUtils.doGet(CODE2SESSION_URL, params, "UTF-8");
        JSONObject jsonObj = JSONObject.fromObject(jsonStr);
        
        // 错误码
        String errcode = jsonObj.optString("errcode");
        if(StringUtils.equals(errcode, "40028")){ // code 无效
            return ResponseCode.buildCodeMap("40028", "code 无效!", null);
        }
        
        // errcode[-1:系统繁忙,此时请开发者稍候再试;45011:频率限制,每个用户每分钟100次]
        if(StringUtils.equals(errcode, "45011") || StringUtils.equals(errcode, "-1")){
            return ResponseCode.buildCodeMap("45011", "系统繁忙,请稍后再试!", null);
        }
        
        String session_key = jsonObj.optString("session_key");
        String openid = jsonObj.optString("openid");
        // 会话密钥和用户唯一标识为空,表示服务请求失败,记录日志
        if(StringUtils.isEmpty(session_key) || StringUtils.isEmpty(openid)){
            return ResponseCode.buildCodeMap("40029", "code无效!", null);
        }
        
        // 解析小程序加密用户数据
        String userInfo = WXCore.decrypt(payment.getWx_appid(), encryptedData, session_key, iv);
        if(StringUtils.isEmpty(userInfo)){
            return ResponseCode.buildCodeMap("40030", "获取用户数据失败!", null);
        }
        JSONObject userJson = JSONObject.fromObject(userInfo);
        // 开放平台的唯一标识符
        String unionid = userJson.optString("unionId");
        if(StringUtils.isEmpty(unionid)){
            return ResponseCode.buildCodeMap("40032", "获取用户数据失败!", null);
        }
        
        boolean phone=false;
        User user=null;
        boolean flag = false;   //true 则不需要授权手机号
        // 根据开放平台的唯一标识签,查询用户对象是否存在,不存在注册一条数据
        synchronized (this) {
            user = userService.selectByUnionid(unionid);
            if(user !=  null && user.getSecurity() == 1){
                return ResponseCode.buildCodeMap("40031", "账户存在安全隐患禁止登录!", null);
             }
            if (user!=null&&user.getUsername()!=null&&StringUtils.isNotBlank(user.getMobile())) {
                phone=true;
            }
            if(user == null){
                flag = true;
                user = new User();
                user.setOpenId(openid);
                if (StringUtils.isNotEmpty(nickName)) {
                    user.setNickName(nickName);
                }else{
                    user.setNickName(userJson.optString("nickName"));  //微信提供的默认头像
                }
                user.setWeixin_unionID(unionid);
                user.setDay_msg_count(0); 
                user.setDeleteStatus(0);
                user.setAddTime(new Date());
                user.setPassword(Md5Encrypt.md5("123456").toLowerCase());//设置默认密码为123456
                user.setYears(0); // 用户年龄
                user.setIs_live(0);
                user.setLive_code(userService.selectMaxLiveCode() + 1);
                user.setUser_type(0); // 用户类别,默认为0个人用户,1为企业用户
                user.setStore_apply_step(0); // 店铺申请进行的步骤,默认为0
                user.setInvoiceType(0); // 发票类型
                user.setWhether_attention(1); //是否允许关注 0为不允许,1为允许
                user.setUser_form("miniProgram"); //注册来源,分为pc,android,ios,miniProgram, WXOffiaccount
                if (StringUtils.isNotEmpty(source_type)) {
                    user.setSource_type(CommUtil.null2Int(source_type));    //1为海报
                }
                userService.saveEntity(user);
                user = userService.selectByUnionid(unionid);
            }else if(StringUtils.equals(user.getUser_form(), "WXOffiaccount") && StringUtils.isBlank(user.getOpenId())){  //通过微信公众号注册的
                user.setOpenId(openid);
                userService.updateById(user);
                flag = true;   //微信注册第一次进来分销关系重新建立
            }
        }
        
        boolean isUpdate=false;
        // 处理用户头像(用户头像不存在,将微信的头像保存到用户头像)
        //String photo_url = userJson.optString("avatarUrl");
        if(user.getPhoto_id() == null && StringUtils.isNotEmpty(userphoto)){
            AccessoryDto photo = uploadPhotoFile(userphoto, user.getId());
            if(photo != null){
                user.setPhoto(photo);
                user.setPhoto_id(photo.getId());
                isUpdate=true;
            }
        }
        //用户换名称或头像
        if(user.getNickName()==null){
            user.setNickName(nickName);
            isUpdate=true;
        }
        if (user.getLive_code()==null) {
            user.setLive_code(userService.selectMaxLiveCode() + 1);
            isUpdate=true;
        }
        if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(user.getNickName())) {
            user.setNickName(nickName);
            isUpdate = true;
        }
        if (StringUtils.isEmpty(user.getOpenId())) {
            user.setOpenId(openid);
            isUpdate = true;
        }
        if (isUpdate) {
            userService.updateById(user);
        }
        //所有用户都是分销用户
        if(flag){
            userService.saveDisUser(user, share_uid);
        }
        // 生成token,格式:用户id;时间戳  
        String token = JWT.sign(user.getId() + ";" + System.currentTimeMillis()+";"+"small", 0);
        // 将token存到redis中,有效期24小时 
        redisUtil.set(Globals.WECHAT_LOGIN_MARK + user.getId(), token, Globals.USER_INFO_EXPIRE_TIME);
        
        // 覆盖redis用户信息
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        redisUtil.set(Globals.USER_INFO_MARK + user.getId(), userDto, Globals.USER_INFO_EXPIRE_TIME);
        
        String storestatus="";
        if (userDto.getStore_id()!=null) {
            StoreDto storeDto = storeFeignClient.selectByPrimaryKey(userDto.getStore_id());
            if (storeDto!=null) {
                storestatus=storeDto.getStore_status()+"";
            }
        }
        HashMap<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("storestatus", storestatus);
        SysConfigDto sysConfig = sysConfigFeignClient.getSysConfig();
        if (sysConfig.getOpen_live()==0) {
            result.put("phone", true);
        }else{
            result.put("phone", phone);
        }
        
        result.put("session_key", session_key);
        result.put("user", user);
        
        if (user != null&&user.getIs_live()!=null) {
            result.put("is_live", user.getIs_live()==2?true:false);
        }else{
            result.put("is_live", false);
        }
        return ResponseCode.buildSuccessMap(result);
    }
    
    
    /**
     * 保存用户手机号
     * @return
     */
    @RequestMapping(value = "/savePhone", method = RequestMethod.POST)
    public Map<String, Object> savePhone(HttpServletRequest request, @RequestBody JSONObject json) {
        String session_key = json.optString("session_key");
        String iv = json.optString("iv");
        String encryptedData = json.optString("encrypData");
 
        if (StringUtils.isBlank(session_key)) {
            return ResponseCode.buildFailMap("获取失败,session_key信息错误", null);
 
        }
        if (StringUtils.isBlank(iv)) {
            return ResponseCode.buildFailMap("获取失败,iv信息错误", null);
            
        }
        if (StringUtils.isBlank(encryptedData)) {
            return ResponseCode.buildFailMap("获取失败,encryptedData信息错误", null);
            
        }
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(session_key);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
 
                JSONObject fromObject = JSONObject.fromObject(result);
                Object object = fromObject.get("purePhoneNumber");
                User user = userService.selectByPrimaryKey(SecurityUserHolder.getCurrentUserId(request));
                //查询是否已经存在该手机号
                User UserName = userService.selectByUserName(CommUtil.null2String(object));
                
                //需要合并用户    ,          手机号存在, 并且 unionid 为空     
                if (UserName!=null&&StringUtils.isEmpty(UserName.getWeixin_unionID())) {
                    
                    UserName.setWeixin_unionID(user.getWeixin_unionID());    //将新unionid 存入旧数据中
                    if (UserName.getLive_code()==null) {
                        UserName.setLive_code(userService.selectMaxLiveCode() + 1);
                    }
                    if (StringUtils.isEmpty(UserName.getNickName())) {
                        UserName.setNickName(user.getNickName());
                    }
                    if (user.getPhoto_id()!=null) {
                        UserName.setPhoto_id(user.getPhoto_id());
                    }
                    if (user.getOpenId()!=null) {
                        UserName.setOpenId(user.getOpenId());
                    }
                    if (user.getWx_open_id()!=null) {
                        UserName.setWx_open_id(user.getWx_open_id());;
                    }
                    userService.updateById(UserName);
                    user.setDeleteStatus(1);
                    user.setMobile("del"+CommUtil.null2String(object));
                    user.setUserName("del"+CommUtil.null2String(object));
                    user.setWeixin_unionID("del"+UserName.getId()+"");
                    userService.updateById(user);
                    disUserFeignClient.deleteByUserId(user.getId());   //删除新的 分销关系表
                    redisUtil.remove(Globals.WECHAT_LOGIN_MARK + user.getId());
                    //换用户登录
                    // 生成token,格式:用户id;时间戳  
                    String token = JWT.sign(UserName.getId() + ";" + System.currentTimeMillis()+";"+"small", 0);
                    // 将token存到redis中,有效期24小时 
                    redisUtil.set(Globals.WECHAT_LOGIN_MARK + UserName.getId(), token, Globals.USER_INFO_EXPIRE_TIME);
                    
                    // 覆盖redis用户信息
                    UserDto userDto = new UserDto();
                    BeanUtils.copyProperties(UserName, userDto);
                    redisUtil.set(Globals.USER_INFO_MARK + UserName.getId(), userDto, Globals.USER_INFO_EXPIRE_TIME);
                    return ResponseCode.buildSuccessMap(token);
                    
                }
                //删除
                
                
                /*//手机号跟原来一致, 直接通过
                if (CommUtil.null2String(object).equals(user.getUserName())) {
                    return ResponseCode.buildSuccessMap("isOk");
                }*/
                //手机号已存在
                if (UserName!=null) {
                    return ResponseCode.buildFailMap("手机号已存在", "false");
                }
                user.setUserName(CommUtil.null2String(object));
                user.setMobile(CommUtil.null2String(object));
                userService.updateById(user);
                return ResponseCode.buildSuccessMap(null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseCode.buildFailMap("信息有误", "false");
    }
    
    
    
    /**
     * 分享邀请用户注册的分享链接
     * @return
     */
    @RequestMapping(value = "/shareLogin", method = RequestMethod.POST)
    public Map<String, Object> shareLogin( HttpServletRequest request) {
        UserDto user = SecurityUserHolder.getCurrentUser(request);
        if(user == null || user.getId() == null){
            return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);
        }
        return ResponseCode.buildSuccessMap(user.getId());
    }
    /**
     * 分享邀请用户注册的分享链接
     * @return
     */
    @RequestMapping(value = "/checkUserPhone", method = RequestMethod.POST)
    public Map<String, Object> checkUserPhone( HttpServletRequest request) {
        UserDto user = SecurityUserHolder.getCurrentUser(request);
        if(user == null || user.getId() == null){
            return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);
        }
        User new_user = userService.selectByPrimaryKey(user.getId());
        if (new_user.getMobile()==null||new_user.getUserName()==null) {
            return ResponseCode.buildEnumMap(ResponseCode.RESPONSE_CODE_USER_MOBILE_OR_TELEPHONE_NOT_EMPTY, null);
        }
        return ResponseCode.buildSuccessMap(null);
    }
    
    
    /**
     * 分享邀请用户购买商品的分享链接
     * @return
     */
    @RequestMapping(value = "/shareGoods", method = RequestMethod.POST)
    public Map<String, Object> shareGoods( HttpServletRequest request) {
        UserDto user = SecurityUserHolder.getCurrentUser(request);
        if(user == null || user.getId() == null){
            return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);
        }
        return ResponseCode.buildSuccessMap(user.getId());
    }
    
    
    
    
    /**
    * @Description 将字符串中的emoji表情转换成可以在utf-8字符集数据库中保存的格式(表情占4个字节,需要utf8mb4字符集)
    * @param str
    * 待转换字符串
    * @return 转换后字符串
    * @throws UnsupportedEncodingException
    * exception
    */
    public static String emojiConvert1(String str) {
        String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            try {
                matcher.appendReplacement(sb, "[[" + URLEncoder.encode(matcher.group(1), "UTF-8") + "]]");
            } catch (Exception e) {
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    
    
    /**
     * 微信授权登录上传头像
     * @param photo_url
     * @param user_id
     * @return
     */
    public AccessoryDto uploadPhotoFile(String photo_url, Long user_id){
        try {
            AccessoryDto accessoryDto = ftpFileFeignClient.upload("user/image", "", "JPG", user_id, photo_url);
            return accessoryDto;
        } catch (Exception e) {
            log.error("微信授权登录上传头像失败:"+Exceptions.getStackTraceAsString(e));
        }
        return null;
    }
    
    
    /**
     * 将全部的用户注册IM账号
     * @return
     */
    @RequestMapping(value = "/IM/outImportMultipleAccounts", method = RequestMethod.GET)
    public boolean outImportMultipleAccounts() {
        //获取所有用户的信息
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("deleteStatus", "0");
        int count = userService.selectCount(params);
        int pageNum = (count/100)+1;    //腾讯只支持最多100个账号删除
        boolean bol = true;
        for(int i = 1; i <= pageNum; i++){
            params.put("currentPage", i);
            params.put("pageSize", 100);
            List<User> list = userService.queryPages(params);
            List<String> uids = new ArrayList<String>();
            for (User user : list) {
                uids.add(user.getId().toString());
            }
            bol = tencentIMFeignClient.importMultipleAccounts(uids);
        }
        return bol;
    }
    
    
    /**
     * 将全部的用户注册IM账号
     * @return
     */
    @RequestMapping(value = "/IM/outAccountDelete", method = RequestMethod.GET)
    public boolean outAccountDelete() {
        //获取所有用户的信息
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("deleteStatus", "0");
        int count = userService.selectCount(params);
        int pageNum = (count/100)+1;    //腾讯只支持最多100个账号删除
        boolean bol = true;
        for(int i = 1; i <= pageNum; i++){
            params.put("currentPage", i);
            params.put("pageSize", 100);
            List<User> list = userService.queryPages(params);
            List<String> uids = new ArrayList<String>();
            for (User user : list) {
                uids.add(user.getId().toString());
            }
            bol = tencentIMFeignClient.accountDelete(uids);
        }
        return bol;
    }
    
    /**
     * 微信授权登录
     * @param code 授权临时票据
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/weChatLogin" , method = RequestMethod.GET)
    public Map<String, Object> weChatLogin(@RequestParam("code") String code) throws Exception {
        return userService.weChatLogin(code);
    }
    /**
     * 微信授权登录(uniapp使用)
     * @param code 授权临时票据
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/appWeChatLogin" , method = RequestMethod.POST)
    public Map<String, Object> appWeChatLogin(@RequestBody JSONObject json) throws Exception {
        return userService.appWeChatLogin(json);
    }
    @RequestMapping(value = "/appWeChatLoginNew" , method = RequestMethod.POST)
    public Map<String, Object> appWeChatLoginNew(@RequestBody JSONObject json) throws Exception {
        return userService.appWeChatLoginNew(json);
    }
    
    /**
     * 微信授权登录
     * @param code 授权临时票据
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/weChatH5Login" , method = RequestMethod.GET)
    public Map<String, Object> weChatH5Login(@RequestParam("code") String code) throws Exception {
        return userService.weChatH5Login(code);
    }
    
}
@源码地址来源: https://minglisoft.cn/honghu2/business.html
​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个用于构建微服务的开源框架,它能够快速搭建项目并且提供了许多便捷的功能和特性。Spring Security 是一个用于处理认证和授权的框架,可以保护我们的应用程序免受恶意攻击。JWT(JSON Web Token)是一种用于身份验证的开放标准,可以被用于安全地传输信息。Spring MVC 是一个用于构建 Web 应用程序的框架,它能够处理 HTTP 请求和响应。MyBatis 是一个用于操作数据库的框架,可以简化数据库操作和提高效率。Redis 是一种高性能的键值存储系统,可以用于缓存与数据存储。 基于这些技术,可以搭建一个商城项目。Spring Boot 可以用于构建商城项目的后端服务,Spring Security 可以确保用户信息的安全性,JWT 可以用于用户的身份验证,Spring MVC 可以处理前端请求,MyBatis 可以操作数据库,Redis 可以用于缓存用户信息和商品信息。 商城项目的后端可以使用 Spring BootSpring Security 来搭建,通过 JWT 来处理用户的身份验证和授权。数据库操作可以使用 MyBatis 来简化与提高效率,同时可以利用 Redis 来缓存一些常用的数据和信息,提升系统的性能。前端请求则可以通过 Spring MVC 来处理,实现商城项目的整体功能。 综上所述,借助于 Spring BootSpring Security、JWT、Spring MVC、MyBatisRedis 这些技术,可以构建出一个高性能、安全可靠的商城项目,为用户提供良好的购物体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值