需求:
最近在做项目的时候采用了多模块的方案
前台是一个系统 后台是另一个系统
在做图片上传的时候有个问题 如果想之前那样前台系统的图片保存的自己的web应用目录下 后台系统是没法访问的 (直接写死路径不太好)
这里我想到了两个方案
方案一:自己搭建一个ftp服务器上传图片 然后再搭建一个nginx服务器来访问
方案二:采用七牛云存储平台
这里我采用的是方案二 因为没有体验过七牛 借这个机会玩玩
- 第一步注册七牛账号 获取相关的key
- 导入jar包 这里采用maven方式
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<!--这样写 会自动找7.2的最高版本-->
<version>[7.2.0, 7.2.99]</version>
</dependency>
- 上传图片有两种方式 一是客户端上传 而是服务器直传
这里我用的服务器直传
浏览器采用的html5 压缩 传输base64方式 所以这里用Base64解码并生成图片
如果是传统的MultipartFile则不需要
@RequestMapping("/upload")
@ResponseBody
public Map imageUpload(String type,String value,HttpServletRequest request) {
Logger logger = Logger.getLogger(this.getClass());
Map map = imageService.uploadImage(value, request.getSession().getServletContext());
return map;
}
@Service
public class ImageServiceImpl implements ImageService {
@Override
public Map uploadImage(String imgStr, ServletContext servletContext) {
Map map = new HashMap();
//对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) { //图像数据为空
map.put("error", 1);
map.put("message", "上传失败");
return map;
}
BASE64Decoder decoder = new BASE64Decoder();
try {
//Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {//调整异常数据
b[i] += 256;
}
}
String key = IDUtils.genImageName();
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
String accessKey = "ceLw-DN7neXckVebuUE6eOJC1GPBuXkXS4mkyOzb";
String secretKey = "pg3QL2EuJY9LOjSayhBWGHvAlwfdxEk9UXrx9zT9";
String bucket = "zspwork";
//默认不指定key的情况下,以文件内容的hash值作为文件名
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(b);
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
Response response = uploadManager.put(byteInputStream, key, upToken, null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
map.put("error", 0);
map.put("message", "http://o7k6tx0fl.bkt.clouddn.com/" + key);
} catch (Exception e) {
e.printStackTrace();
map.put("error", 1);
map.put("message", "上传失败");
return map;
}
return map;
}
}
前台 上传图片后回调拿到地址
<a href="javascript:;" class="file">选择文件
<input type="file" id="photo" accept="image/*">
</a>
<input type="text" class="form-control" name="cardImgurl" id="imgInput" readonly>
// 图片上传
$('#photo').change(function () {
var _this = $(this)[0],
_file = _this.files[0],
fileType = _file.type;
console.log(_file.size);
if (/image\/\w+/.test(fileType)) {
//提示
var index = layer.open({
content: '图片上传中...'
, skin: 'msg'
});
var fileReader = new FileReader();
fileReader.readAsDataURL(_file);
fileReader.onload = function (event) {
var result = event.target.result; //返回的dataURL
var image = new Image();
image.src = result;
image.onload = function () { //创建一个image对象,给canvas绘制使用
var cvs = document.createElement('canvas');
var scale = 1;
if (this.width > 1000 || this.height > 1000) { //1000只是示例,可以根据具体的要求去设定
if (this.width > this.height) {
scale = 1000 / this.width;
} else {
scale = 1000 / this.height;
}
}
cvs.width = this.width * scale;
cvs.height = this.height * scale; //计算等比缩小后图片宽高
var ctx = cvs.getContext('2d');
ctx.drawImage(this, 0, 0, cvs.width, cvs.height);
var newImageData = cvs.toDataURL(fileType, 0.8); //重新生成图片,<span style="font-family: Arial, Helvetica, sans-serif;">fileType为用户选择的图片类型</span>
var sendData = newImageData.replace("data:" + fileType + ";base64,", '');
$.post('/upload', {type: 'photo', value: sendData}, function (data) {
if (data.error == '0') {
$('.modify_img').attr('src', newImageData);
$("#imgInput").attr("value", data.message);
layer.closeAll();
} else {
layer.closeAll();
layer.open({
content: data.message
, skin: 'msg'
});
}
});
}
}
} else {
layer.open({
content: '请选择图片格式文件'
, skin: 'msg'
});
}
});