** Alibaba Cloud Object Storage Service (OSS) ** stocke les objets dans des ressources appelées «buckets». L'objet de publication utilise un formulaire HTML pour télécharger le fichier dans le compartiment spécifié.
Alibaba Cloud Object Storage Service (OSS) est un service facile à utiliser qui vous permet de stocker, sauvegarder et archiver de grandes quantités de données dans le cloud. OSS agit comme un référentiel central chiffré, vous donnant un accès sécurisé aux fichiers du monde entier. De plus, avec une disponibilité garantie jusqu'à 99,9%, il est idéal pour les équipes mondiales et la gestion de projets internationaux.
Alibaba Cloud Object Storage Service (OSS) stocke en toute sécurité les objets dans des ressources appelées «buckets». OSS vous donne un accès complet aux compartiments et vous permet d'afficher les journaux et les objets dans chaque compartiment. Vous pouvez lire, écrire, supprimer et enregistrer un nombre illimité d'objets dans votre compartiment. Les hautes performances d'OSS prennent en charge plusieurs lectures / écritures en même temps. Le transfert de données vers le compartiment s'effectue via SSL et est chiffré.
Post Object utilise des formulaires HTML au lieu de Put pour télécharger des fichiers dans le compartiment spécifié. Cela vous permet de télécharger des fichiers dans votre bucket via votre navigateur. Le désir d'implémenter Post Object en Java vient des brèves explications de divers personnels de support. Selon eux, les utilisateurs qui ont besoin de cette fonctionnalité sont confrontés à divers problèmes difficiles lorsqu'ils tentent de mettre en œuvre la fonctionnalité selon la documentation officielle. Cela se produit parce qu'il n'y a pas de référence de code officielle.
Jetons un coup d'œil aux étapes que l'utilisateur doit suivre.
Le site officiel fournit d'abord la syntaxe de requête HTTP. Le format de l'en-tête de la requête HTTP et du champ de formulaire codé en plusieurs parties / données de forme du corps du message pour satisfaire les paramètres.
Ensuite, nous allons introduire chaque champ de formulaire "requis" tel que "fichier" et "clé" dans la table des champs de formulaire. L'utilisateur demande l'un des champs du formulaire tels que "OSSAccessKeyId", "policy", "Signature". Vous avez également besoin de l'en-tête de requête REST, de la méta utilisateur x-oss -meta- * et d'autres champs de formulaire facultatifs.
La publication de ceci introduit des utilisations spéciales et des mises en garde pour certains champs de formulaire. Il partage également une pile d'informations sur les fonctionnalités de politique de publication et de signature et sur la façon de les utiliser. «La documentation est claire dans une certaine mesure, mais de nombreux concepts sont difficiles à comprendre et il est difficile d'étudier le problème. De plus, il n'y a pas de faits saillants sur la mise en œuvre sujette aux erreurs, qui présente aux utilisateurs deux défis majeurs: Les utilisateurs peuvent se heurter à deux défis majeurs, et deux autres aspects sont impliqués.
Non familier avec les encodages de type MIME comme multipart / form-data.
Non familier avec les règles d'implémentation OSS pour l'analyse des requêtes Post Object
Ensuite, j'expliquerai les deux aspects mentionnés ci-dessus.
Pour une introduction détaillée à multipart / form-data, voir RFC 2388. Il y a quelques points à noter ici. Discutons-en un par un.
Content-Disposition: form-data; name=“your_key"
Remarque: les deux ":" et ";" suivent l'espace.
Content-Disposition: form-data; name="file"; filename="MyFilename.jpg "
Content-Type: image/jpeg
Remarque: Le ";" avant le "nom de fichier" a toujours un espace à la fin. De même, il y a un espace de fin dans le ":" après le "Content-Type".
Content-Type: multipart/form-data; boundary=9431149156168
Le quatrième point à noter est que la structure de chaque champ de formulaire est fixe. De par sa conception, chaque champ de formulaire commence par "-" boundary +, suivi d'un retour chariot (/ r / n). Ceci est suivi de la description du champ de formulaire (voir point 1), puis / r / n. Si le contenu que vous souhaitez transférer est un fichier, les informations sur le nom du fichier incluent également le retour chariot (/ r / n) suivi du type de contenu du fichier (voir point 2). De plus, il existe un autre retour chariot (/ r / n) pour démarrer le contenu réel, qui doit se terminer à / r / n.
Notez également que le dernier champ de formulaire se termine par "-" + limite + "-".
De plus, la marque / r / n est nécessaire pour faire la distinction entre les en-têtes de requête HTTP et les informations de corps (à la jonction de l'en-tête et du premier champ de formulaire). Il s'agit essentiellement d'une ligne vierge supplémentaire comme un document, qui ressemble à ceci:
Content-Type: multipart/form-data; boundary=9431149156168
--9431149156168
Content-Disposition: form-data; name="key"
Jusqu'à présent, nous avons fourni une description générale de la syntaxe de requête fournie dans la documentation officielle OSS et une analyse connexe par comparaison avec la norme RFC 2388.
Dans cette section, nous allons approfondir certaines des mises en garde associées à certains des traitements que le système OSS effectue pour analyser les demandes d'objet POST.
La procédure générale pour OSS pour analyser une requête POST est illustrée dans la figure ci-dessous pour référence.
Le flux de traitement des demandes est résumé en trois étapes principales.
Par conséquent, la documentation insiste sur le fait de placer le champ "fichier" dans le "dernier champ". Sinon, les champs de formulaire après "fichier" peuvent n'avoir aucun effet. Le fait de placer le champ de formulaire requis «clé» après «fichier» garantit que le résultat est un InvalidArgument.
Ensuite, je vais expliquer brièvement le flux de travail comme indiqué dans la figure.
Ceci est destiné à vérifier la longueur du champ d'options en raison de la longueur totale limitée du corps de la demande de publication. 5) Analysez ParseContentType avec ParseFile. Analyse le champ ContentType dans le champ Fichier. Ce champ n'est pas obligatoire.
Cela se termine avec le code Java (projet Maven) qui implémente le téléchargement de Post Object dans OSS pour référence et utilisation par ceux qui sont familiers avec OSS.
import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by yushuting on 16/4/17.
*/
public class OssPostObject {
private String postFileName = "your_file";
Make sure that the file exists at the path indicated in the run code.
private String ossEndpoint = "your_endpoint";
For example: http://oss-cn-shanghai.aliyuncs.com
private String ossAccessId = "your_accessid"; This is your access AK
private String ossAccessKey = "your_accesskey"; This is your access AK
private String objectName = "your_object_name"; This is the object name after you upload the file
private String bucket = "your_bucket"; Make sure that the bucket you created previously has been created.
private void PostObject() throws Exception {
String filepath=postFileName;
String urlStr = ossEndpoint.replace("http://", "http://"+bucket+"."); This is the URL for the submitted form is the bucket domain name
LinkedHashMap<String, String> textMap = new LinkedHashMap<String, String>();
// key
String objectName = this.objectName;
textMap.put("key", objectName);
// Content-Disposition
textMap.put("Content-Disposition", "attachment;filename="+filepath);
// OSSAccessKeyId
textMap.put("OSSAccessKeyId", ossAccessId);
// policy
String policy = "{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [[\"content-length-range\", 0, 104857600]]}";
String encodePolicy = java.util.Base64.getEncoder().encodeToString(policy.getBytes());
textMap.put("policy", encodePolicy);
// Signature
String signaturecom = com.aliyun.oss.common.auth.ServiceSignature.create().computeSignature(ossAccessKey, encodePolicy);
textMap.put("Signature", signaturecom);
Map<String, String> fileMap = new HashMap<String, String>();
fileMap.put("file", filepath);
String ret = formUpload(urlStr, textMap, fileMap);
System.out.println("[" + bucket + "] post_object:" + objectName);
System.out.println("post reponse:" + ret);
}
private static String formUpload(String urlStr, Map<String, String> textMap, Map<String, String> fileMap) throws Exception {
String res = "";
HttpURLConnection conn = null;
String BOUNDARY = "9431149156168";
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(30000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + BOUNDARY);
OutputStream out = new DataOutputStream(conn.getOutputStream());
// text
if (textMap != null) {
StringBuffer strBuf = new StringBuffer();
Iterator iter = textMap.entrySet().iterator();
int i = 0;
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String inputName = (String) entry.getKey();
String inputValue = (String) entry.getValue();
if (inputValue == null) {
continue;
}
if (i == 0) {
strBuf.append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
} else {
strBuf.append("\r\n").append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
}
i++;
}
out.write(strBuf.toString().getBytes());
}
// file
if (fileMap != null) {
Iterator iter = fileMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String inputName = (String) entry.getKey();
String inputValue = (String) entry.getValue();
if (inputValue == null) {
continue;
}
File file = new File(inputValue);
String filename = file.getName();
String contentType = new MimetypesFileTypeMap().getContentType(file);
if (contentType == null || contentType.equals("")) {
contentType = "application/octet-stream";
}
StringBuffer strBuf = new StringBuffer();
strBuf.append("\r\n").append("--").append(BOUNDARY).append(
"\r\n");
strBuf.append("Content-Disposition: form-data; name=\""
+ inputName + "\"; filename=\"" + filename
+ "\"\r\n");
strBuf.append("Content-Type: " + contentType + "\r\n\r\n");
out.write(strBuf.toString().getBytes());
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
}
StringBuffer strBuf = new StringBuffer();
out.write(strBuf.toString().getBytes());
}
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
// Read the returned data
StringBuffer strBuf = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
strBuf.append(line).append("\n");
}
res = strBuf.toString();
reader.close();
reader = null;
} catch (Exception e) {
System.err.println("Error in sending a POST request: " + urlStr);
throw e;
} finally {
if (conn != null) {
conn.disconnect();
conn = null;
}
}
return res;
}
public static void main(String[] args) throws Exception {
OssPostObject ossPostObject = new OssPostObject();
ossPostObject.PostObject();
}
}
Veuillez noter que vous devez ajouter ce qui suit à pom.xml.
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.2.1</version>
</dependency>
Post Object vous permet de télécharger des fichiers dans votre compartiment en fonction de votre navigateur. Le codage du corps du message Post Object utilise des données multipart / form. Dans les opérations Post Object, le programme transfère les paramètres sous forme de champs de formulaire dans le corps du message. Post Object utilise AccessKeySecret pour calculer la signature de la stratégie. Le champ de formulaire POST est une option pour télécharger des compartiments publics en lecture / écriture, mais nous vous recommandons d'utiliser ce champ pour limiter les demandes POST.