Java微信公众平台开发_07_JSSDK图片上传
一、本节要点
1.获取jsapi_ticket
- //2.获取getJsapiTicket的接口地址,有效期为7200秒
- private static final String GET_JSAPITICKET_URL="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
- /**
- * @desc :2.获取JsapiTicket
- *
- * @param accessToken 有效凭证
- * @return
- * @throws Exception String
- */
- public static String getJsapiTicket(String accessToken) throws Exception {
- //1.获取请求url
- String url=GET_JSAPITICKET_URL.replace("ACCESS_TOKEN", accessToken);
- //2.发起GET请求,获取返回结果
- JSONObject jsonObject=HttpHelper.doGet(url);
- logger.info("jsonObject:"+jsonObject.toJSONString());
- //3.解析结果,获取accessToken
- String jsapiTicket="";
- if (null != jsonObject) {
- //4.错误消息处理
- if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {
- int errCode = jsonObject.getInteger("errcode");
- String errMsg = jsonObject.getString("errmsg");
- throw new Exception("error code:"+errCode+", error message:"+errMsg);
- //5.成功获取jsapiTicket
- }else {
- jsapiTicket=jsonObject.getString("ticket");
- }
- }
- return jsapiTicket;
- }
2.JS-SDK 使用权限签名算法
- /**
- * @desc :4.获取前端jsapi需要的配置参数
- *
- * @param request
- * @return String
- */
- public static String getJsapiConfig(HttpServletRequest request){
- //1.准备好参与签名的字段
- //1.1 url
- /*
- *以http://localhost/test.do?a=b&c=d为例
- *request.getRequestURL的结果是http://localhost/test.do
- *request.getQueryString的返回值是a=b&c=d
- */
- String urlString = request.getRequestURL().toString();
- String queryString = request.getQueryString();
- String queryStringEncode = null;
- String url;
- if (queryString != null) {
- queryStringEncode = URLDecoder.decode(queryString);
- url = urlString + "?" + queryStringEncode;
- } else {
- url = urlString;
- }
- //1.2 noncestr
- String nonceStr=UUID.randomUUID().toString(); //随机数
- //1.3 timestamp
- long timeStamp = System.currentTimeMillis() / 1000; //时间戳参数
- String signedUrl = url;
- String accessToken = null;
- String ticket = null;
- String signature = null; //签名
- try {
- //1.4 jsapi_ticket
- accessToken=getAccessToken(Env.APP_ID, Env.APP_SECRET);
- ticket=getJsapiTicket(accessToken);
- //2.进行签名,获取signature
- signature=getSign(ticket,nonceStr,timeStamp,signedUrl);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- logger.info("accessToken:"+accessToken);
- logger.info("ticket:"+ticket);
- logger.info("nonceStr:"+nonceStr);
- logger.info("timeStamp:"+timeStamp);
- logger.info("signedUrl:"+signedUrl);
- logger.info("signature:"+signature);
- logger.info("appId:"+Env.APP_ID);
- String configValue = "{signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'"
- + timeStamp + "',appId:'" + Env.APP_ID + "'}";
- logger.info("configValue:"+configValue);
- return configValue;
- }
- /**
- * @desc : 4.1 生成签名的函数
- *
- * @param ticket jsticket
- * @param nonceStr 随机串,自己定义
- * @param timeStamp 生成签名用的时间戳
- * @param url 需要进行免登鉴权的页面地址,也就是执行dd.config的页面地址
- * @return
- * @throws Exception String
- */
- public static String getSign(String jsTicket, String nonceStr, Long timeStamp, String url) throws Exception {
- String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + timeStamp + "&url=" + url;
- System.out.println(plainTex);
- try {
- MessageDigest crypt = MessageDigest.getInstance("SHA-1");
- crypt.reset();
- crypt.update(plainTex.getBytes("UTF-8"));
- return byteToHex(crypt.digest());
- } catch (NoSuchAlgorithmException e) {
- throw new Exception(e.getMessage());
- } catch (UnsupportedEncodingException e) {
- throw new Exception(e.getMessage());
- }
- }
- /**
- * @desc :4.2 将bytes类型的数据转化为16进制类型
- *
- * @param hash
- * @return
- * String
- */
- private static String byteToHex(byte[] hash) {
- Formatter formatter = new Formatter();
- for (byte b : hash) {
- formatter.format("%02x", new Object[] { Byte.valueOf(b) });
- }
- String result = formatter.toString();
- formatter.close();
- return result;
- }
2.1 签名生成规则
(1)参与签名的字段包括:
noncestr(随机字符串),
有效的jsapi_ticket,
timestamp(时间戳),
url(当前网页的URL,不包含#及其后面部分) 。
(2)对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
(3)对string1进行sha1签名,得到signature:
2.2 签名算法应用实例
(1)待签名参数:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com
(2)字典序
string1=jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-
HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com
(3)sha1加密
signature=sha1(string1)
3.JS-SDK使用步骤
(1)绑定域名
测试号:
(2)引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
- <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
(3)通过config接口注入权限验证配置
- //1.jsapi签名校验
- wx.config({
- beta: true,// 必须这么写,否则在微信插件有些jsapi会有问题
- debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
- appId: _config.appId, // 必填,公众号的唯一标识
- timestamp: _config.timeStamp, // 必填,生成签名的时间戳
- nonceStr: _config.nonceStr, // 必填,生成签名的随机串
- signature: _config.signature,// 必填,签名,见附录1
- jsApiList: [ 'checkJsApi', 'onMenuShareAppMessage',
- 'onMenuShareWechat', 'startRecord', 'stopRecord',
- 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice',
- 'uploadVoice', 'downloadVoice', 'chooseImage',
- 'previewImage', 'uploadImage', 'downloadImage',
- 'getNetworkType', 'openLocation', 'getLocation',
- 'hideOptionMenu', 'showOptionMenu', 'hideMenuItems',
- 'showMenuItems', 'hideAllNonBaseMenuItem',
- 'showAllNonBaseMenuItem', 'closeWindow', 'scanQRCode',
- 'previewFile', 'openEnterpriseChat',
- 'selectEnterpriseContact','chooseInvoice'
- ]// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
- });
(4)通过ready接口处理成功验证
(5) 通过error接口处理失败验证
- //2.jsapi签名校验失败后执行error
- wx.error(function(err){
- alert('wx error: ' + JSON.stringify(err));
- // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
- });
4.图片上传
4.1 图片上传的流程
(1)使用 jssdk 上传图片到微信服务器,返回图片对应的mediaId( 即 serverId)
- //2.2 上传图片
- var images = {
- localId : [],
- serverId : []
- };
- $("#uploadImg").click(function(){
- //2.2.1拍照或从手机相册中选图
- wx.chooseImage({
- success : function(res) {
- images.localId = res.localIds;
- alert('已选择 ' + res.localIds.length + ' 张图片');
- //2.2.2 上传图片
- uploadImg();
- }
- });
- });
- // 2.2.2 上传图片
- function uploadImg() {
- if (images.localId.length == 0) {
- alert('请先使用 chooseImage 接口选择图片');
- return;
- }
- var i = 0, length = images.localId.length;
- images.serverId = [];
- function upload() {
- wx.uploadImage({
- localId : images.localId[i],
- success : function(res) {
- i++;
- alert('已上传:' + i + '/' + length);
- images.serverId.push(res.serverId);
- //将serverId上传至服务器
- alert("ajax请求即将执行--");
- $.ajax({
- type : "POST",
- url : "http://se9mxs.natappfree.cc/weixin_gz/uploadimg",
- data : {
- serverId : res.serverId
- },
- dataType : "text",
- success : function(data) {
- alert(data);
- }
- });
- if (i < length) {
- upload();
- }
- },
- fail : function(res) {
- alert(JSON.stringify(res));
- }
- });
- }
- upload();
- };
(2)使用素材管理接口,根据 mediaId 从微信服务器将图片下载至服务器本地。参见:Java微信公众平台开发_06_素材管理
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String mediaId=request.getParameter("serverId");
- System.out.println("serverId:"+mediaId);
- try {
- String accessToken=AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET);
- //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png";
- String fileDir=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";
- System.out.println("fileDir:"+fileDir);
- //2.调用业务类,获取临时素材
- TempMaterialService.getTempMaterial(accessToken, mediaId, fileDir);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- PrintWriter out = response.getWriter();
- out.print("HHHHHHHHHH");
- out.close();
- out = null;
- }
二、代码实现
1.前端页面—uploadImg.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>JSSDK之上传图片</title>
- <script src="js/jquery-3.2.1.min.js"></script>
- <script type="text/javascript"
- src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
- <script type="text/javascript">
- var _config =
- <%=com.ray.weixin.gz.util.AuthHelper.getJsapiConfig(request)%>
- ;
- </script>
- <script type="text/javascript" src="js/auth.js"></script>
- </head>
- <body>
- <div align="center">
- <img id="userImg" alt="头像" src="">
- </div>
- <div align="center">
- <span>UserName:</span>
- <div id="userName" style="display: inline-block"></div>
- </div>
- <div align="center">
- <span>UserId:</span>
- <div id="userId" style="display: inline-block"></div>
- </div>
- <div align="center">
- <span class="desc">是否验证成功</span>
- <button class="btn btn_primary" id="yanzheng">验证</button>
- </div>
- <div align="center">
- <span class="desc">测试按钮</span>
- <button class="btn btn_primary" id="ceshi">测试</button>
- </div>
- <div align="center">
- <span class="desc">上传图片按钮</span>
- <button class="btn btn_primary" id="uploadImg">上传图片</button>
- </div>
- <div align="center">
- <span class="desc">拍照上传图片按钮</span>
- <button class="btn btn_primary" id="uploadImgFromCamera">拍照上传</button>
- </div>
- <div align="center">
- <span class="desc">扫码按钮</span>
- <button class="btn btn_primary" id="qrcode" >扫码</button>
- </div>
- </body>
- </html>
auth.js
- //1.jsapi签名校验
- wx.config({
- beta: true,// 必须这么写,否则在微信插件有些jsapi会有问题
- debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
- appId: _config.appId, // 必填,公众号的唯一标识
- timestamp: _config.timeStamp, // 必填,生成签名的时间戳
- nonceStr: _config.nonceStr, // 必填,生成签名的随机串
- signature: _config.signature,// 必填,签名,见附录1
- jsApiList: [ 'checkJsApi', 'onMenuShareAppMessage',
- 'onMenuShareWechat', 'startRecord', 'stopRecord',
- 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice',
- 'uploadVoice', 'downloadVoice', 'chooseImage',
- 'previewImage', 'uploadImage', 'downloadImage',
- 'getNetworkType', 'openLocation', 'getLocation',
- 'hideOptionMenu', 'showOptionMenu', 'hideMenuItems',
- 'showMenuItems', 'hideAllNonBaseMenuItem',
- 'showAllNonBaseMenuItem', 'closeWindow', 'scanQRCode',
- 'previewFile', 'openEnterpriseChat',
- 'selectEnterpriseContact','chooseInvoice'
- ]// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
- });
- //2.jsapi签名校验成功后执行ready
- wx.ready(function(){
- // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
- //2.1 提示jsapi签名验证成功
- $("#yanzheng").html("验证成功");
- $("#ceshi").click(function(){
- alert("ceshiaaa");
- });
- $("#checkJsApi").click(function(){
- wx.checkJsApi({
- jsApiList: [ 'checkJsApi', 'onMenuShareAppMessage',
- 'onMenuShareWechat', 'startRecord', 'stopRecord',
- 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice',
- 'uploadVoice', 'downloadVoice', 'chooseImage',
- 'previewImage', 'uploadImage', 'downloadImage',
- 'getNetworkType', 'openLocation', 'getLocation',
- 'hideOptionMenu', 'showOptionMenu', 'hideMenuItems',
- 'showMenuItems', 'hideAllNonBaseMenuItem',
- 'showAllNonBaseMenuItem', 'closeWindow', 'scanQRCode',
- 'previewFile', 'openEnterpriseChat',
- 'selectEnterpriseContact','chooseInvoice'
- ], // 需要检测的JS接口列表,所有JS接口列表见附录2,
- success: function(res) {
- // 以键值对的形式返回,可用的api值true,不可用为false
- // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
- }
- });
- });
- //2.2 上传图片
- var images = {
- localId : [],
- serverId : []
- };
- $("#uploadImg").click(function(){
- //2.2.1拍照或从手机相册中选图
- wx.chooseImage({
- success : function(res) {
- images.localId = res.localIds;
- alert('已选择 ' + res.localIds.length + ' 张图片');
- //2.2.2 上传图片
- uploadImg();
- }
- });
- });
- // 2.2.2 上传图片
- function uploadImg() {
- if (images.localId.length == 0) {
- alert('请先使用 chooseImage 接口选择图片');
- return;
- }
- var i = 0, length = images.localId.length;
- images.serverId = [];
- function upload() {
- wx.uploadImage({
- localId : images.localId[i],
- success : function(res) {
- i++;
- alert('已上传:' + i + '/' + length);
- images.serverId.push(res.serverId);
- //将serverId上传至服务器
- alert("ajax请求即将执行--");
- $.ajax({
- type : "POST",
- url : "http://se9mxs.natappfree.cc/weixin_gz/uploadimg",
- data : {
- serverId : res.serverId
- },
- dataType : "text",
- success : function(data) {
- alert(data);
- }
- });
- if (i < length) {
- upload();
- }
- },
- fail : function(res) {
- alert(JSON.stringify(res));
- }
- });
- }
- upload();
- };
- //2.3 扫一扫
- $("#qrcode").click(function(){
- wx.scanQRCode({
- needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
- scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
- success: function (res) {
- var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
- alert(result);
- },
- fail:function (res) {
- var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
- alert(result);
- }
- });
- });
- //2.4 拉起发票列表
- //注意,调用此接口时,config接口必须传入beta参数。
- $("#showInvoice").click(function(){
- alert("timestamp:"+invoice_config.timestamp);
- alert("nonceStr:"+invoice_config.nonceStr);
- alert("signType:"+invoice_config.signType);
- alert("cardSign:"+invoice_config.cardSign);
- wx.invoke('chooseInvoice', {
- 'timestamp': invoice_config.timestamp, // 卡券签名时间戳
- 'nonceStr' : invoice_config.nonceStr, // 卡券签名随机串
- 'signType' : invoice_config.signType, // 签名方式,默认'SHA1'
- 'cardSign' : invoice_config.cardSign, // 卡券签名
- }, function(res) {
- // 这里是回调函数
- alert("aaaaaa");
- alert(JSON.stringify(res)); // 返回的结果
- });
- });
- });
- //2.jsapi签名校验失败后执行error
- wx.error(function(err){
- alert('wx error: ' + JSON.stringify(err));
- // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
- });
2.web.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
- <display-name>weixin_gz</display-name>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>default.html</welcome-file>
- <welcome-file>default.htm</welcome-file>
- <welcome-file>default.jsp</welcome-file>
- </welcome-file-list>
- <!--微信公众号回调-->
- <servlet>
- <servlet-name>weixin</servlet-name>
- <servlet-class>com.ray.weixin.gz.controller.WeiXinServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>weixin</servlet-name>
- <url-pattern>/weixin</url-pattern>
- </servlet-mapping>
- <!-- 微信公众号回调-->
- <servlet>
- <description></description>
- <display-name>uploadimg</display-name>
- <servlet-name>uploadimg</servlet-name>
- <servlet-class>com.ray.weixin.gz.controller.UploadImgServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>uploadimg</servlet-name>
- <url-pattern>/uploadimg</url-pattern>
- </servlet-mapping>
- </web-app>
3.上传图片servlet—UploadImgServlet
- package com.ray.weixin.gz.controller;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import com.ray.weixin.gz.config.Env;
- import com.ray.weixin.gz.service.tempmaterial.TempMaterialService;
- import com.ray.weixin.gz.util.AuthHelper;
- /**
- * Servlet implementation class UploadImgServlet
- */
- public class UploadImgServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /**
- * @see HttpServlet#HttpServlet()
- */
- public UploadImgServlet() {
- super();
- // TODO Auto-generated constructor stub
- }
- /**
- * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
- */
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // TODO Auto-generated method stub
- response.getWriter().append("Served at: ").append(request.getContextPath());
- }
- /**
- * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
- */
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String mediaId=request.getParameter("serverId");
- System.out.println("serverId:"+mediaId);
- try {
- String accessToken=AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET);
- //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png";
- String fileDir=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";
- System.out.println("fileDir:"+fileDir);
- //2.调用业务类,获取临时素材
- TempMaterialService.getTempMaterial(accessToken, mediaId, fileDir);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- PrintWriter out = response.getWriter();
- out.print("HHHHHHHHHH");
- out.close();
- out = null;
- }
- }
4.素材管理业务类—TempMaterialService.java
- package com.ray.weixin.gz.controller;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import com.ray.weixin.gz.config.Env;
- import com.ray.weixin.gz.service.tempmaterial.TempMaterialService;
- import com.ray.weixin.gz.util.AuthHelper;
- /**
- * Servlet implementation class UploadImgServlet
- */
- public class UploadImgServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /**
- * @see HttpServlet#HttpServlet()
- */
- public UploadImgServlet() {
- super();
- // TODO Auto-generated constructor stub
- }
- /**
- * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
- */
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- // TODO Auto-generated method stub
- response.getWriter().append("Served at: ").append(request.getContextPath());
- }
- /**
- * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
- */
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String mediaId=request.getParameter("serverId");
- System.out.println("serverId:"+mediaId);
- try {
- String accessToken=AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET);
- //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png";
- String fileDir=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";
- System.out.println("fileDir:"+fileDir);
- //2.调用业务类,获取临时素材
- TempMaterialService.getTempMaterial(accessToken, mediaId, fileDir);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- PrintWriter out = response.getWriter();
- out.print("HHHHHHHHHH");
- out.close();
- out = null;
- }
- }
其他的同上一节
Java微信公众平台开发_07_JSSDK图片上传的更多相关文章
- Java微信公众平台开发_02_启用服务器配置
源码将在晚上上传到 github 一.准备阶段 需要准备事项: 1.一个能在公网上访问的项目: 见:[ Java微信公众平台开发_01_本地服务器映射外网 ] 2.一个微信公众平台账号: 去注册: ...
- Java微信公众平台开发【番外篇】(七)--公众平台测试帐号的申请
转自:http://www.cuiyongzhi.com/post/45.html 前面几篇一直都在写一些比较基础接口的使用,在这个过程中一直使用的都是我个人微博认证的一个个人账号,原本准备这篇是写[ ...
- Java微信公众平台开发--番外篇,对GlobalConstants文件的补充
转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...
- Java微信公众平台开发(十二)--微信用户信息的获取
转自:http://www.cuiyongzhi.com/post/56.html 前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信 ...
- Java微信公众平台开发(十)--微信用户信息的获取
前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...
- Java微信公众平台开发(一)--接入微信公众平台
转自:http://www.cuiyongzhi.com/post/38.html (一)接入流程解析 在我们的开发过程中无论如何最好的参考工具当然是我们的官方文档了:http://mp.weixin ...
- Java微信公众平台开发(七)--多媒体消息回复之图片回复
之前我们在做消息回复的时候我们对回复的消息简单做了分类,前面也有讲述如何回复[普通消息类型消息],这里将讲述多媒体消息的回复方法,[多媒体消息]包含回复图片消息/回复语音消息/回复视频消息/回复音乐消 ...
- Java微信公众平台开发_03_消息管理之被动回复消息
GitHub源码:https://github.com/shirayner/weixin_gz 一.本节要点 1.回调url 上一节,我们启用服务器配置的时候,填写了一个服务器地址(url),如下图, ...
- Java微信公众平台开发之获取地理位置
本部分需要用到微信的JS-SDK,微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包.通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统 ...
随机推荐
- 【小程序】调用wx.request接口时需要注意的问题
写在前面 之前写了一篇<微信小程序实现各种特效实例>,上次的小程序的项目我负责大部分前端后台接口的对接,然后学长帮我改了一些问题.总的来说,收获了不少吧! 现在项目已经完成,还是要陆陆续续 ...
- memcached讲解
Memcached 最近空闲的是时候研究了一下缓存,根据公司环境对缓存进行了系统的了解,我们使用memcacheed进行缓存,下面结合我的 理解,以及网上的相关资料,memecached进行讲解. m ...
- Entity Framework相关介绍
在深入学习某项技术之前,应该努力形成对此技术的总体印象,并了解其基本原理,本文的目的就在于此. 一.理解EF数据模型 EF本质上是一个ORM框架,它需要把对象映射到底层数据库中的表,为此,它使用了三个 ...
- 阿里巴巴 Java 开发规约插件初体验
阿里巴巴 Java 开发手册 又一次来谈<阿里巴巴 Java 开发手册>,经过这大半年的版本迭代,这本阿里工程师们总结出来避免写出那么多 Bug 的规范,对于 Java 开发者简直就是必备 ...
- php 变量 循环关键词以及方法
<?php/* 多行注释 */常用数据类型int string double/float bool变量的定义$a = 123;$b = "123";$c = '456';$d ...
- C#使用Xamarin开发可移植移动应用进阶篇(10.综合演练,来一份增删改查CRUD)
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 呃 也有半 ...
- win10 uwp 简单MasterDetail
中文 English 本文主要讲实现一个简单的界面,可以在窗口比较大显示列表和内容,窗口比较小时候显示列表或内容.也就是在窗口比较小的时候,点击列表会显示内容,点击返回会显示列表. 先放图,很简单. ...
- 解析PHP多种序列化与反序列化的方法
1. serialize和unserialize函数这两个是序列化和反序列化PHP中数据的常用函数. 复制代码 代码如下: <?php$a = array('a'=> 'Apple' ,' ...
- KDevelop使用笔记【中文】
师从官方文档: https://userbase.kde.org/KDevelop4/Manual https://docs.kde.org/trunk5/en/extragear-kdevelop/ ...
- 【转】IO流程
原文地址:http://blog.chinaunix.net/uid-26922071-id-3954900.html IO之流程与buffer概览 为了说明这个流程,还是用图来描述一下比较直观. ...