jfinal框架增加微信jsapi支持

部分手机在图片上传的时候,调取不到sd卡相册或其他图片,为了解决这个兼容性问题,同一个页面使用了两种图片上传方案。

  1. html5 :图片编码成base64 ,发送到后台,解码存储。这种方法用于解决非微信浏览器的上传问题。

  2. jsapi:用于解决微信浏览器的上传问题。

思路:

首先判断是否是微信浏览器(微信js接口提供方法),然后调用上面不同的方法。

这里记下jfinal整合jsapi的关键代码和流程 。


前端页面需要一段javascript ,官方文档有详细说明,以下我的config

  1.     
        wx.config({
    
            debug: true,
            appId: 'wx23eeb004xxxx8ecb', // 必填,公众号的唯一标识
            timestamp:'${timestamp}', // 必填,生成签名的时间戳
            nonceStr: 't8bI2mW5Mxxxx20Y', // 必填,生成签名的随机串
            signature: '${signature}',
            jsApiList: [
               'chooseImage'
                       ]
        });

以下是前端页面对应的ctrl ,惯例只是关键部分

//微信
        ApiConfig ac = new ApiConfig();
        String token = ConfigUtil.get("weixinToken");
        String appid = ConfigUtil.get("weixinAppId");
        String secret = ConfigUtil.get("weixinSecret");
        // 配置微信 API 相关常量
        ac.setToken(token);
        ac.setAppId(appid);
        ac.setAppSecret(secret);
        /**
         *  是否对消息进行加密,对应于微信平台的消息加解密方式:
         *  1:true进行加密且必须配置 encodingAesKey
         *  2:false采用明文模式,同时也支持混合模式
         */
        ac.setEncryptMessage(false);
        ac.setEncodingAesKey(ConfigUtil.get("weixinEncodingAESKey"));

        ApiConfigKit.setThreadLocalApiConfig(ac); //必须

        JssdkTicket jssdkTicket = JssdkTicketUtil.getJssdkTicket();

        if (!jssdkTicket.getErrmsg().equals("ok")){
            setAttr("errormsg","如需使用图片上传功能,请刷新页面重试");
        }else {
            String fuckU= DateUtil.getCurMis().toString().substring(0,10);

            String tempStr = new StringBuilder().append("jsapi_ticket=" + jssdkTicket.getTicket() + "&noncestr=t8bI2mW5Mma0I20Y&timestamp=" + fuckU + "&url=" + getRequest().getRequestURL()+"").toString();
            System.out.println("string1="+tempStr);

            tempStr = EncryptionKit.sha1Encrypt(tempStr);
            System.out.println("加密后="+tempStr);

            setAttr("timestamp", fuckU);
            setAttr("signature",tempStr);

        }

        createToken("blogToken", 30 * 60);
        render(AppConst.PATH_WAP_PC+"/abc.ftl");


以下是JssdkTicketUtil ,该util用于缓存jsapi_ticket,也是微信官方文档中一再强调的东西

public class JssdkTicketUtil {

    private static JssdkTicket jssdkTicket;

    public static JssdkTicket getJssdkTicket() {
        if(jssdkTicket != null && jssdkTicket.isAvailable()) {
            return jssdkTicket;
        } else {
            refreshAccessToken();
            return jssdkTicket;
        }
    }

    private static void refreshAccessToken() {
        jssdkTicket = requestJssdkTicket();
    }

    private static synchronized JssdkTicket requestJssdkTicket() {

        JssdkTicket result = null;
        AccessToken accessToken = AccessTokenApi.getAccessToken();

        String json = HttpKit.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken.getAccessToken() + "&type=jsapi");

        result = new JssdkTicket(json);

        if(!result.isAvailable()) {
            refreshAccessToken();
        }

        return result;

    }

}

以下是jssdkTicket ,用于存储信息

public class JssdkTicket {

    private String jsapi ;//服务器返回
    private Long expiredTime ; //过期时间

    private Integer errcode;  //错误码
    private String errmsg; //错误信息
    private String ticket; //票据

    private Integer expires_in; //


    public JssdkTicket(String jsapiStr){
        this.jsapi = jsapiStr;


        try {
            Map e = (Map)(new ObjectMapper()).readValue(jsapiStr, Map.class);
            this.expires_in = (Integer)e.get("expires_in");
            this.errcode = (Integer)e.get("errcode");
            this.errmsg = (String)e.get("errmsg");
            this.ticket = (String)e.get("ticket");

            if(this.expires_in != null) {
                this.expiredTime = Long.valueOf(System.currentTimeMillis() + (long)((this.expires_in.intValue() - 5) * 1000));
            }

        } catch (Exception var3) {
            throw new RuntimeException(var3);
        }
    }


    public boolean isAvailable() {
        return this.expiredTime == null ? false : (this.errcode != 0 ? false : (this.expiredTime.longValue() < System.currentTimeMillis() ? false : this.ticket != null));
    }

    public String getJsapi() {
        return jsapi;
    }

    public Long getExpiredTime() {
        return expiredTime;
    }


    public Integer getErrcode() {
        return errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public String getTicket() {
        return ticket;
    }

    public Integer getExpires_in() {
        return expires_in;
    }
}

以上两个类完成参照jfinal-weixin-1.2中对access_token的处理方式 。感谢jfinal作者  @jfinal

:::::::::::::::::::::::::::::::::::::::::::::::::::

2015-05-29 16:29:58 更新

图片上传完成后,需要从微信服务器下载图片并保存到本地服务器

savePath = HttpClientKit.getFileAndSave("http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + ss.getAccessToken() + "&media_id=" + list.get(i));

PS:savePath是本地服务器的保存路径

getFileAndSave方法的关键代码如下(需要引入commons-httpclient.jar):

/**
     * 从微信服务器取图片并保存到服务器指定路径
     * @param url 微信服务器路径
     * @return 本地服务器路径
     */
    public static String getFileAndSave(String url) {

        String result = "";


        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String ymd = sdf.format(new Date());

        String savePath = PathKit.getWebRootPath() + "/photo/"+ymd+"/";


        File uploadDir = new File(savePath);

        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        if (!uploadDir.isDirectory()) {
            return "1"; //上传目录不存在。

        }

        if (!uploadDir.canWrite()) {
            return "2"; //上传目录没有写权限
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); // 时间戳
        String newFileName = df.format(new Date()) + "_"
                + new Random().nextInt(1000) + ".jpg"; // 拼文件名

        savePath += newFileName;
        result = "/photo/"+ymd+"/" + newFileName;

        HttpClient client = new HttpClient();

        GetMethod get = new GetMethod(url);

//        String filePath = FileKit.getSaveRealPath("jpg");

        try {
            File storeFile = new File(savePath);
            FileOutputStream output = null;
            client.executeMethod(get);
            output = new FileOutputStream(storeFile);
            output.write(get.getResponseBody());
            output.close();
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }


你可能感兴趣的:(jfinal框架增加微信jsapi支持)