2019-04-27 21:09:23 pharos 阅读数 4295

开发微信小程序需要前后端一起配合,前端通过微信提供的工具开发,实际页面、样式及JS代码部署在微信服务器;后端可以通过JAVA语言开发,实现具体业务逻辑并与数据库、Redis缓存、MQ等进行交互,代码部署在开发者服务器;调用微信提供的API时,后端开发关键点有两个:

一、在前端调用wx.login() 获取 临时登录凭证code之后,将code字符串发送给后端,后端通过auth.code2Session接口获取用户唯一标识 OpenID 。

为什么非要获取OpenID?因为一个微信小程序客户在此微信小程序之内,这个OpenID是唯一的,在客户登录、使用小程序的整个过程中,开发者的后端服务就是通过它来区分不同用户的。
前端的code只是临时凭证,是有时效性的,统一OpenID的用户在每次登录小程序时code不一样。

后端获取OpenID非常简单,遵循微信小程序提供的帮助文档就成,直接Get这个地址:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code, 将appid、secret、js_code、grant_type放进去,然后解析出返回的JSON串就可以啦。
比如用SpringBoot开发,可以将getOpenId封装成一个服务方法,在登录的时候直接调用就可以啦。
代码如下:

@Override
public CodeToSessionEntity getOpenId(String code, String logUniqueFlag) {
    String requestUrl = mallConstant.getWx_getopenid_url();
    String appId = mallConstant.getWx_appid();
    String secret = mallConstant.getWx_appSecret();
    String getUrlPath = requestUrl + "?" + "appid=" + appId + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
    try {
        sessionEntity = restTemplate.getForObject(getUrlPath, CodeToSessionEntity.class);
    } catch (Exception e) {
        log.error("{}-根据code从微信小程序获取OpenId的值发起请求,出现了异常!e={}", logUniqueFlag, e);
    }
    log.info("{}-根据code从微信小程序获取OpenId的值发起请求,url={},result={}", logUniqueFlag, getUrlPath, sessionEntity.toString());
    return sessionEntity;
}

调用处代码如下:

CodeToSessionEntity sessionEntity = weiXinService.getOpenId(code, mtmWxCodeReq.getLogUniqueFlag());

二、后端业务逻辑如果打算调用微信提供的活体认证(生物认证)、物流助手、大数据分析能力,那么就需要access_token,这个access_token是调用这些api的接口调用凭证。

比如说调用生物认证能力,必须得有access_token。
在这里插入图片描述
获取access_token比获取OpenID还要简单,只要Get这个地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET, 将appid、secret放进去,然后解析出返回的JSON串就成。

“模拟大量微信小程序用户对平台进行并发访问的性能测试指引”请参考
https://blog.csdn.net/pharos/article/details/89397826

2018-03-18 19:32:09 yiwangxiblog 阅读数 6436

      第一次做前后端分离的项目,当时就有一个疑问,在微信开发者工具里写的前端代码和在idea里写的后台代码如何交互,做过了才知道,其实非常简单,主要思想就是后端发布成一个URL地址,前端调用即可。在微信小程序中,通过wx.request( )发起请求。

wx.request({
  url: 'https://wxdemo.com/login', 
  data: {
     username: '' ,
     password: ''
  },
  header: {
      'content-type': 'application/json' // 默认值
  },
  success: function(res) {
    console.log(res.data)
  }
})

通过上面的代码可以看出,wx.request()方法传递了一些参数,这些参数起到了不同的作用:

参数名类型必填默认值说明最低版本
urlString 开发者服务器接口地址 
dataObject/String/ArrayBuffer 请求的参数 
headerObject 设置请求的 header,header 中不能设置 Referer。 
methodStringGET(需大写)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT 
dataTypeStringjson如果设为json,会尝试对返回的数据做一次 JSON.parse 
responseTypeStringtext设置响应的数据类型。合法值:text、arraybuffer1.7.0
successFunction 收到开发者服务成功返回的回调函数 
failFunction 接口调用失败的回调函数 
completeFunction 接口调用结束的回调函数(调用成功、失败都会执行)

当请求成功后,success会接收到成功的信息,主要参数包括:

