微信小程序后端(java)开发流程的详细步骤

微信小程序后端开发流程根据官网总结为两个步骤

1、前端调用 wx.login 返回了code,然后调用wx.getUserInfo获取到用户的昵称 头像

2、服务端根据code去微信获取openid, 接口地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html%EF%BC%9B%E5%90%8C%E6%97%B6%EF%BC%8C%E6%9B%B4%E6%96%B0%E7%94%A8%E6%88%B7%E6%98%B5%E7%A7%B0%E5%A4%B4%E5%83%8F%E7%AD%89%E8%B5%84%E6%96%99

微信小程序后端接口开发

controller层

public class OauthController {

  @Autowired
  private WeChatService weChatService;

  /**
   * 微信授权用js_code换取openId
   * @param code
   * @return
   */
  @GetMapping("/code2Session")
  public BaseResponse code2Session(String code) {
    log.info("code2Session,code={}", code);
    if (StringUtil.isEmpty(code)) {
      return BaseResponse.buildFail("参数异常");
    }
    Code2SessionResponse res = weChatService.code2Session(code);
    log.info("code2Session,res={}", res);
    if (!res.isSuccess()) {
      return BaseResponse.buildFail(res.getErrCode(), res.getErrMsg());
    }
    return BaseResponse.buildSuccess(res);
  }

 /**
   * 解密获取手机号
   * @param request
   * @param response
   * @param param
   * @return
   */
  public BaseResponse decryptGetPhone(HttpServletRequest request, HttpServletResponse response,
                  @RequestBody OauthParam param) {

      if (!StringUtil.isEmpty(param.getOpenId())) {//微信授权登录
        String sessionKey = weChatService.getSessionKey(param.getOpenId());
        if (StringUtil.isEmpty(sessionKey)) {
          return BaseResponse.buildFail("会话不存在");
        }
        Sha1Utils sha = new Sha1Utils();
        // 获取用户信息
        log.debug("微信登陆 sessionKey = {}", sessionKey);
        String userInfoStr = sha.decryptWXAppletInfo(sessionKey, param.getEncryptedData(), param.getIv());
        if (StringUtil.isEmpty(userInfoStr)) {
          return BaseResponse.buildFail("无法获取用户信息");
        }
        JSONObject json = JSONObject.parseObject(userInfoStr);
        //绑定微信的手机号
        String tel = json.getString("purePhoneNumber");
        Assert.isTrue(!StringUtils.isEmpty(tel), "无法获取用户手机号");
        BaseResponse baseResponse=new BaseResponse();
        baseResponse.setResultInfo(tel);
        baseResponse.setState(0);
        return baseResponse;
      }

  }
}

接口

public interface WeChatService {

  /**
   * 用code换取openid
   *
   * @param code
   * @return
   */
  Code2SessionResponse code2Session(String code);

  /**
   * 获取凭证
   *
   * @return
   */
  String getAccessToken();

  /**
   * 获取凭证
   *
   * @param isForce
   * @return
   */
  String getAccessToken(boolean isForce);

  String getSessionKey(String openId);

}

实现类

public class WeChatServiceImpl implements WeChatService {

  //获取配置文件数据
  @Value("${wechat.miniprogram.id}")
  private String appId;

  @Value("${wechat.miniprogram.secret}")
  private String appSecret;

  @Reference
  private SysUserService sysUserService;

  @Override
  public Code2SessionResponse code2Session(String code) {
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_CODE2SESSION, appId, appSecret, code));
    log.info("rawResponse====={}", rawResponse);
    Code2SessionResponse response = JSON.parseObject(rawResponse, Code2SessionResponse.class);
    if (response.isSuccess()) {
      cacheSessionKey(response);
    }
    return response;
  }

  private void cacheSessionKey(Code2SessionResponse response) {
    RedisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(response.getOpenId());
    redisCache.setCache(key, 2147483647, response.getSessionKey());
  }

  @Override
  public String getAccessToken() {
    return getAccessToken(false);
  }

  @Override
  public String getAccessToken(boolean isForce) {
    RedisCache redisCache = RedisCache.getInstance();
    String accessToken = null;
    if (!isForce) {
      accessToken = redisCache.getCache(RedisCacheKeys.getWxAccessTokenKey(appId));
    }
    if (StringUtil.isNotEmpty(accessToken)) {
      return accessToken;
    }
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_GET_ACCESS_TOKEN, appId, appSecret));
    AccessTokenResponse response = JSON.parseObject(rawResponse, AccessTokenResponse.class);
    log.info("getAccessToken:response={}", response);
    if (response.isSuccess()) {
      redisCache.setCache(RedisCacheKeys.getWxAccessTokenKey(appId), 7000, response.getAcessToken());
      return response.getAcessToken();
    }
    return null;
  }

  @Override
  public String getSessionKey(String openId) {
    RedisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(openId);
    String sessionKey = redisCache.getCache(key);
    return sessionKey;
  }
}

