背景
最近涉及到图片上传存储、获取等接口的开发,以此进行相关设计
思路
主要两个接口:
上传图片:读取本地图片,然后以二进制方式上传,服务端存储在对象存储上(例如S3、COS等)
获取图片:根据key名字获取图片的二进制
上传图片
public class Controller {
@RequestMapping(path = {"/add-image"}, method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResData addImage(@RequestParam("image")MultipartFile image, @RequestParam("label") String label, @RequestParam("t") String t) throws Exception {
ResData resData = new ResData();
log.info("keyId:" + label);
log.info("t:" + t);
String objectName = new String();
if (t.equals("top")) {
objectName = "top_1000/top" + label + ".jpeg";
} else if (t.equals("bot")) {
objectName = "bot_1000/bot" + label + ".jpeg";
} else {
resData.code = 601;
resData.msg = "t is not right";
return resData;
}
byte[] input = image.getBytes();
amazonS3.putObject(bucketName, objectName, new ByteArrayInputStream(input), null);
resData.code = 200;
resData.msg = "ok";
resData.data = objectName;
return resData;
}
}
测试
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
url := "http://localhost:8080/eve/cmdb/rest/equipment/add-image"
// 读取图片文件
imagePath := "golang.png"
imageFile, err := os.Open(imagePath)
if err != nil {
fmt.Println("Error opening image file:", err)
return
}
defer imageFile.Close()
// 创建multipart form
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("image", imagePath)
if err != nil {
fmt.Println("Error creating form file:", err)
return
}
// 将图片文件写入multipart form
imageBytes, err := io.ReadAll(imageFile)
if err != nil {
fmt.Println("Error reading image file:", err)
return
}
part.Write(imageBytes)
//writer.WriteField("keyId", "20190625035")
//writer.WriteField("t", "top")
keyPart, err := writer.CreateFormField("keyId")
if err != nil {
fmt.Println("Error creating form field:", err)
return
}
_, err = keyPart.Write([]byte("20190625035"))
if err != nil {
fmt.Println("Error writing key:", err)
return
}
tPart, err := writer.CreateFormField("t")
tPart.Write([]byte("top"))
// 关闭multipart writer
err = writer.Close()
if err != nil {
fmt.Println("Error closing multipart writer:", err)
return
}
// 创建HTTP请求
req, err := http.NewRequest("POST", url, body)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("Content-Type", writer.FormDataContentType()
// 发送HTTP请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
rBody, _ := io.ReadAll(resp.Body)
// 输出响应状态
fmt.Println("Response body:", string(rBody))
}
获取图片
public class Controller {
@RequestMapping(path = {"/get-image"}, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public ResponseEntity<byte[]> getImage(@RequestParam("label") String label, @RequestParam("t") String t) throws Exception {
List<byte[]> imageBytesList = new ArrayList<>();
String objectName = new String();
if (t.equals("top")) {
objectName = "top_1000/top" + label + ".jpeg";
} else if (t.equals("bot")) {
objectName = "bot_1000/bot" + label + ".jpeg";
} else {
return null;
}
try {
S3Object s3Object = amazonS3.getObject(bucketName, objectName);
InputStream content = s3Object.getObjectContent();
log.info("content:" + content);
S3ObjectInputStream inputStream = s3Object.getObjectContent();
byte[] imageBytes = IOUtils.toByteArray(inputStream);
log.info("image bytes:" + imageBytes);
imageBytesList.add(imageBytes);
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM).body(imageBytes);
} catch (Exception e) {
return null;
}
// return new ResponseEntity<>(imageBytesList, headers, HttpStatus.OK);
}
}
测试
//go:build ignore
// +build ignore
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
url := "http://localhost:8080/eve/cmdb/rest/equipment/get-image"
//keys := "golang.png"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("Accept", "application/octet-stream")
q := req.URL.Query()
q.Add("keyId", "20190625035")
q.Add("t", "top")
req.URL.RawQuery = q.Encode()
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
fmt.Println("resp status:", resp.StatusCode)
data, err := io.ReadAll(resp.Body)
fmt.Println("resp body:", data)
if resp.StatusCode == http.StatusOK {
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
// Process the data (List of byte arrays) as needed
fmt.Println("Received images data:", data)
imageName := "golang_get2.png"
err := os.WriteFile(imageName, data, 0644)
if err != nil {
fmt.Println("Error saving image:", err)
} else {
fmt.Println("Image saved:", imageName)
}
} else {
fmt.Println("Error fetching images:", resp.Status)
}
}