参数类型说明最低版本
dataObject/String/ArrayBuffer开发者服务器返回的数据 
statusCodeNumber开发者服务器返回的 HTTP 状态码 
headerObject开发者服务器返回的 HTTP Response Header1.2.0

2019-04-27 21:01:13 double_sweet1 阅读数 1053

在微信小程序中,如果前后端分离开发的话,是需要通过接口来进行交互的,

因此在联系不到后台的情况下,写前端的我们应当如何测试自己的页面呢?方法如下:

微信小程序前端与后台交互的时候使用的是request请求,请求的地址必须是Http打头的,为了方便前台测试,我们可以自己先写一个我们需要的json文件,然后使用tomcat去访问。

具体做法就是:

1.在idea编辑器(其他可以做web的编辑器也可以)中新建一个web项目,

2.将微信小程序的项目文件(假设叫weixin_test)拖进web目录下,

3.配置并启动tomcat,

4.将web项目web目录下的小程序文件(假设叫weixin_test)用微信开发者打开,

5.正常使用request请求去访问我们写好的json文件即可。

6.与此同时,我们使用微信开发者工具调代码的时候idea下的那个web项目也会同步更新(因为微信开发者工具打开的是web项目下的一个子文件),前提是tomcat是启动状态,这样就可以提高编码效率啦。

 

原创文章,请勿转载!

2018-07-16 15:02:24 bianyamei 阅读数 687

微信二次开发其实和web项目开发一样,只不过要使用微信的提供接口,遵循腾讯的接口规范.微信公众号就相当于前端页面,我们通过自己开发的后台来和前端页面交互,按照我们的需求拓展微信公众号的功能.

1.在eclipse里搭建一个web工程.

2.创建一个servlet类,因为后台和微信公众号是通过doGet方式交互的,我们在servlet里写一个doGet方法.

/**
 * 
 *@author bym @date 2018年7月4日
 *
 */
public class CoreServlet extends HttpServlet {
	
	private static final long serialVersionUID = -6595792134085823033L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		String signature = request.getParameter("signature");
		
		String timestamp = request.getParameter("timestamp");
	
		String nonce = request.getParameter("nonce");

		String echostr = request.getParameter("echostr");

		PrintWriter out = response.getWriter();
	
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			out.print(echostr);
		}
		out.close();
		out = null;
	}

	/**
	 * Post方法
	 * @param request
	 * @param response
	 */
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");

	
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");

		PrintWriter out = response.getWriter();

		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
	
			String respXml = CoreService.processRequest(request);
			out.print(respXml);
		}
		out.close();
		out = null;
	}
}

coreServlet的doGet方法调用SignUtil.java类中的checkSignature方法

/**
 * 请求校验工具类
 * 
 * @author bym @date 2018年7月4日
 */
public class SignUtil {
	// 与开发模式接口配置信息中的Token保持一致
	private static String token = "weixin";

	/**
	 * 校验签名
	 * 
	 * @param signature 微信加密签名
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @return
	 */
	public static boolean checkSignature(String signature, String timestamp, String nonce) {
		// 对token、timestamp和nonce按字典排序
		String[] paramArr = new String[] { token, timestamp, nonce };
		Arrays.sort(paramArr);

		// 将排序后的结果拼接成一个字符串
		String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

		String ciphertext = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			// 对接后的字符串进行sha1加密
			byte[] digest = md.digest(content.toString().getBytes());
			ciphertext = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		// 将sha1加密后的字符串与signature进行对比
		return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;
	}

	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}
}

注意SignUtil中设置的tocken要和公众号设置-服务器设置中的tocken要一致!

然后在web.xml配置CoreServlet的路径,因为web项目启动先读取web.xml,获取项目的配置信息.通过读取配置的Servlet的路径来调用Servlet服务.

这样就可以把项目发布到服务器上,必须是公网上,用公网ip访问CoreServlet,因为没有通过微信传数据会报空指针异常,这是正常的.服务启动之后,去微信服务器设置里,设置你的url和tocken就可以.填写的信息都正确,会提示你提交成功的,点击开启,就启用开发者模式啦.

2019-05-22 21:53:47 qq_37591637 阅读数 594

我的qq 2038373094

