jfinal框架增長微信jsapi支持

部分手機在圖片上傳的時候,調取不到sd卡相冊或其餘圖片,爲了解決這個兼容性問題,同一個頁面使用了兩種圖片上傳方案。javascript

  1. html5 :圖片編碼成base64 ,發送到後臺,解碼存儲。這種方法用於解決非微信瀏覽器的上傳問題。html

  2. jsapi:用於解決微信瀏覽器的上傳問題。前端

思路:html5

首先判斷是不是微信瀏覽器(微信js接口提供方法),而後調用上面不一樣的方法。java

這裏記下jfinal整合jsapi的關鍵代碼和流程 。json


前端頁面須要一段javascript ,官方文檔有詳細說明,如下個人configapi

  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;
    }
相關文章
相關標籤/搜索