上文我们使用FastDFS-Client进行了简单的文件上传操作测试,淘淘商城项目中添加商品时上传图片的功能还没实现,如下图所示。本文将花大量笔墨来教大家如何实现图片上传这个功能。
我们来看下item-add.jsp页面,可以看到上传图片触发的方法是通过叫做picFileUpload的class来处理的,在标签的下方是一个隐藏域,是用来接收图片上传到图片服务器的回显地址的,当我们提交表单的时候,可以把这些图片地址保存到数据库中。
图片上传的流程是这样的,item-add.jsp页面加载完之后,会自动调用TAOTAO.init进行初始化,如下图所示。
TAOTAO是在common.js文件中定义的,我们来看下common.js,可以看到TAOTAO=TT都是在这里定义的,在init方法中this.initPicUpload(data);
是用来初始化上传组件的。初始化上传组件中就有我们在item-add.jsp页面中定义的叫做picFileUpload的class,由于上传操作可能不只一个地方调用,因此$(".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依赖中查看一下是否有这两个jar包,目前是有commons-io-1.3.2.jar这个jar包的(它是在taotao-common工程的Maven依赖中,而taotao-manager-web依赖了taotao-common,因此它也有了这个jar包),但目前没有commons-fileupload,因此我们需要在taotao-manager-web工程的pom.xml文件中添加对commons-fileupload的依赖。
添加的依赖如下,由于在taotao-parent工程当中统一定义了版本号,因此这里不用指定版本号。
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
dependency>
我们需要在taotao-manager-web工程的springmvc.xml文件当中配置一下文件上传解析器,如下图所示。
为方便大家复制,现把文件上传解析器的配置贴出:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8">property>
<property name="maxUploadSize" value="5242880">property>
bean>
我们在访问图片时是以http的方式访问的,例如http://192.168.25.133/group1/M00/00/00/wKicDVjxPn2AOBiGAAHk-VzqZ6w952.jpg
,从上文中我们知道图片服务器返回的图片路径是group1/M00/00/00/wKicDVjxPn2AOBiGAAHk-VzqZ6w952.jpg
,也就是说没有前面那部分路径,即http://192.168.25.133/
,而我们又不能在代码中写死前缀,因为IP及端口号都有可能更改,因此最好是放到配置文件当中,我们在src/main/resources/resource目录下新建一个resource.properties文件,配置文件中输入IMAGE_SERVER_URL=http://192.168.25.133/
,这说明图片服务器中的nginx配置的访问端口是默认的80端口,如下图所示。
我们在上面新建了resource.properties文件之后,在Spring容器中我们就需要加载该配置文件了,因此我们在springmvc.xml配置文件中加入如下配置:
<context:property-placeholder location="classpath:resource/resource.properties" />
如下图所示:
如此一来,springmvc.xml配置文件的完整内容就如下了。
<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" />
<context:component-scan base-package="com.taotao.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
bean>
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8">property>
<property name="maxUploadSize" value="5242880">property>
bean>
<dubbo:application name="taotao-manager-web"/>
<dubbo:registry protocol="zookeeper" address="192.168.25.128:2181"/>
<dubbo:reference interface="com.taotao.service.ItemService" id="itemService" />
<dubbo:reference interface="com.taotao.service.ItemCatService" id="itemCatService" />
beans>
我们需要新建一个PictureController类来处理图片上传操作,如下图所示。
上图中@Value("${IMAGE_SERVER_URL}")
是为了注入我们在配置文件resource.properties中配置的图片访问前缀。@RequestMapping("/pic/upload")
指定上传文件(图片)请求的url,与下图指定的url一样,上图uploadPic方法中的形参——uploadFile与下图的上传文件的参数名称是要一样的。
那么方法uploadPic应该返回什么样的格式呢,我们可以从kindeditor官网查看一下,如下图所示,可以看到返回值格式是json串,那么我们便有三种实现方式。第一种是直接返回Map格式的数据,json和Map数据都是key和value的形式,因此返回Map是没问题的。第二种是创建一个pojo类,该类有三个属性,分别是error、url、message,然后将该类转换为json之后返回。第三种是将Map转变为json字符串返回。这里我们暂且使用第一种方式。
为了方便大家复制,现把PictureController类的代码粘贴如下:
/**
* 图片上传Controller
* Title: PictureController
* Description:
* Company: www.itcast.cn
* @version 1.0
*/
@Controller
public class PictureController {
@Value("${IMAGE_SERVER_URL}")
private String IMAGE_SERVER_URL;
@RequestMapping("/pic/upload")
@ResponseBody
public Map uploadPic(MultipartFile uploadFile) {
try {
// 首先接收页面上传的文件
byte[] content = uploadFile.getBytes();
// 取出文件的扩展名
String originalFilename = uploadFile.getOriginalFilename();
String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
// 把这个文件内容上传到图片服务器
FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/fast_dfs.conf");
String url = fastDFSClient.uploadFile(content, ext);
// 从配置文件中取图片服务器的url
// 创建返回结果对象
Map result = new HashMap();
result.put("error", 0);
result.put("url", IMAGE_SERVER_URL + url);
// 返回结果
return result;
} catch (Exception e) {
e.printStackTrace();
Map result = new HashMap();
result.put("error", 1);
result.put("message", "图片上传失败");
return result;
}
}
}
上面我们都配置完后,现在我们就来试试图片上传功能,如下图所示,发现点击”开始上传”之后图片正常回显了。
接着我们点击”全部插入”按钮,可以看到在”上传图片”按钮的下方有我们刚才上传的四张图片,我们是可以点击任何一张图片在浏览器中浏览的,比如我们点击第三张图片——a.jpg。
在浏览器中访问的效果如下图所示。这样我们的图片上传功能便实现了。