基本的实现思路:
1、图片Base64编码转图片文件临时存储到服务器
2、临时图片文件上传阿里云OSS
3、最后拼接图片的访问路径保存到数据库。
注释已经很详细了,下面直接贴代码,有不足之处,请多指教。
controller层(主业务代码)
package com.aikang.face.controller;
import com.aikang.face.dao.FaceMessageDao;
import com.aikang.face.entity.FaceMessage;
import com.aikang.face.oss.OssUpload;
import com.aikang.face.utils.Base64ToImageUtils;
import com.aikang.face.utils.DateUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@RestController
public class AuthcMessageController {
@Resource
private FaceMessageDao faceMessageDao;
@Autowired
private OssUpload ossUpload;
@PostMapping("/admin/authc")
public void unfamiliar(@RequestBody JSONObject jsonParams) throws IOException {
/*这里要说说用JSONObject做接收参数的好处,因为当发现对方上报的json数据存在各种json、数组嵌套时,
* 我们可能一下子不好创建一个对应复杂实体对象,就可以用JSONObject来接收第三方发送的json对象
* 然后根据已知的json格式,一步步解析,拿到我们想要的值**/
JSONObject info = jsonParams.getJSONObject("info");
String sanpPic = jsonParams.getString("SanpPic");//图片Base64编码数据
FaceMessage faceMessage = new FaceMessage();
faceMessage.setOperator("身份认证");
faceMessage.setDeviceID(info.getInteger("DeviceID"));
faceMessage.setTemperature(info.getDouble("Temperature"));
faceMessage.setCreateTime(DateUtils.DateParse2(info.getString("CreateTime")));
faceMessage.setTemperatureAlarm(info.getInteger("TemperatureAlarm"));
faceMessage.setTemperatureMode(info.getInteger("TemperatureMode"));
faceMessage.setSendintime(info.getInteger("Sendintime"));
faceMessage.setTelnum(info.getString("Telnum"));
faceMessage.setName(info.getString("Name"));
faceMessage.setNative(info.getString("Native"));
faceMessage.setBirthday(info.getString("Birthday"));
//去掉前面的"data:image/jpeg;base64,"的字样
String imgData = sanpPic.replace("data:image/jpeg;base64,","");
/* start 自定义图片临时文件路径,base64编码 转 图片*/
//处理根据日期生成目录
String dateDirPath = ResourceUtils.getURL("classpath:").getPath()+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"/";
//生成随机文件名
String fileName = UUID.randomUUID().toString().replace("-","")+".jpg";
//检查目录,没有要先创建目录,不然 new FileOutputStream() 会报 FileNotFoundException异常
File folder = new File(dateDirPath);
if (!folder.exists()){
folder.mkdirs();
}
//合成最后临时文件路径
String imgFilePath = dateDirPath + fileName;
//base64编码 转 图片(imgData:base64编码,imgFilePath:生成图片的路径)
Base64ToImageUtils.GenerateImage(imgData, imgFilePath);
/* end */
/* start
1、inputStream 转 ByteArrayInputStream,转成ByteArrayInputStream是因为上传阿里oss的参数需要
2、自定义存到阿里云oss对象存储的文件路径
3、调用阿里提供的SDK代码上传文件*/
File file = new File(imgFilePath);
FileInputStream fin = new FileInputStream(file);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = fin.read(buff, 0, 100)) > 0) {
bout.write(buff, 0, rc);
}
//输出流和输入流
bout.close();
fin.close();
//处理根据日期生成目录
String aliYunDir = "face/authc/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"/";
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
//aliYunDir:存放路径(目录),fileName:文件名,bin:ByteArrayInputStream
ossUpload.oss(aliYunDir,fileName,bin);
/* end */
/* 经过上面步骤,文件已成功上传阿里oss,所以这步是删除临时文件*/
if (file.exists() && file.isFile()){
boolean delete = file.delete();
System.out.println(delete);
}
//保存图片的访问路径,访问路径是根据上传时定的文件目录和文件名拼接的
faceMessage.setImgPath("https://ailesi.oss-cn-shenzhen.aliyuncs.com/"+aliYunDir+fileName);
faceMessageDao.save(faceMessage);
}
}
Base64编码转图片代码:
package com.aikang.face.utils;
import org.apache.commons.codec.binary.Base64;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Base64ToImageUtils {
public static boolean GenerateImage(String imgData, String imgFilePath) throws IOException { // 对字节数组字符串进行Base64解码并生成图片
System.out.println("图片数据:"+imgData);
if (imgData == null) // 图像数据为空
return false;
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(imgFilePath));
// Base64解码
byte[] b = Base64.decodeBase64(imgData);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
out.write(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
out.flush();
out.close();
return true;
}
}
}
OSS配置类代码:
package com.aikang.face.oss;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "oss")
public class OssConstant {
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String endpoint;
}
OSS上传文件代码:
package com.aikang.face.oss;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@Component
public class OssUpload {
@Autowired
private OssConstant ossConstant;
public void oss(String dateFormat, String fileName, ByteArrayInputStream bin) throws IOException {
String objectName = dateFormat + fileName;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(
ossConstant.getEndpoint(),
ossConstant.getAccessKeyId(),
ossConstant.getAccessKeySecret());
// 上传文件到指定的存储空间(bucketName)并将其保存为指定的文件名称(objectName)。
ossClient.putObject(ossConstant.getBucketName(), objectName, bin);
// 关闭OSSClient。
ossClient.shutdown();
}
}