使用七牛云进行上传图片

上传图片的过程

点击上传图片按钮,选择要上传的图片,然后发起同步请求,springmvc调用了一个内部的类文件上传解析器去请求体拿文件,封装到MultipartFile中,然后结合七牛云的官方文档写seviceImpl类的方法,返回FileResult对象。

上传相同文件名的图片会怎么样?重复上传同一个图片?会不会造成文件名重复的现象?

会出来,因此我们需要解决。给文件名加一个时间戳,这样就不会出现文件名重复的问题了。

首先我们需要明确上传图片的注意点是什么?

1、表单组件标签只能用

2、上传图片必须采用post请求

图片是二进制数据。上传图片需要将文件数据通过请求体发送到服务器。这样可以保证数据的安全性和完整性。

get请求:参数通过请求头提交到后台,参数放到url后面,而且url长度有限制,长度超限无法提交;而且只能向后台提交文本数据或者字符串数据存在get缓存的问题(可以通过加时间戳来解决这个问题)。GET请求一般用于获取资源,不应该对资源进行修改。效率高,不需要对数据进行封装,减轻了后台处理请求的压力。
post:参数通过请求体提交到后台;能提交文本数据,也能提交二进制数据。对参数长度没有限制,相对安全。post请求一般用于提交数据,会走服务器,因此可能会对服务器资源进行修改。

3、表单的编码格式只能用:enctype=multipart/form-data
根据HTTP协议的规定,浏览器每次向后台提交参数,都会对参数进行统一编码:默认采用的编码格式是urlencoded,这种编码格式只能对文本数据进行编码,浏览器每次向后台提交参数,都会首先把所有的参数转换成字符串,然后对这些数据统一进行urlencoded编码,不管前台发的是啥,浏览器把所有的参数统一转换成字符串,我们拿到的永远也是字符串。
文件上传的表单编码格式只能是:multipart/form-data 多样性的表单数据,阻止默认行为,提交的是什么数据,拿到的是什么数据。没有进行任何的编码。

怎么设置表单的编码格式呢?

前台数据,设置ajax的行为
processDate: false //设置ajax向后台提交参数之前,是否把参数统一转换为字符串:true
contentType:false,//设置ajax向后台提交参数之前,是否把参数的编码统一按urlencoded编码。

请求的方式?异步还是同步?

form表单发送的请求是同步的。浏览器发送的是同步请求。
同步请求只能处理字符串数据。无法解析json对象,无法解析Object
接收文件数据,springmvc专门给我们提供了一个类用来接收客户端上传的文件,MultipartFile类,当文件传过来后,会自动的将请求体的文件封装到这个类的对象中。

springmvc怎么去拿文件到请求体中?

springmvc调用了一个内部的类去请求体拿文件,封装这个对象。
那一个类一开始没有放在spring(mvc)容器中,要调用这个方法必须创建这个对象,把类的对象创建好,如果没有创建好这个类,他也没法调用方法从请求体中拿到数据封装对象,他会自动去找文件。
这个类是文件上传解析器,将拿到的文件赋值给MultipartFile

使用第三方工具一般有三步骤

第一步:引入插件的配置文件
第二步:创建容器,放入插件
第三步:加载容器,调用工具函数

七牛云官方文档
七牛云是一个云存储服务提供商,可以用于储存和管理大量数据。FilePult.js是一种JavaScript库,可用于将文件上传到云存储服务。七牛云提供了与FilePut.js兼容的API,以便在使用FilePut.js上传文件时,可以将文件上传到七牛云。当使用FilePut.js上传文件时,可以使用七牛云提供的API密钥和密钥等信息进行身份验证,并通过API将文件上传到七牛云。因此,七牛云和FilePut.js之间是一种可以协同工作的关系。

导入maven

<dependency>
  <groupId>com.qiniugroupId>
  <artifactId>qiniu-java-sdkartifactId>
  <version>[7.7.0, 7.10.99]version>
dependency>

对象存储空间-地区
使用七牛云进行上传图片_第1张图片

前端:

引入配置文件

<link rel="stylesheet" href="${ctx}/css/fileinput.min.css">link>
	<script type="text/javascript" src="${ctx}/js/fileinput.js">script>
	
	<script type="text/javascript" src="${ctx}/js/fileinput_locale_zh.js">script>

在这里我们是将这个表单组件放到了一个from表单里面,form表单都是同步请求。

添加容器

<tr>
										<td>上传商品图片:</td>
										<td>
											<input type="hidden" name="originalImg" id="originalImg"/>
											<form enctype="multipart/form-data">
												<input id="file-product" class="file" name="file" type="file" multiple
													   data-min-file-count="1">
											</form>
										</td>
									</tr>

调用工具函数