用到的解密工具类

public class Sha1Utils {
  public static String decryptWXAppletInfo(String sessionKey, String encryptedData, String iv) {
    String result = null;
    try {
      byte[] encrypData = Base64.decodeBase64(encryptedData);
      byte[] ivData = Base64.decodeBase64(iv);
      byte[] sessionKeyB = Base64.decodeBase64(sessionKey);

      AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
      byte[] doFinal = cipher.doFinal(encrypData);
      result = new String(doFinal);
      return result;
    } catch (Exception e) {
      //e.printStackTrace();
      log.error("decryptWXAppletInfo error",e);
    }
    return null;
  }

}

网络请求工具类

public class HttpClientUtil {

  // utf-8字符编码
  public static final String            CHARSET_UTF_8     = "utf-8";

  // HTTP内容类型。
  public static final String            CONTENT_TYPE_TEXT_HTML = "text/xml";

  // HTTP内容类型。相当于form表单的形式,提交数据
  public static final String            CONTENT_TYPE_FORM_URL = "application/x-www-form-urlencoded";

  // HTTP内容类型。相当于form表单的形式,提交数据
  public static final String            CONTENT_TYPE_JSON_URL = "application/json;charset=utf-8";

  // 连接管理器
  private static PoolingHttpClientConnectionManager pool;

  // 请求配置
  private static volatile RequestConfig requestConfig;

  private static CloseableHttpClient getNewHttpClient() {

    CloseableHttpClient httpClient = HttpClients.custom()
      // 设置连接池管理
      .setConnectionManager(pool)
      // 设置请求配置
      .setDefaultRequestConfig(getRequestConfig())
      // 设置重试次数
      .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();

    return httpClient;
  }

  /**
   * 发送 post请求
   *
   * @param httpUrl
   *      地址
   */
  public static String post(String httpUrl) {
    // 创建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return request(httpPost);
  }

  public static byte[] postRaw(String httpUrl) {
    // 创建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return requestRaw(httpPost);
  }

  /**
   * 发送 get请求
   *
   * @param httpUrl
   */
  public static String get(String httpUrl) {
    // 创建get请求
    HttpGet httpGet = new HttpGet(httpUrl);
    return request(httpGet);
  }

  /**
   * 发送 post请求(带文件)
   *
   * @param httpUrl
   *      地址
   * @param maps
   *      参数
   * @param fileLists
   *      附件
   */
  public static String post(String httpUrl, Map<String, String> maps, List<File> fileLists,
               String fileName) {
    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
    MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
    if (maps != null) {
      for (String key : maps.keySet()) {
        meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
      }
    }
    if (fileLists != null) {
      for (File file : fileLists) {
        FileBody fileBody = new FileBody(file);
        meBuilder.addPart(fileName, fileBody);
      }
    }
    HttpEntity reqEntity = meBuilder.build();
    httpPost.setEntity(reqEntity);
    return request(httpPost);
  }

  public static String post(String httpUrl, Map<String, String> maps, List<File> fileLists) {
    return post(httpUrl, maps, fileLists, "file");
  }

  public static String post(String httpUrl, List<File> fileLists) {
    return post(httpUrl, Collections.emptyMap(), fileLists, "file");
  }