我做的是微信小程序、网站、手机app,后端java+前端vue、bootstrap框架、原生的html+css+js都会

做过律师在线咨询系统、共享农场手机app、在线心理咨询系统

 

前提

强烈推荐一个微信小程序开发快捷的框架:touchWX框架

http://www.wetouch.net/touchwx_doc/component/summary/Introduction

 这个框架的

1、开发工具是vscode

2、需要安装Nodejs

3、新建touchwx 基础工程   环境的配置看这里  http://www.wetouch.net/touchwx_doc/quickstart/begin/ide

 

数据库数据如下

 

index.wx代码如下(index.wx可以变成index.wxml、index.wxss、index.js)

http://www.wetouch.net/touchwx_doc/component/view/nav-bar

<template>
  <view>
<ui-segment bindchange="changeTab2">
    <ui-segment-item>
        推荐
    </ui-segment-item>
    <ui-segment-item>
        教育
    </ui-segment-item>
    <ui-segment-item>
       成长
    </ui-segment-item>
     <ui-segment-item>
     心理
    </ui-segment-item>
     <ui-segment-item>
      课程
    </ui-segment-item>
</ui-segment>
<view class="tabContent">
  <!-- 连接数据库 -->
 <view class="top_tip" wx:for="{{mydata}}" wx:key="item.nid">
    <ui-row height="80" border-bottom hover-class="touchui-hover">
        <ui-col width="80" align="center" vertical-align="middle">
                <img src="/images/t1.jpg" class="im"/>
        </ui-col>
        <ui-col class="text" align="left" vertical-align="middle" space="20">
            <view style="width: 100%;">
                <ui-row height="30">
                    <ui-col align="left" vertical-align="middle">
                        <text class="tme">{{item.title}}</text>
                    </ui-col>
                </ui-row>
                <view>类型{{item.kinds}}、浏览量{{item.count}}、{{item.time}}发布</view>
            </view>
        </ui-col>
    </ui-row>
</view>
  <!-- 连接数据库 -->
</view>
  </view>
</template>
<script>
//引入文件
export default {
    data :{
        contentshow: 1,
        mydata:[]
    },
    changeTab2 (e) {
        var that=this;
        var kk=['教育','教育','成长','心理','课程'];
        let index = e.detail.index;
        var k=kk[index];
        console.log("类型:"+k);
           wx.request({
  url: 'http://localhost:8080/Teacher/queryNews.action', //接口地址
  data: {
     kinds:k
  },
  method:'get',
  header: {
    'content-type': 'application/json'
  },
  success: res => {
        console.log("真实的类型是:"+k);
    console.log(res.data);
     that.setData({
         mydata:res.data
        })
  }
})
    },
}
</script>

<style lang="less">
.im{
    width:50px;
    height:50px;
}
.top_tip{
    .left_icon{
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background-color:#FCB300; 
        text-align: center;
        line-height: 50px;
    }
    .left_icon2{
        background-color: #FF7360;
    }
    .left_icon3{
        background-color: #39CCC5;
    }
    .text{
        text{
            font-size: 16px;
            color: #313338;
        }
        view{
            color: #9C9FA4;
            font-size: 12px;
            .mix-text-overflow();
        }
    }
}
</style>

后台使用ssh框架实现的

package cn.com.service;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import cn.com.bean.News;
import com.opensymphony.xwork2.ModelDriven;
@Repository(value = "queryNews")
@Scope("prototype")
public class QueryNews implements ModelDriven<News>{
	@Autowired
	private SessionFactory sf;
	@Autowired
	private News news;
	@Transactional
	public String querynews() {
		System.out.println("["+news.getKinds()+"]");
		Session session = sf.getCurrentSession();
		String sql = "from News where kinds=?";
		Query query = session.createQuery(sql);
		query.setString(0, news.getKinds());
		List<News> list=query.list();
		//把list变成json
	   HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding("utf-8");
		try {
			 JSONArray json=JSONArray.fromObject(list);
			response.getWriter().write(json.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	@Override
	public News getModel() {
		// TODO Auto-generated method stub
		return news;
	}
}

 

效果如下

 

 

 

没有更多推荐了,返回首页