Секретные записки WEB-программиста




100mbru, android, bitrix, CentOS, cms, drupal, java, joomla, LAMP, linux, mysql, nicru, Open-Source, php, Red Hat, seo, telegramm, Typo3, ubuntu, win, windows, авто, администрирование, алгоритмы, алкоголь, бизнес, видео, военмех, выборы, германия, джино, домены, интересности, исследования, картинки, кино, компьютеры, ливия, магазин, маразм, мастерхост, обработка-изображений, пейнтбол, политика, политэкономия, прикольное-видео, программирование, путешествия, работа, религия, рунет, сайтостроение, сео, сми, технологии, украина, форум, хиханьки, холивары, хостинг

Отправка http-multipart-Post запроса из андроид

27.12.2024

1) утилиты

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
 
 /**
 * This constructor initializes a new HTTP POST request with content type
 * is set to multipart/form-data
 *
 * @param requestURL
 * @throws IOException
 * https://blog.morizyun.com/blog/android-httpurlconnection-post-multipart/index.html
 * https://stackoverflow.com/questions/11766878/sending-files-using-post-with-httpurlconnection
 */
 public HTTPMultipartUtility(String requestURL)
 throws IOException {

 // creates a unique boundary based on time stamp
 URL url = new URL(requestURL);
 httpConn = (HttpURLConnection) url.openConnection();
 httpConn.setUseCaches(false);
 httpConn.setDoOutput(true); // indicates POST method
 httpConn.setDoInput(true);
 httpConn.setConnectTimeout(10000);

 httpConn.setRequestMethod("POST");
 httpConn.setRequestProperty("Connection", "Keep-Alive");
 httpConn.setRequestProperty("Cache-Control", "no-cache");
 httpConn.setRequestProperty(
 "Content-Type", "multipart/form-data;boundary=" + this.boundary);

 request = new DataOutputStream(httpConn.getOutputStream());

 }

 /**
 * Adds a form field to the request
 *
 * @param name field name
 * @param value field value
 */
 public void addFormField(String name, String value)throws IOException {
 request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
 request.writeBytes("Content-Disposition: form-data; name="" + name + """+ this.crlf);
 request.writeBytes("Content-Type: text/plain; charset=UTF-8" + this.crlf);
 request.writeBytes(this.crlf);
 request.writeBytes(value+ this.crlf);
 request.flush();
 }

 /**
 * Adds a upload file section to the request
 *
 * @param fieldName name attribute in Файл не выбран
 * @param uploadFile a File to be uploaded
 * @throws IOException
 */
 public void addFilePart(String fieldName, File uploadFile)
 throws IOException {
 String fileName = uploadFile.getName();
 request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
 request.writeBytes("Content-Disposition: form-data; name="" +
 fieldName + "";filename="" +
 fileName + """ + this.crlf);
 request.writeBytes(this.crlf);

 byte[] bytes = Files.readAllBytes(uploadFile.toPath());
 request.write(bytes);
 }

 /**
 * Completes the request and receives response from the server.
 *
 * @return a list of Strings as response in case the server returned
 * status OK, otherwise an exception is thrown.
 * @throws IOException
 */
 public String finish() throws IOException {
 String response ="";

 request.writeBytes(this.crlf);
 request.writeBytes(this.twoHyphens + this.boundary +
 this.twoHyphens + this.crlf);

 request.flush();
 request.close();

 // checks server`s status code first
 int status = httpConn.getResponseCode();
 if (status == HttpURLConnection.HTTP_OK) {
 InputStream responseStream = new
 BufferedInputStream(httpConn.getInputStream());

 BufferedReader responseStreamReader =
 new BufferedReader(new InputStreamReader(responseStream));

 String line = "";
 StringBuilder stringBuilder = new StringBuilder();

 while ((line = responseStreamReader.readLine()) != null) {
 stringBuilder.append(line).append("
");
 }
 responseStreamReader.close();

 response = stringBuilder.toString();
 httpConn.disconnect();
 } else {
 throw new IOException("Server returned non-OK status: " + status);
 }

 return response;
 }
}

2) собственно отправка

import android.content.Context;
import android.content.Intent;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.io.File;

public class HTTPMultipartRequest {

 public static void send(Context co, String param1,String param2,String filename) {

 new Thread(new Runnable() {
 @Override
 public void run() {
 String re="*",err="";
 try {
 HTTPMultipartUtility req = new HTTPMultipartUtility("http://my-site/connector.php" );
 req.addFormField("param1", param1);
 req.addFormField("param2", param2);

 if(filename.length()>0) {
 File fil=new File(filename);
 req.addFilePart("myfile", fil);
 }
 re=req.finish();
 System.out.println("HTTPMultipartRequest sended");

 } catch (Exception e) {
 // Several error may come out with file handling or DOM
 err=e.getMessage();
 System.out.println("ERR: "+err);
 e.printStackTrace();
 }

 Intent intent = new Intent("sendfile");
 intent.putExtra("message", re);
 intent.putExtra("err", err);
 LocalBroadcastManager.getInstance(co).sendBroadcast(intent);
 }
 }).start();
 }
}

Эти танцы с бубном асинхронного потока нужны потому что Андроид не любит сетевые запосы в основном потоке - иначе вы получите Exception с сообщением null в этой строке:

HTTPMultipartUtility req = new HTTPMultipartUtility("http://my-site/connector.php" );

3) домашнее задание

Когда всё вышеперечисленное будет реализовано вам останется только дописать обработчик интента - если вы хотите информировать пользователя о результатах отправки