  /**
   * 发送 post请求
   *
   * @param httpUrl
   *      地址
   * @param params
   *      参数(格式:key1=value1&key2=value2)
   *
   */
  public static String post(String httpUrl, String params) {
    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
    try {
      // 设置参数
      if (params != null && params.trim().length() > 0) {
        StringEntity stringEntity = new StringEntity(params, "UTF-8");
        stringEntity.setContentType(CONTENT_TYPE_FORM_URL);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return request(httpPost);
  }

  /**
   * 发送 post请求
   *
   * @param maps
   *      参数
   */
  public static String post(String httpUrl, Map<String, String> maps) {
    String param = convertStringParamter(maps);
    return post(httpUrl, param);
  }

  /**
   * 发送 post请求 发送json数据
   *
   * @param httpUrl
   *      地址
   * @param content
   *
   *
   */
  public static String post(String httpUrl, String content, String contentType) {
    //    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
    //    try {
    //      // 设置参数
    //      if (StringUtils.isNotEmpty(content)) {
    //        StringEntity stringEntity = new StringEntity(content, "UTF-8");
    //        stringEntity.setContentType(contentType);
    //        httpPost.setEntity(stringEntity);
    //      }
    //    } catch (Exception e) {
    //      e.printStackTrace();
    //    }
    //    return request(httpPost);
    return new String(postRaw(httpUrl, content, contentType), StandardCharsets.UTF_8);
  }

  public static byte[] postRaw(String httpUrl, String content, String contentType) {
    HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
    try {
      // 设置参数
      if (StringUtils.isNotEmpty(content)) {
        StringEntity stringEntity = new StringEntity(content, "UTF-8");
        stringEntity.setContentType(contentType);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return requestRaw(httpPost);
  }

  /**
   * 发送 post请求 发送json数据
   *
   * @param httpUrl
   *      地址
   * @param paramsJson
   *      参数(格式 json)
   *
   */
  public static String postJson(String httpUrl, String paramsJson) {
    return post(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  public static byte[] postJsonRaw(String httpUrl, String paramsJson) {
    return postRaw(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  /**
   * 发送 post请求 发送xml数据
   *
   * @param url  地址
   * @param paramsXml 参数(格式 Xml)
   *
   */
  public static String postXml(String url, String paramsXml) {
    return post(url, paramsXml, CONTENT_TYPE_TEXT_HTML);
  }

  /**
   * 将map集合的键值对转化成:key1=value1&key2=value2 的形式
   *
   * @param parameterMap
   *      需要转化的键值对集合
   * @return 字符串
   */
  public static String convertStringParamter(Map parameterMap) {
    StringBuilder parameterBuffer = new StringBuilder();
    if (parameterMap != null) {
      Iterator iterator = parameterMap.keySet().iterator();
      String key = null;
      String value = null;
      while (iterator.hasNext()) {
        key = (String) iterator.next();
        if (parameterMap.get(key) != null) {
          value = (String) parameterMap.get(key);
        } else {
          value = "";
        }
        parameterBuffer.append(key).append("=").append(value);
        if (iterator.hasNext()) {
          parameterBuffer.append("&");
        }
      }
    }
    return parameterBuffer.toString();
  }

  /**
   * 发送请求
   *
   * @param request
   * @return
   */
  public static byte[] requestRaw(HttpRequestBase request) {

    CloseableHttpClient httpClient;
    CloseableHttpResponse response = null;
    // 响应内容
    //    String responseContent = null;
    byte[] rawResponse = null;
    try {
      // 创建默认的httpClient实例.
      httpClient = getNewHttpClient();
      // 配置请求信息
      request.setConfig(requestConfig);
      // 执行请求
      response = httpClient.execute(request);
      // 得到响应实例
      HttpEntity entity = response.getEntity();

      // 可以获得响应头
      // Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);
      // for (Header header : headers) {
      // System.out.println(header.getName());
      // }

      // 得到响应类型
      // System.out.println(ContentType.getOrDefault(response.getEntity()).getMimeType());

      // 判断响应状态
      if (response.getStatusLine().getStatusCode() >= 300) {
        throw new Exception("HTTP Request is not success, Response code is "
                  + response.getStatusLine().getStatusCode());
      }

      if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
        rawResponse = EntityUtils.toByteArray(entity);
        //        responseContent = EntityUtils.toString(entity, CHARSET_UTF_8);
        EntityUtils.consume(entity);
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        // 释放资源
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return rawResponse;
  }

  private static String request(HttpRequestBase req) {
    return new String(requestRaw(req), StandardCharsets.UTF_8);
  }

  private static RequestConfig getRequestConfig() {

    if (requestConfig == null) {
      synchronized (HttpClientUtil.class) {
        if (requestConfig == null) {
          try {
            //System.out.println("初始化HttpClientTest~~~开始");
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
              builder.build());
            // 配置同时支持 HTTP 和 HTPPS
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
              .<ConnectionSocketFactory> create()
              .register("http", PlainConnectionSocketFactory.getSocketFactory())
              .register("https", sslsf).build();
            // 初始化连接管理器
            pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            // 将最大连接数增加到200,实际项目最好从配置文件中读取这个值
            pool.setMaxTotal(200);
            // 设置最大路由
            pool.setDefaultMaxPerRoute(2);
            // 根据默认超时限制初始化requestConfig
            int socketTimeout = 10000;
            int connectTimeout = 10000;
            int connectionRequestTimeout = 10000;
            requestConfig = RequestConfig.custom()
              .setConnectionRequestTimeout(connectionRequestTimeout)
              .setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout)
              .build();

          } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
          } catch (KeyStoreException e) {
            e.printStackTrace();
          } catch (KeyManagementException e) {
            e.printStackTrace();
          }

          // 设置请求超时时间
          requestConfig = RequestConfig.custom().setSocketTimeout(50000)
            .setConnectTimeout(50000).setConnectionRequestTimeout(50000).build();
        }
      }
    }
    return requestConfig;
  }
}

常量

public interface WechatConstant {
  Integer OK_STATUS      = 0;
  String URL_CODE2SESSION   = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

  String URL_GET_ACCESS_TOKEN   = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

  String URL_GET_IMAGE = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";

  /**
   * 给公众号发送信息。参考https://mp.weixin.qq.com/advanced/tmplmsg?action=faq&token=708366329&lang=zh_CN
   */
  String URL_SEND_TO_CHANNEL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
  String URL_SEND_MESSAGE   = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";

  /**
   * 发送模板消息。参考https://developers.weixin.qq.com/miniprogram/dev/api-backend/sendMiniTemplateMessage.html
   */
  String URL_SEND_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s";

  String URL_QR_CODE_UNLIMTED = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";

  String URL_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s";

  /**
   * 获取标签下粉丝列表
   */
  String URL_ALL_FANS_OPENID = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=%s";
  /**
   * 获取公众号已创建的标签
   */
  String URL_ALL_TAGS = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=%s";

}

使用到的实体类

public class Code2SessionResponse implements Serializable {
  public static Integer RESPONSE_OK = 0;

  @JSONField(name = "openid")
  private String    openId;
  @JSONField(name = "session_key")
  private String    sessionKey;
  @JSONField(name = "unionid")
  private String    unionId;
  @JSONField(name = "errcode")
  private Integer   errCode;
  @JSONField(name = "errmsg")
  private String   errMsg;

  public boolean isSuccess() {
    return this.errCode == null || RESPONSE_OK.equals(this.errCode);
  }
}

总结:微信小程序的后端开发主要就是对用户进行授权 , 1、前端调用 wx.login 返回了code,然后调用wx.getUserInfo获取到用户的昵称 头像 2.首先通过微信授权用js_code换取openId,来获取openId,前端传微信的参数 code字段 3.然后解密获取手机号 前端需要传openId encryptedData iv 等字段来获取用户的的授权手机号

这些信息都获取后 接着就是调用后端的登陆接口,登陆接口如果只有授权登录就是我们将接口参数为下图最后三个字段为前端必填字段

主要步骤是根据前端的openId获取sessionKey 然后根据sessionKey 和其他参数进行解密获取用户手机号

通过解密获取授权登录的手机号,然后根据自己的业务逻辑处理即可,这样我们就可以根据授权的手机号进行授权登录

(0)

相关推荐

  • 微信小程序实现获取小程序码和二维码java接口开发

    前言:目前小程序推出了自己的识别码,小程序码,这个圆形的码看起来比二维码好看.本文总结微信小程序的获取小程序码和二维码并生成二维码图片的接口开发.主要内容摘抄自微信小程序的API文档,java接口开发是自己总结开发. 微信小程序API文档:获取二维码 一.简介 通过后台接口可以获取小程序任意页面的二维码,扫描该二维码可以直接进入小程序对应的页面.目前微信支持两种二维码,小程序码(左),小程序二维码(右),如下所示: 二.获取小程序码 目前有两个接口可以生成小程序码,开发者可以根据自己的需要选择合

  • Java实现简单日历小程序 Java图形界面小日历开发

    今天给大家介绍一下如何用Java swing开发一款简单的小日历,下面我们来看代码: 首先创建一个CalendarBean类,用于基本的日期计算: package other1; import java.util.Calendar; public class CalendarBean { String day[]; int year=2005,month=0; public void setYear(int year) { this.year=year; } public int getYear

  • 微信小程序后端(java)开发流程的详细步骤

    微信小程序后端开发流程根据官网总结为两个步骤 1.前端调用 wx.login 返回了code,然后调用wx.getUserInfo获取到用户的昵称 头像 2.服务端根据code去微信获取openid, 接口地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html%EF%BC%9B%E5%90%8C%E6%97%B6%EF%BC%8C%E6%9B%B4

  • 微信小程序+后端(java)实现开发

    前言 现在微信小程序越来越火了,相信不少人都通过各种途径学习过微信小程序或者尝试开发,作者就是曾经由于兴趣了解开发过微信小程序,最终自己的毕业设计也是开发一个微信小程序.所以现在用这篇博客记录我之前开发的一些经验和一些心得吧. 主要内容 springboot后端架构构建 小程序项目构建 小程序api调用 后台resetful接口编写 小程序调用后台接口 免费的https申请 linux下部署上线 微信小程序项目构建 这些基础的东西我就不过多介绍,大家在刚开始开发的时候一般都没有自己的服务器及域名

  • 微信小程序后端Java接口开发的详细步骤

    目录 1.搭建一个springboot项目并引入依赖 2.编写controller层 3.创建微信小程序项目 微信小程序使用wx.request(OBJECT)来调用后端接口. 首先 我们来一个简单案例 -- helloworld实现 1.搭建一个springboot项目并引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-

  • 微信小程序接入vant Weapp组件的详细步骤

    刚创建的项目的文件结构 首先在你项目的根目录下打开终端,输入npm init 对项目初始化 这时会生成pachage.json文件. 继续在终端运行以下命令 我这里用这个: npm i vant-weapp -S --production 运行完如图所示: 安装成功后 回到小程序开发工具 点击 工具 => 构建npm 运行完截图: 完成后在编辑器右边的详情把红框内的打勾上 使用组件 在你想使用组件库的的json文件内引入组件.比如你想在fundIncome页面内使用button组件. 效果: 上

  • 微信小程序 实战实例开发流程详细介绍

    前言:         微信小程序最近要发布了,抽空学习下如何开发,在网上找到的实例,觉得不错,给大家分享, 前后两天花了大约四五个小时制作完了自己第一个小程序,当然是没法发布的,小程序的发布要求还是挺严格的:企业资质.HTTPS.审核. 先大概介绍下自己,我9年前和很多网友一样开始自学编程,这些年来什么语言都学过.什么平台都接触过,自己也做过十来个产品,所以编程基础不是很稳固但是各方面都相对比较熟悉,因此在接触小程序的时候上手比较快. 至于为什么现在选择开发小程序,原因很简单,尝尝鲜! 学习

  • 微信小程序支付及退款流程详解

    首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语言语法层面,去从系统和流程的角度考虑.好的,也不说什么废话了.进入正题. 一. 支付 支付主要分为几个步骤: 前端携带支付需要的数据(商品id,购

  • 微信小程序后端实现授权登录

    登录与授权 官方文档 一.登录登录流程时序 说明: 调用 wx.login()获取临时登录凭证code,并回传到开发者服务器. 调用code2Session接口,换取用户唯一标识 OpenID和会话密钥 session_key. 之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份. 注意: 会话密钥session_key是对用户数据进行加密签名的密钥.为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥. 临时登录

  • 微信小程序向Java后台传输参数的方法实现

    首先,微信小程序我使用的是微信web开发者工具 想要向后台传输数据,需要在js中写 在微信小程序的官方文档中可以看到一个api叫wx.request它的作用是用来发送https请求的 在js代码中,我们先使用wx.request这个api,它需要我们去写url,这个url其实就是Java代码部署在服务器上运行后的地址,这里我们没有真实服务器,我们使用tomcat去运行后端代码,将这个url复制给微信小程序的url中 我的Java代码在运行时出现一个问题,就是找不到我这个类,一直报404错误,一个

  • 微信小程序使用uni-app开发小程序及部分功能实现详解

    目录 一.uni-app 1.简介 2.开发工具 3.新建 uni-app项目 4.把项目运行到微信开发者工具 二.实现tabBar效果 1.创建tabBar页面 2.配置tabBar 三.配置网络请求 1.依照官网提示安装.导入.使用 2.实战 四.uni-app 里面小程序分包 1.创建分包目录 2.在 pages.json 文件中配置 3.创建分包页面 五.公用方法封装 六.搜索功能 1.搜索组件 2.搜索建议实现 3.本地存储 4.过滤器 七.上拉加载.下拉刷新 1.上拉加载 2.下拉刷

  • 微信小程序访问mysql数据库流程详解

    目录 1 开通云上的mysql 2 创建自定义连接器 3 创建云函数 4 安装依赖 5 出参映射 6 在小程序中使用连接器 总结 1 开通云上的mysql 经过询价,我发现阿里云的数据库是比较便宜的,新人购买非常划算.对于爱学习的博主来说,果断购买一个. 按照操作指引购买后,云会帮你创建一系列的环境,在控制台就可以看到属于自己的实例 点击操作列上的管理,就可以创建我们自己的数据库.配置的步骤是先创建数据库的账号 然后创建一个数据库 都设置好之后就可以登录数据库,创建表,加数据了 刚创建好的数据库

随机推荐