前言
之前老是在想OkHttp3 发图片到服务器,因为我要发的是DNG格式的图片,MIMIE没有相应的类型图片,想了想通过Base64编码即可发送即可。Android端写测试代码太麻烦,全都要结合Gui界面写,无形间增加了工作量,所以OkHttp3通过导jar包的方法,在IntelliJ写,不用写那么多,又好理解。
之前还陷入一个误区,发文件就要用OkHttp3的MultipartBody
,实际上好像不要,key-value就可以了,服务端读取request设定的key值相应的value就行了。okhttp 上来就是各种设计模式的方法,适应起来真是不容易。
代码
客户端
okhttptest.java
import utils.addform_body;
public final class okhttptest {
public static void main (String...args) throws Exception{
new addform_body().run();
}
}
addform_body.java
package utils;
import okhttp3.*;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;
public class addform_body {
final String SERVER_URL = "http://127.0.0.1:5000/receive";
// private static final MediaType MEDIA_TYPE_OSTREAM = MediaType.parse("application/octet-stream");
private OkHttpClient client = new OkHttpClient();
public void run() throws Exception{
String send = new base64_test("C:\\编程\\java\\okhttp-test\\src\\source\\test.DNG").Encode_To_Base64();
String uuid = UUID.randomUUID().toString();//保证没有重复
String filename =uuid+".DNG";
RequestBody requestBody = new MultipartBody.Builder() //原先打算用MultipartBody方法构造requestBody的,后来发现不需要。
.setType(MultipartBody.FORM)
.addFormDataPart("username","victor")
.addFormDataPart("b64",send)
.addFormDataPart("filename",filename)
// .addFormDataPart("file","tets.PNG",
// RequestBody.create(send,MEDIA_TYPE_OSTREAM))
.build();
Request request = new Request.Builder()
.url(SERVER_URL)
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()){
if (!response.isSuccessful())throw new IOException("Unexpected code " + response);
System.out.println(Objects.requireNonNull(response.body()).string());
}
}
}
base64_test.java
package utils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.util.UUID;
import java.util.Base64;
public class base64_test {
private String IMAGE_URL;
static String STORAGE_URL = "C:/编程/java/okhttp-test/src/image/";
public base64_test() {
}
public base64_test(String IMAGE_URL) {
this.IMAGE_URL = IMAGE_URL;
}
/*
将图片编码成 Base64字符串
*/
public String Encode_To_Base64() throws Exception {
File file = new File(IMAGE_URL);
FileInputStream inputStream = new FileInputStream(IMAGE_URL);
byte[] buffer = new byte[(int)file.length()];
//noinspection ResultOfMethodCallIgnored
inputStream.read(buffer);
inputStream.close();
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(buffer);
}
public void Decode_To_Image(String Base64,String Type){
BASE64Decoder decoder = new BASE64Decoder();
String random_file_name = UUID.randomUUID().toString();
try {
FileOutputStream outputStream = new FileOutputStream(new File(STORAGE_URL+random_file_name+"."+Type));//随机uuid存储解码后的图片
byte[] decodeBytes = decoder.decodeBuffer(Base64);
outputStream.write(decodeBytes);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String ...args)throws Exception{
String string = new base64_test("C:\\编程\\java\\okhttp-test\\src\\source\\test.PNG").Encode_To_Base64();
new base64_test().Decode_To_Image(string,"PNG");
}
}
服务端
from flask import Flask,url_for,request,escape,jsonify
from werkzeug.utils import secure_filename
import os
import base64
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello world'
@app.route('/receive',methods=['POST'])
def receive():
#测试接受base64编码过的图片
user_id = request.form['username']
img_filename = request.form['filename']
test_image = base64.b64decode(request.form['b64']) #本质就是解码字符串
upload_image_dir = "user_image"
if not os.path.isdir(upload_image_dir) :
os.mkdir(upload_image_dir)
user_dir = os.path.join(upload_image_dir,user_id)
if not os.path.isdir(user_dir):
os.mkdir(user_dir)
file_path = os.path.join(user_dir,img_filename)
#写入文件
try:
with open(file_path,"wb") as f:
f.write(test_image)
return "true"
except:
return "error"
if __name__=="__main__":
app.run(port = 5000,debug = True)