//================商品-图片上传==================
	/**
	 * 初始设置
	 *    language指定语言
	 *    uploadUrl指定文件上传的后台地址
	 *    allowedPreviewTypes允许上传文件的类型
	 */
	$('#file-product').fileinput({
		language: 'zh',
		uploadUrl: '${ctx}/fileUpload/save',
		allowedPreviewTypes: ['image', 'html', 'text', 'video', 'audio', 'flash']
	});
	/**
	 * 上传文件失败后 调用方法(回调函数)
	 */
	$('#file-product').on('fileuploaderror', function (event, data, previewId, index) {
		var form = data.form,
				files = data.files,
				extra = data.extra,
				response = data.response,
				reader = data.reader;

		console.log(data);
		console.log('File upload error');
	});
	/**
	 * 文件错误 比如文件类型错误 调用方法(回调函数)
	 */
	$('#file-product').on('fileerror', function (event, data) {
		console.log(data.id);
		console.log(data.index);
		console.log(data.file);
		console.log(data.reader);
		console.log(data.files);
	});
	/**
	 * 文件上传成功后 调用方法(回调函数)
	 */
	$('#file-product').on('fileuploaded', function (event, data, previewId, index) {
		var form = data.form,
				files = data.files,
				extra = data.extra,
				response = data.response,
				reader = data.reader;
		// 服务器文件地址
		// alert(data.response.fileUrl);
		// 将服务器文件地址设置至隐藏域
		$("#originalImg").val(data.response.fileUrl);
		console.log('File uploaded triggered');
	});
	//================商品-图片上传==================

后端:

yml文件
使用七牛云进行上传图片_第2张图片

pojo

文件返回对象。

 */
public class FileResult implements Serializable {
    
    // success字符串bootstrap file input必须包含该属性
    private String success;
    // error字符串bootstrap file input必须包含该属性
    private String error;
    // 描述信息
    private String message;
    // 文件路径
    private String fileUrl;

    public String getSuccess() {
        return success;
    }

    public void setSuccess(String success) {
        this.success = success;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getFileUrl() {
        return fileUrl;
    }

    public void setFileUrl(String fileUrl) {
        this.fileUrl = fileUrl;
    }
}

Controller

@Controller
@RequestMapping("/fileUpload")
public class UploadController {

	@Autowired
	private UploadService uploadService;

	/**
	 * 将上传的文件赋值给MultipartFile,然后重命名文件,使得每一个文件的名称都不重复,然后调用service方法上传这个文件到后台。
	 * 返回这个文件的信息,在前端得到响应信息判断文件上传是否成功,渲染页面。
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/save")
	@ResponseBody
	public FileResult upload(MultipartFile file) throws IOException {
		String filename = file.getOriginalFilename();
		String date = DateTimeFormatter.ofPattern("yyyy/MM/dd/").format(LocalDateTime.now());
		filename = date+System.currentTimeMillis()+filename.substring(filename.lastIndexOf("."));
		return uploadService.upload(file.getInputStream(),filename);
	}

}

ServiceImpl

@Service("UploadService")
public class UploadServiceImpl implements UploadService {

	@Override
	public FileResult upload(InputStream inputStream, String fileName) {
		FileResult fileResult = new FileResult();
		//构造一个带指定 Region 对象的配置类
		Configuration cfg = new Configuration(Region.region2());
		//...其他参数参考类注释
		UploadManager uploadManager = new UploadManager(cfg);
		//...生成上传凭证,然后准备上传,密钥
		String accessKey = "3scC_cEM9rkaDmh-Nj7djoprxZMUCwqp47GpspS2";
		String secretKey = "GkC1lqSJXoZVwJxtiN-j81CES9uAsqkKMFhwZC5k";
		String bucket = "shop-wll";
		//默认不指定key的情况下,以文件内容的hash值作为文件名
		String key = fileName;
		System.out.println("文件上传....");
		try {
			Auth auth = Auth.create(accessKey, secretKey);
			String upToken = auth.uploadToken(bucket);
			try {
				Response response = uploadManager.put(inputStream,key,upToken,null, null);
				//解析上传成功的结果
				if (response.statusCode==200){
					fileResult.setSuccess("success");
					fileResult.setMessage("上传成功");
					fileResult.setFileUrl("http://ru4mmztz7.hn-bkt.clouddn.com/"+fileName);
					return fileResult;
				}else {
					fileResult.setError("error");
					fileResult.setMessage("上传失败");
					return fileResult;
				}
			} catch (QiniuException ex) {
				Response r = ex.response;
				System.err.println(r.toString());
				fileResult.setError("error");
				fileResult.setMessage("上传失败");
				try {
					System.err.println(r.bodyString());
				} catch (QiniuException ex2) {
					//ignore
				}
			}
		} catch (Exception ex) {
			//ignore
		}
		return fileResult;
	}
}

你可能感兴趣的:(ajax,javascript,json)