百度智能云

All Product Document

          Object Storage

          Mobile Meitu APP Practice

          Scenarios Overview

          In the era of mobile Internet, the data upload by mobile phone is common everywhere. In order to facilitate developers to focus on the business logic of products, users can directly save files on BOS. BOS products provide users with safe upload and download methods based on STS authorization, and BOS also supports image processing services. BOS features in low cost, supporting mass storage and elastic expansion, which can help developers to develop mobile APP business more easily.

          This tutorial can help users quickly build a BOS based file direct transmission + image processing mobile APP, which is primarily based on three modules: STS temporary authorization, Android SDK and image processing API.

          • Due to the risk of user's mobile application leaking, it is impossible to directly save AK/SK information, so STS temporary authorization mode must be used to access BOS. STS temporary authorization mode will generate a temporary token, which has a certain timeliness. That is, APP applications can complete the upload or download picture service only when they access within the timeliness of the token, which shall be retrieved after the expiration.
          • Android SDK helps users create a new BOS client and save files in BOS or download files from BOS.
          • The image processing API primarily implements the functions of image processing, such as zooming, clipping, format conversion, rotation, adding textimage/watermark, etc.

          The data interaction of mobile Meitu APP is as follows:

          image_4ec9c1a.png

          Example of Meitu APP

          Download address of mobile Meitu example APP:

          After downloading and installing APP, you can directly access BOS through the application server address and process the pictures. The application server address refers to the background server for building mobile application. The default enabled port is 8080. Both the BOS region and bucket settings need to be configured in the application server.

          APP Operation Method

          APP supports three functions: upload, download and download zoom image.

          • Upload: After the user fills in the application server address, select the local image to upload. The image will be displayed under the operation interface, and then click Upload. If the upload is successful, "File Uploaded" will be displayed.
          • Download: The user fills in the name of the file to download and clicks Download. If the download is successful, "File Downloaded" will be displayed.
          • Download zoomed image: When downloading a zoomed image, specify a clear image suffix, such as jpg, and then set the width, height and rotation angle of the downloaded image. Click Download zoomed image to get the processed image. If the download is successful, "File Downloaded" will be displayed. The pictures downloaded from demo will not be stored locally.

          How to Build Meitu APP

          Building Meitu APP includes following steps:

          1.Enable BOS service and create bucket to store pictures. For detailed operations of opening and creating a bucket, please see Create Bucket. To download the zoom image, ensure that the specified bucket has the image processing service enabled. 2.Open STS Service to ensure the security of uploading and downloading pictures. 3.Deploy the application server to realize the interaction with BOS and client. For the code of Meitu APP, please see: BOS Meitu APP Code. 4.Download and install Meitu APP.

          How to Deploy Application Server

          1.Download the code package of Sample Code from github. The code package primarily includes two parts: "bos_meitu_app" and "bos_meitu_app_server". Among them, "bos_meitu_app" is primarily used to define the APP interface and related actions, and" bos_meitu_app_server" is the application server related configuration.

          2.Modify "MeituAppServerHandler.java" file in "bos_meitu_app_server", which defines Endpoint and bucket name corresponding to ak/sk and BOS server.

           public String getBosInfo(String bosRequestType) {
                //Configure ak, sk
                String bosAk = "developer's ak";
                String bosSk = "developer's SK";
                //stsendpoint provided by Baidu AI Cloud 
                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();
          
                // Endpoint address and bucket name of BOS service. 
                String bosEndpoint = "http://bj.bcebos.com";
                String bucketName = "bucket name";
                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) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    res = "";
                }
                System.out.println(res);
                try {
                    res = new String(res.getBytes(), "utf8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    res = "";
                }
                return res;
            }

          3.Recompile and package the modified server code as bos_meitu_app_server.jar, upload the jar package to the application server and execute the command java -jar bos_meitu_app_server.jar .

          Interaction Process

          Upload Pictures to BOS

          The interaction process of APP, APP server and BOS during uploading pictures to BOS is shown in the following figure:

          BOS_meituAPP_upload.png

          1.When the APP uploads a picture, it sends a request to APP server to get the upload method. 2.APP Server requests AK/SK accessed by STS from BOS to STS server, and STS server returns STS credentials to APP Server, including temporary AK, SK and Session Token. 3.APP Server returns STS voucher and upload method parameters, including bucket name, Endpoint, etc. 4.APP uploads the file to BOS according to the returned information, and BOS will return the upload result to APP. 5.APP can provide upload results to APP Server as required.

          Download Pictures from BOS

          The interaction process of APP, APP Server and BOS in the process of downloading pictures from BOS is shown in the following figure:

          BOS_meituAPP_download.png

          1.When the APP downloads pictures, it sends a request to the APP Server to get the download method. 2.APP Server requests AK/SK accessed by STS from BOS to STS server, and STS server returns STS credentials to APP Server, including temporary AK, SK and Session Token. 3.APP Server returns the STS voucher and download method parameters to the APP. The download method parameters include bucket name, Endpoint, etc. 4.Based on the returned information 5.APP downloads the file from BOS, and BOS will return the download result to APP. 6.APP can provide download results to APP Server as required.

          Download Zoomed Image from BOS

          The interaction process of APP, APP Server and BOS in the process of downloading zoomed image from BOS is shown in the following figure:

          BOS_meituAPP_download_Processed.png

          The interactive process of downloading the zoomed image from BOS is basically similar to that of downloading the image from BOS, except that when downloading the zoomed image from BOS, you need to carry the image processing parameters set on the APP, such as image width, height, rotation angle, etc.

          Sample Code

          The example code takes Java language as an example to explain the implementation of Meitu APP. The code consists of two parts: APP client and application server.

          APP Client Code Example

          APP end code primarily includes three function modules: BOSClient initialization, obtaining BOS information from APP Server end, and uploading files to BOS.

          BOSclient Initialization

          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);
              }
          }

          Upload File to BOS Code

          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();
          }

          Get BOS Information Code from APP Server

          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 Code Example

          APP Server is based on the Jetty framework, and the interface primarily deals with Android APP's request for BOS information. APP Server will return parameters such as temporary AK, SK, Session Token, bucket name, resource path and Endpoint of resource request. The following is an example of the code processed by 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;
          }
          Previous
          Peripheral Tools
          Next
          How to Solve CORS Problems of a Browser