微信公众号开发

微信官方文档参考地址: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

1、微信公众号平台基础设置

1-1、白名单配置

微信公众号开发_第1张图片

1-2、回调接口配置

微信公众号开发_第2张图片

2、后台服务接口

2-1、公众号二维码生成接口

**注意说明:**当前接口主要是生成临时二维码,调用腾讯服务器获取公众号二维码并将企业logo合成到二维码中。

2-1-1、controller代码逻辑

 @GetMapping("qrcode")
    public Response login(HttpServletResponse response, HttpServletRequest request){
        return wxMpManager.qrcode();
    }

2-1-2、service接口

public Response qrcode() {
      Map<String,Object> showQrcodeMap = new HashMap();
        String accessToken = getAccessToken();
        String url = String.format(PUBLICACCOUNT_QRCODE_URL,accessToken);
        Map<String,Object> paramMap = new HashMap();
        paramMap.put("expire_seconds",604800);
        paramMap.put("action_name","QR_SCENE");
        Map<String,Object> sceneMap = new HashMap();
        Map<String,Object> sceneMap2 = new HashMap();
        sceneMap2.put("scene_id",IdGen.uuid());
        sceneMap.put("scene",sceneMap2);
        paramMap.put("action_info",sceneMap);
        HttpEntity httpEntity = new HttpEntity<>(new Gson().toJson(paramMap),new HttpHeaders());
        ResponseEntity<String> response  = restTemplate.postForEntity(url,httpEntity,String.class);
        JSONObject jsonObject =new JSONObject(response.getBody());
        log.info("临时二维码获取ticket,获取json:{}",jsonObject);
        String qrCodeUrl = jsonObject.getString("url");
        if(StringUtils.isEmpty(qrCodeUrl)){
            log.error("临时二维码获取ticket,获取json:{}",jsonObject);
            return ResponseUtils.returnCommonException("二维码获取失败");
        }
        try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            InputStream inputStream = getClass().getResourceAsStream(JIANMO_LOG_PATH)){
            BufferedImage bufferedImage =QRCodeUtil.createImage(qrCodeUrl,inputStream , false, QR_CODE_SIZE);
            ImageIO.write(bufferedImage,"jpg",outputStream);
            String content = Base64.getEncoder().encodeToString(outputStream.toByteArray());
            showQrcodeMap.put("showQrcodeUrl", "data:image/jpeg;base64,"+content);
            showQrcodeMap.put("ticket",jsonObject.getString("ticket"));
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        } catch (Exception e) {
           log.error(e.getMessage(),e);
        }
        return ResponseUtils.returnObjectSuccess(showQrcodeMap);
    }

2-2、微信回调接口

2-2-1、微信公众号平台配置回调校验接口

说明: 验证回调接口参数是否合法,如果合法直接返回入参中的echostr,这样公众平台中的回调校验才能正常通过。

@RequestMapping(method ={RequestMethod.GET,RequestMethod.POST},value ="login" )
    public String login(PublicAccountCallDTO publicAccountCallDTO,HttpServletRequest request,HttpServletResponse response) {
        log.info("publicAccountCallDTO={}",publicAccountCallDTO);
        boolean flag= wxMpManager.getSignature(publicAccountCallDTO);
         return flag ? publicAccountCallDTO.getEchostr():"";
    }
    public boolean getSignature(PublicAccountCallDTO publicAccountCallDTO) {
        if(StringUtils.isEmpty(publicAccountCallDTO.getSignature())){
            return false;
        }
        String[] array = new String[]{wxpayConfig.getWxOpenToken() , publicAccountCallDTO.getTimestamp() , publicAccountCallDTO.getNonce()};
        StringBuilder sb = new StringBuilder();
        // 字符串排序
        Arrays.sort(array);
        for (int i = 0; i < 3; i++) {
            sb.append(array[i]);
        }
        String signature = DigestUtils.sha1Hex(sb.toString());
        return signature.equals(publicAccountCallDTO.getSignature());
    }

2-2-2、controller业务逻辑代码接口

注意说明: 当前接口响应公众平台回调,所以返回格式为xml文件格式,为了避免返回数据乱码,此处需要二外配置produces = “application/xml; charset=UTF-8”

 @RequestMapping(method ={RequestMethod.POST},value ="login",produces =  "application/xml; charset=UTF-8")
    public String login( @RequestBody String requestBody,PublicAccountCallDTO publicAccountCallDTO,HttpServletRequest request,
                         HttpServletResponse response) {
        log.info("body={},publicAccountCallDTO={},paramMap={}",requestBody,publicAccountCallDTO,new Gson().toJson(request.getParameterMap()));

        boolean flag= wxMpManager.getSignature(publicAccountCallDTO);
        if(!flag){
            log.error("非法回调,body={},publicAccountCallDTO={}",requestBody,publicAccountCallDTO);
            return "";
        }
        wxMpManager.updateUser(requestBody,publicAccountCallDTO.getOpenid(), request);

        WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
        WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
        if(outMessage!=null) {
            log.info("输出xml数据,{}",outMessage.toXml());
            return outMessage.toXml();
        }
        return "";
    }

2-3、微信公众号扫码关注客户端消息推送

2-3-1、公众号关注消息处理

@Component
@Slf4j
public class WxMpSubscribeHandler implements WxMpMessageHandler {
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) throws WxErrorException {
        log.info("wxMessage={}",wxMessage);
        return WxMpXmlOutMessage.TEXT().
                fromUser(wxMessage.getToUser()).
                toUser(wxMessage.getFromUser()).
                content("欢迎关注,用户登录成功").
                build();
    }
}

2-3-2、公众号取消关注消息处理

@Component
@Slf4j
public class WxMpUnSubscribeHandler implements WxMpMessageHandler {
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) throws WxErrorException {
        log.info("wxMessage={}",wxMessage);
        return WxMpXmlOutMessage.TEXT().
                fromUser(wxMessage.getToUser()).
                toUser(wxMessage.getFromUser()).
                content("请别离开我").
                build();
    }
}

2-3-3、公众号扫码场景消息处理

@Component
@Slf4j
public class WxMpScanHandler implements WxMpMessageHandler {
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) throws WxErrorException {
        log.info("绑定系统用户成功,wxMessage={}",wxMessage);
        return WxMpXmlOutMessage.TEXT().
                content("用户登录成功!").
                fromUser(wxMessage.getToUser()).
                toUser(wxMessage.getFromUser()).
                build();
    }
}

2-4、消息路由


@Configuration
public class WeChartConfig {

    @Resource
    private WxMpSubscribeHandler wxMpSubscribeHandler;

    @Resource
    private WxMpUnSubscribeHandler wxUnSubscribeHandler;

    @Resource
    private WxMpScanHandler wxMpScanHandler;
    @Resource
    private WeChartWxMpService weChartWxMpService;

    @Bean
    public WxMpMessageRouter wxMpMessageRouter(){
        WxMpMessageRouter router = new WxMpMessageRouter(weChartWxMpService);
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE)
                .handler(wxMpSubscribeHandler).end();
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE)
                .handler(wxUnSubscribeHandler).end();
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SCAN)
                .handler(wxMpScanHandler).end();
        return router;
    }
}

公众号平台参考文档:
1、https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
2、https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId

公众号接口参考信息:
//获取accessToken
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=
//临时二维码获取ticket
https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s
//公众号获取用户信息接口
https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN

你可能感兴趣的:(微信,web项目开发,微信,java)