后端实现
加入jar包的依赖
<dependencies>
<!-- fastDFS -->
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>fastdfs-client-java</artifactId>
<fastdfs.version>1.27</fastdfs.version>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<fileupload.version>1.3.1</fileupload.version>
</dependency>
</dependencies>
将demo中的上传代码抽取出来形成工具类
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
if (conf.contains("classpath:")) {
conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
}
ClientGlobal.init(conf);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* 上传文件方法
* <p>
* Title: uploadFile
* </p>
* <p>
* Description:
* </p>
*
* @param fileName
* 文件全路径
* @param extName
* 文件扩展名,不包含(.)
* @param metas
* 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* 上传文件方法
* <p>
* Title: uploadFile
* </p>
* <p>
* Description:
* </p>
*
* @param fileContent
* 文件的内容,字节数组
* @param extName
* 文件扩展名
* @param metas
* 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
}
配置fdfs_client.conf,保存tracker的ip和端口
#tracker服务器IP地址和端口号
tracker_server=192.168.2.123:22122
配置fdfs_server.properties用来保存服务器的ip
#图片服务器的ip
fdfs_server=http://192.168.2.123/
在springmvc.xml文件中加载fdfs_server.properties,将图片服务器的ip放到spring容器中,在业务代码中通过value注解取出
<!--加载配置文件-->
<context:property-placeholder location="classpath:fdfs_server.properties"/>
在springmvc.xml文件中配置文件上传多媒体解析器
在Spring中,MultipartResolver主要用来处理文件上传。默认没有使用,则开发者需要自己处理。若要使用MultipartResolver则需要在web.xml中添加multipart解析器,若请求中包含multipart,那么上下文定义的MultipartResolver就会解析它。
<!-- 配置文件上传多媒体解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
在controller层,写请求路径和上传代码,上传完成后把存储在图片服务器的路径返回给前端
@RestController
@RequestMapping("/file")
public class UploadController {
@Value("${fdfs_server}")
private String FILE_SERVER_URL;
@RequestMapping("/upload")
public Result upload(MultipartFile file){
//1、取文件的扩展名
//作用是上传文件时,会把文件名及其后缀截掉,重新命名,重新命名完成后再加上后缀
//abc.jpg
String originalFilename = file.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try {
//2、创建一个 FastDFS客户端
FastDFSClient fastDFSClient = new FastDFSClient("classpath:fdfs_client.conf");
//3、执行上传处理
String path = fastDFSClient.uploadFile(file.getBytes(), extName);
//4、拼接返回的图片路径 和 ip 地址成完整的 url
String url = FILE_SERVER_URL + path;
return new Result(true, url);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "上传失败");
}
}
}
前端实现
service层
type=file 的文件上传框获得到的对象files包含多信息(实际上files是个数组),文件信息保存在files[0]里,文件上传框的id,调用files属性
文件上传需要定义文件的类型MultipartFile(多部件)
js模拟表单提交
// h5新增类,实现表单数据的序列化
var formData = new FormData();
// key-value
formData.append("file", file.files[0]);
anjularjs对于post和get请求默认的Content-Type header 是application/json。通过设置‘Content-Type’: undefined,这样浏览器会帮我们把Content-Type 设置为 multipart/form-data.
//设置上传文件所需要的更多属性
return $http({
method:'post',
url:'../file/upload.do',
data:formData,
headers:{//设置请求头
'content-Type':undefined
},
transformRequest:angular.entity //转化传递
});
后端要通过MultipartFile file来接收媒体类型文件
controller层
$scope.uploadFile = function () {
uploadService.uploadFile().success(
function (response) {
if (response.success){//如果上传成功,取出后台返回图片存储url
$scope.image_entity.url=response.message;//设置文件地址
}
else{
alert(response.message);
}
}).error(function () {
alert("上传发生错误!");
})
}
页面绑定
<button type="button" class="btn btn-default" title="新建" data-target="#uploadModal" data-toggle="modal" ng-click="image_entity={}"><i class="fa fa-file-o"></i> 新建</button>
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">上传商品图片</h3>
</div>
<div class="modal-body">
<table class="table table-bordered table-striped">
<tr>
<td>颜色</td>
<td><input class="form-control" placeholder="颜色" ng-model="image_entity.color"> </td>
</tr>
<tr>
<td>商品图片</td>
<td>
<table>
<tr>
<td>
<input type="file" id="file" />
<button class="btn btn-primary" type="button" ng-click="uploadFile()">
上传
</button>
</td>
<td>
<img ng-src="{{image_entity.url}}" width="200px" height="200px">
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true">保存</button>
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
</div>
</div>
</div>
</div>