Un certain serveur reçoit une requête en multipart et renvoie une réponse en multipart, donc un mémo de l'implémentation qui lui correspond
Créez une classe qui implémente le UploadContext de commons-fileupload pour gérer la réponse en plusieurs parties (même si cela semble étrange de recevoir la réponse). Définissez également InputStream qui reçoit la réponse pour l'implémentation de méthode de UploadContext en tant que membre. Puisque la réponse vérifie si la réponse est en plusieurs parties ou l'en-tête cette fois, HttpURLConnection est également un membre. Implémentez également la méthode UploadContext requise pour traiter le multipart.
Définition de classe
public class MultipartRequestResponse implements UploadContext {
private InputStream is;
private HttpURLConnection connection;
//Au minimum, implémentez le contenu de getInputStream
@Override
public InputStream getInputStream() throws IOException {
return is;
}
//Implémenter si nécessaire la vérification de l'en-tête de réponse
@Override
public String getContentType() {
return connection.getHeaderField("Content-Type");
}
//D'autres méthodes qui nécessitent un remplacement ne sont implémentées que pour le moment, elles sont donc omises.
//・ ・ ・
}
Étant donné que la limite est utilisée à plusieurs reprises, il est plus facile de la créer d'abord en tant que variable de classe. Puisqu'il s'agit d'un test, il est fixe, mais je pense qu'il vaut mieux permettre d'émettre au hasard compte tenu des spécifications des limites et de l'enquête lorsque quelque chose se passe.
Définissez la limite avec une variable de classe
private static final String BOUNDARY = "--boundary";
Préparez l'URL de destination de la demande et l'en-tête de la demande. L'en-tête de la demande est défini selon les spécifications du serveur.
URL url = new URL("https://hogehoge");
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
connection.setRequestProperty("host", url.getHost());
//S'il y a d'autres paramètres nécessaires
Récupérez OutputStream de l'instance HttpURLConnection et écrivez le corps.
Le corps doit également écrire des sauts de ligne et des limites selon les spécifications en plusieurs parties. Au fait, le saut de ligne doit être CRLF (je l'ai envoyé une fois avec LF et je ne pouvais pas bien gérer le multipart).
Définissez le code de saut de ligne avec une variable de classe
private static final String CRLF = "\r\n";
Envoyer une demande
//Commencer la communication avec le serveur
OutputStream os = connection.getOutputStream();
StringBuilder multipartBody = new StringBuilder();
multipartBody.append(CRLF);
//partie(JSON)
multipartBody.append(BOUNDARY).append(CRLF);
multipartBody.append("Content-Disposition: form-data; name=\"parameter1\"").append(CRLF);
multipartBody.append("Content-Type: application/json; charset=utf-8").append(CRLF);
multipartBody.append("Content-Transfer-Encoding: 8bit").append(CRLF);
multipartBody.append(CRLF);
multipartBody.append("{\"hoge\": \"fuga\"}" + CRLF);
//Partie finale
multipartBody.append(BOUNDARY).append("--");
//Ecrire le corps dans OutputStream
os.write(multipartBody.toString().getBytes());
//Envoyer le corps au serveur
os.close();
L'appel de HttpURLConnection # getOutputStream () démarrera la communication avec le serveur et enverra l'en-tête. L'appel de OutputStream # close () envoie le corps de la requête écrite au serveur. Il semble que si vous appelez OutputStream # flush () pour chaque partie, vous pouvez envoyer le corps au serveur à chaque fois, mais il n'a pas été envoyé. Je voudrais vérifier cette zone séparément et rédiger à nouveau un article.
C'est un processus lorsque le côté serveur renvoie la réponse en plusieurs parties, mais je pense que ce ne sera peut-être pas possible si je fais de mon mieux pour analyser le InputStream de la réponse, mais je le traiterai avec l'aide d'apache commons.
//Recevoir une réponse
is = connection.getInputStream();
//Vérifiez si la réponse est en plusieurs parties
// getContentType()La valeur de retour de est vérifiée
if (!FileUpload.isMultipartContent((RequestContext) this)) {
//Que faire si la réponse n'est pas en plusieurs parties
}
//Convertit le contenu d'InputStream en Iterator
FileUpload upload = new FileUpload();
FileItemIterator fit = upload.getItemIterator(this);
//Boucle pour chaque partie du corps de réponse
while (fit.hasNext()) {
FileItemStream fis = fit.next();
//Obtenir le nom du champ de la pièce
String field = fis.getFieldName();
//Obtenir InputStream de la pièce
InputStream isPart = fis.openStream();
//Après cela, c'est OK si vous traitez le contenu de la pièce
//・ ・ ・
}
Si vous recevez une réponse avec FileItemIterator, vous pouvez la tourner en boucle et traiter les parties une par une.
Je nettoierai l'exemple de code et le publierai sur github plus tard.