上节课我们一起学习了搭建一个单机版的FastDFS图片服务器以及使用FastDFS-Client进行简单的文件上传操作测试,这节我们一起学习项目中添加商品时上传图片的问题,目前上传图片还没有实现,如下图所示。
我们看下list-add.jsp页面,可以看到上传图片触发方法picFileUpload是通过class来处理的,在<a>标签的下方是一个隐藏域,是用来接收上传到图片服务器的回显地址的,当我们提交表单的时候,可以把这些图片地址保存到数据库中。
流程是这样的,页面加载完之后,会自动调用TAOTAO.init进行初始化,如下图所示。
TAOTAO在common.js中定义,我们来看下common.js,可以看到TAOTAO=TT都是在这里定义的,在init方法中this.initPicUpload(data);用来初始化上传组件。初始化上传组件中就有我们在jsp页面中定义的类picFileUpload,由于上传操作可能不只一个地方调用,因此$(".picFileUpload").each(function(i,e){来对所有调用上传的页面的组件进行初始化。如果已经上传过图片,现在处于编辑状态的话,那么就使用_ele.siblings(".pics").find("ul").append来加载原来已经添加过的图片。点击上传图片按钮后,就会加载富文本编辑的上传图片界面,富文本编辑器的参数是在上面var TT=TAOTAO={的下面,指定了上传文件参数的名称,请求的url是/pic/upload,上传类型是image、flash、media、file四种。
下面我们来实现图片上传功能
第一步:导包
上传图片需要依赖commons-io和commons-fileupload开发包,我们需要在taotao-manger-web工程的Maven依赖中查一下是否有这两个包,目前是有commons-io-1.3.2.jar这个包的(它是在taotao-manager-common中依赖的,而taotao-manager-web依赖了taotao-manager-common,因此它也有这个包了),但目前没有commons-fileupload,因此我们需要在taotao-manager-web的pom.xml文件中添加对commons-fileupload的依赖。
添加的依赖如下,由于在taotao-parent当中统一定义了版本号,因此这里不用指定版本号。
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
第二步:配置文件上传解析器
我们需要在taotao-manager-web工程的springmvc.xml文件当中配置一下文件上传解析器。如下所示。
<!-- 配置文件上传解析器 -->
<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>
第三步:配置访问图片前缀
我们在访问图片时是以http的方式访问的,例如http://192.168.156.13:8888/group1/M00/00/00/wKicDVjxPn2AOBiGAAHk-VzqZ6w952.jpg,从上节课我们知道图片服务器返回的图片路径是group1/M00/00/00/wKicDVjxPn2AOBiGAAHk-VzqZ6w952.jpg,也就是说没有前面那部分路径,我们不能在代码中写死前缀,因为IP及端口号都有可能更改,因此最好是放到配置文件当中,我们在resource目录下新建一个resource.properties文件,配置文件中输入IMAGE_SERVER_URL=http://192.168.156.13:8888/,这里输入端口8888是因为我在图片服务器的nginx当中配置的访问端口是8888,如果端口是默认的80端口的话,可以直接输入IMAGE_SERVER_URL=http://192.168.156.13/即可,下图所示。
第四步:加载配置文件
我们在第三步新建了resource.properties,在spring中我们需要加载该配置文件,因此我们在springmvc.xml中加入<context:property-placeholder location="classpath:resource/resource.properties"/>,如下图所示。
当前springmvc.xml文件的完整内容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:resource/resource.properties"/>
<!-- 配置注解驱动 -->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置包扫描器,扫描@Controller注解的类 -->
<context:component-scan base-package="com.taotao.controller"/>
<!-- 配置资源映射 -->
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<!-- 多媒体解析器 -->
<!-- 配置文件上传解析器 -->
<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>
<!-- 引用dubbo服务 -->
<dubbo:application name="taotao-manager-web"/>
<dubbo:registry protocol="zookeeper" address="192.168.156.14:2181"/>
<dubbo:reference interface="com.taotao.service.ItemService" id="itemService" />
<dubbo:reference interface="com.taotao.service.ItemCatService" id="itemCatService" />
</beans>
第五步:创建Controller
我们需要新建一个PictureController类来处理上传操作,如下图所示。
上图中@Value("${IMAGE_SERVER_URL}")是为了注入我们在配置文件resource.properties中配置的图片访问前缀。@RequestMapping("/pic/upload")指定上传文件请求的url,与下图指定url一样,上图的public Map uploadFile(MultipartFile uploadFile) 参数"uploadFile"与下图的上传文件的方法参数名称是要求一样的。
那么方法uploadFile应该返回什么样的格式呢,我们可以从kindeditor官网http://kindeditor.net/docs/upload.html查看一下,如下图所示,可以看到返回值格式是json串,那么我们便有三种实现方式。第一种是直接返回Map格式的数据,json和Map数据都是key和value的形式,因此返回Map是没问题的。第二种是创建一个POJO类,该类有三个属性,分别是error、url、message,然后将该类转换为json之后返回。第三种是将Map转变为json字符串返回。这里我们暂且使用第一种方式。
现把Controller类代码粘贴如下
package com.taotao.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.taotao.utils.FastDFSClient;
@Controller
public class PictureController {
@Value("${IMAGE_SERVER_URL}")
private String IMAGE_SERVER_URL;
@RequestMapping("/pic/upload")
@ResponseBody
public Map uploadFile(MultipartFile uploadFile) {
Map result = new HashMap<>();
try {
//1.接收上传的文件
//2.获取扩展名
String orignalName = uploadFile.getOriginalFilename();
String extName = orignalName.substring(orignalName.lastIndexOf(".")+1);
//3.上传到图片服务器
FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/client.conf");
String url = fastDFSClient.uploadFile(uploadFile.getBytes(), extName);
url = IMAGE_SERVER_URL + url;
result.put("error", 0);
result.put("url", url);
return result;
} catch (Exception e) {
e.printStackTrace();
result.put("error", 0);
result.put("message", "上传图片失败!");
return result;
}
}
}
这样我们便配置完了,现在我们试试图片上传功能,如下图所示,发现点击"开始上传"之后图片正常回显了。我们点击"全部插入"按钮。
点击"全部插入"按钮之后可以看到在"上传图片"按钮的下方有我们刚才上传的三张图片,我们是可以点击任何一张图片在浏览器中浏览的,比如我们点击第三张图片。
在浏览器中访问的效果如下图所示。这样我们的图片上传功能便实现了。