对象存储BOS

    代码示例

    代码示例

    示例代码以 Java 语言为例讲解美图 APP 的实现,代码分为 APP 客户端和应用服务器端两部分。

    APP 客户端代码样例

    APP 端代码主要包括 BOSClient 初始化、从 APP Server 端获取 BOS 信息、及上传文件到 BOS 三个功能模块。

    BOSClient 初始化

    public class bos {
    	private string ak = null;
        private string sk = null;
        private string endpoint = null;
        private string ststoken = null;
        private bosclient client = null;
    
        public bos(string ak, string sk, string endpoint, string ststoken) {
            this.ak = ak;
            this.sk = sk;
            this.endpoint = endpoint;
            this.ststoken = ststoken;
            client = createclient();
        }
    	
        public bosclient createclient() {
            bosclientconfiguration config = new bosclientconfiguration();
            bcecredentials credentials = null;
            if (ststoken != null && !ststoken.equalsignorecase("")) {
                credentials = new defaultbcesessioncredentials(ak, sk, ststoken);
            } else {
                credentials = new defaultbcecredentials(ak, sk);
            }
            config.setendpoint(endpoint);
            config.setcredentials(credentials);
            return new bosclient(config);
        }
    	
        public void uploadfile(string bucket, string object, file file) {
            client.putobject(bucket, object, file);
        }
    	
        public void uploadfile(string bucket, string object, inputstream inputstream) {
            client.putobject(bucket, object, inputstream);
        }
    	
        public void uploadfile(string bucket, string object, byte[] data) {
            client.putobject(bucket, object, data);
        }
    	
        public byte[] downloadfilecontent(string bucket, string object) {
            return client.getobjectcontent(bucket, object);
        }
    }

    上传文件到 BOS 代码实现

    public void uploadPicToBos() {
        // 1. get pic params from ui: file name, file location uri etc
        // 2. send params to app server and get sts, bucket name and region
        // 3. upload selected pic to bos with sts etc, which bos client needs
    
        EditText et = (EditText) findViewById(R.id.app_server_addr_edittext);
        final String appServerAddr = et.getText().toString();
    
    	    new Thread(new Runnable() {
            @Override
            public void run() {
                Map<String, Object> bosInfo = AppServer.getBosInfoFromAppServer(appServerAddr, "user-demo",
                        AppServer.BosOperationType.UPLOAD);
    
                if (bosInfo == null) {
                    return;
                }
                showToast(bosInfo.toString(), Toast.LENGTH_LONG);
    
                String ak = (String) bosInfo.get("ak");
                String sk = (String) bosInfo.get("sk");
                String stsToken = (String) bosInfo.get("stsToken");
                String endpoint = (String) bosInfo.get("endpoint");
                String bucketName = (String) bosInfo.get("bucketName");
                String objectName = (String) bosInfo.get("objectName");
                String prefix = (String) bosInfo.get("prefix");
                Log.i("UploadFileToBos", bosInfo.toString());
    
                // specify a object name if the app server does not specify one
                if (objectName == null || objectName.equalsIgnoreCase("")) {
                    objectName = ((EditText) findViewById(R.id.bos_object_name_edittext)).getText().toString();
                    if (prefix != null && !prefix.equalsIgnoreCase("")) {
                        objectName = prefix + "/" + objectName;
                    }
                }
    
                Bos bos = new Bos(ak, sk, endpoint, stsToken);
                try {
                    byte[] data = Utils.readAllFromStream(MainActivity.this.getContentResolver().openInputStream(selectedPicUri));
                    bos.uploadFile(bucketName, objectName, data);
                } catch (Throwable e) {
                    Log.e("MainActivity/Upload", "Failed to upload file to bos: " + e.getMessage());
                    showToast("Failed to upload file: " + e.getMessage());
                    return;
                }
                // finished uploading file, send a message to inform ui
                handler.sendEmptyMessage(UPLOAD_FILE_FINISHED);
            }
        }).start();
    }

    从 APP Server 上获取 BOS 信息代码实现

    public class AppServer {
        /**
         * get info from app server for the file to upload to or download from BOS
         *
         * @param appServerEndpoint app server
         * @param userName          the app user's name, registered in app server
         * @param bosOperationType  download? upload? or?
         * @return STS, and BOS endpoint, bucketName, prefix, path, object name etc
         */
        public static Map<String, Object> getBosInfoFromAppServer(String appServerEndpoint, String userName, BosOperationType bosOperationType) {
            String type = "";
            switch (bosOperationType) {
                // to simplify
                case UPLOAD: {
                    type = "upload";
                    break;
                }
                case DOWNLOAD: {
                    type = "download";
                    break;
                }
                case DOWNLOAD_PROCESSED: {
                    type = "download-processed";
                    break;
                }
                default:{
                    break;
                }
            }
            // TODO: this url should be url encoded
            String appServerUrl = appServerEndpoint + "/?" + "userName=" + userName + "&command=stsToken&type=" + type;
    
            // create a http client to contact app server to get sts
            HttpParams httpParameters = new BasicHttpParams();
            HttpClient httpClient = new DefaultHttpClient(httpParameters);
    	
            HttpGet httpGet = new HttpGet(appServerUrl);
            httpGet.addHeader("User-Agent", "bos-meitu-app/demo");
            httpGet.setHeader("Accept", "*/*");
            try {
                httpGet.setHeader("Host", new URL(appServerUrl).getHost());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            httpGet.setHeader("Accept-Encoding", "identity");
    	
            Map<String, Object> bosInfo = new HashMap<String, Object>();
            try {
                HttpResponse response = httpClient.execute(httpGet);
                if (response.getStatusLine().getStatusCode() != 200) {
                    return null;
                }
                HttpEntity entity = response.getEntity();
                long len = entity.getContentLength();
                InputStream is = entity.getContent();
                int off = 0;
                byte[] b = new byte[(int) len];
                while (true) {
                    int readCount = is.read(b, off, (int) len);
                    if (readCount < 0) {
                        break;
                    }
                    off += readCount;
                }
                Log.d("AppServer", new String(b, "utf8"));
                JSONObject jsonObject = new JSONObject(new String(b, "utf8"));
                Iterator<String> keys = jsonObject.keys();
                while (keys.hasNext()) {
                    String key = keys.next();
                    bosInfo.put(key, jsonObject.get(key));
                }
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
            return bosInfo;
        }
    	
        public enum BosOperationType {
            UPLOAD,
            DOWNLOAD,
            DOWNLOAD_PROCESSED,
        }
    }

    APP Server端代码样例

    APP Server 端基于 Jetty 框架,接口主要处理 Android APP 获取 BOS 信息的请求。APP Server 端会返回临时 AK、SK、Session Token、bucket 名称、资源路径和资源请求的 Endpoint 等参数。以下为 Jetty 处理的代码示例。

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
    
        // Inform jetty that this request has now been handled
        baseRequest.setHandled(true);
    
        if (!request.getMethod().equalsIgnoreCase("GET")) {
            response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
            return;
        }
    
        // expected url example: localhost:8080/?command=stsToken&type=download
        Map<String, String[]> paramMap = request.getParameterMap();
        if (paramMap.get("command") == null || paramMap.get("type") == null) {
            // invalid request
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
    
        if (!paramMap.get("command")[0].equalsIgnoreCase("stsToken")) {
            response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
            return;
        }
    
        String responseBody = "";
        responseBody = getBosInfo(paramMap.get("type")[0]);
    
        // Declare response encoding and types
        response.setContentType("application/json; charset=utf-8");
    
        // Declare response status code
        response.setStatus(HttpServletResponse.SC_OK);
    
        // Write back response, utf8 encoded
        response.getWriter().println(responseBody);
    }
    
    /**
     * Generates bos info needed by app according to requset type(upload, download etc)
     * this is the key part for uploading file to bos with sts token
     * @param bosRequestType 
     * @return utf8 encoded json string
     */
    public String getBosInfo(String bosRequestType) {
        // configuration for getting stsToken
        // bce bos credentials ak sk
        String bosAk = "your_bos_ak";
        String bosSk = "your_bos_sk";
        // bce sts service endpoint
        String stsEndpoint = "http://sts.bj.baidubce.com";
    
        BceCredentials credentials = new DefaultBceCredentials(bosAk, bosSk);
        BceClientConfiguration clientConfig = new BceClientConfiguration();
        clientConfig.setCredentials(credentials);
        clientConfig.setEndpoint(stsEndpoint);
        StsClient stsClient = new StsClient(clientConfig);
        GetSessionTokenRequest stsReq = new GetSessionTokenRequest();
        // request expiration time
        stsReq.setDurationSeconds(1800);
        GetSessionTokenResponse stsToken = stsClient.getSessionToken(stsReq);
        String stsTokenAk = stsToken.getCredentials().getAccessKeyId();
        String stsTokenSk = stsToken.getCredentials().getSecretAccessKey();
        String stsTokenSessionToken = stsToken.getCredentials().getSessionToken();
    
        // **to simplify this demo there is no difference between "download" and "upload"**
        // parts of bos info
        String bosEndpoint = "http://bj.bcebos.com";
        String bucketName = "bos-android-sdk-app";
        if (bosRequestType.equalsIgnoreCase("download-processed")) {
            // the binded image processing domain set by App developer on bce console
            bosEndpoint = "http://" + bucketName + ".bj.bcebos.com";
        }
    
        // prefix is the bucket name, and does not specify the object name
        BosInfo bosInfo = new BosInfo(stsTokenAk, stsTokenSk, stsTokenSessionToken, bosEndpoint,
                bucketName, "", bucketName);
    
        String res = "";
        ObjectMapper mapper = new ObjectMapper();
        try {
            res = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bosInfo);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            res = "";
        }
        try {
            res = new String(res.getBytes(), "utf8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            res = "";
        }
        return res;
    }  
    上一篇
    基于BOS使用美图APP
    下一篇
    HTTPS传输加密实践