测试的前提是得有fastdfs服务器和nginx服务器
工具类下载地址https://download.csdn.net/download/kxj19980524/10856903
这个在中央仓库没有,下载好后解压,里面是个maven项目,导入到eclipse种安装到本地打成jar包,然后复制pom里面的依赖到项目中就可以使用了.
这个是直接打好的jar包 https://download.csdn.net/download/kxj19980524/10857337
使用这种方式引入的话比较麻烦,得把它放到项目的一个目录下,然后自己定义一个maven依赖引入到本地,例如下面这个引入第三方依赖,需要自己定义一个依赖到本地.
<dependency> <groupId>xx</groupId> <artifactId>yy</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/lib/CCP_REST_SMS_SDK_JAVA_v2.6.3r.jar</systemPath> </dependency>
jar包弄好后进行测试上传图片,首先创建一个tracker_server的配置文件,内容就写tracker服务器的地址就可以了.
然后写个test测试类
package fast; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.StorageClient; import org.csource.fastdfs.StorageServer; import org.csource.fastdfs.TrackerClient; import org.csource.fastdfs.TrackerServer; import org.junit.Test; //import cn.e3mall.common.utils.FastDFSClient; public class FastDfsTest { @Test public void testUpload() throws Exception { //创建一个配置文件。文件名任意。内容就是tracker服务器的地址。 //使用全局对象加载配置文件。必须绝对路径 ClientGlobal.init("E:\\idea\\project\\exam12\\src\\main\\resources\\client.conf"); //创建一个TrackerClient对象 TrackerClient trackerClient = new TrackerClient(); //通过TrackClient获得一个TrackerServer对象 TrackerServer trackerServer = trackerClient.getConnection(); //创建一个StrorageServer的引用,可以是null StorageServer storageServer = null; //创建一个StorageClient,参数需要TrackerServer和StrorageServer StorageClient storageClient = new StorageClient(trackerServer, storageServer); //使用StorageClient上传文件。第一个参数是图片绝对路径,第二个是后缀名,不能加. 第三个是关于图片的源数据写null就可以了 String[] strings = storageClient.upload_file("F:\\pic\\0d436918e1e6f7d2d68817e6df01f412.jpg", "jpg", null); for (String string : strings) { System.out.println(string); } }
}
返回是数据就是上传到fastdfs的路径,然后就可以通过http协议去访问图片了,
当然没回这么写肯定麻烦,所有可以封装一个工具类
package fast; import org.csource.common.NameValuePair; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.StorageClient1; import org.csource.fastdfs.StorageServer; import org.csource.fastdfs.TrackerClient; import org.csource.fastdfs.TrackerServer; 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); } }
然后再进行测试,可以看看那个工具类,构造方法中写的是配置文件路径,如果不写测试类的话,这个路径可以简写成classpath:后面加文件名,自己看看工具类的封装,图片名这块可以不指定扩展名,如果是字节数组的话,需要传扩展名的.
结合项目,从前台传图片上传的话 参考这个https://blog.csdn.net/kxj19980524/article/details/83536366
添加jair包
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
springmvc中配置多媒体解析器,和读取配置文件
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:conf/resource.properties" /><!-- 上传图片解析器 此处的id不能改变-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"></property>
</bean>
controller代码,因为这个fastdsf的路径如果写死的话,到时候项目上线如果要换的话还得改代码,所以以读取配置文件的方式来读取地址.我用的返回方式是string的方式,因为使用string的话,默认的返回格式就成了text/plain,这种格式是兼容性最好的.别的浏览器也可以上传图片.
package cn.e3mall.controller;
import java.util.HashMap;
import java.util.Map;import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
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 cn.e3mall.common.utils.FastDFSClient;
import cn.e3mall.common.utils.JsonUtils;/**
* 图片上传处理Controller
* <p>Title: PictureController</p>
* <p>Description: </p>
* <p>Company: www.itcast.cn</p>
* @version 1.0
*/
@Controller
public class PictureController {
@Value("${IMAGE_SERVER_URL}")
private String IMAGE_SERVER_URL;@RequestMapping(value="/pic/upload", produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@ResponseBody
public String uploadFile(MultipartFile uploadFile) {
try {
//把图片上传的图片服务器
FastDFSClient fastDFSClient = new FastDFSClient("classpath:conf/client.conf");
//取文件扩展名
String originalFilename = uploadFile.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
//得到一个图片的地址和文件名
String url = fastDFSClient.uploadFile(uploadFile.getBytes(), extName);
//补充为完整的url
url = IMAGE_SERVER_URL + url;
//封装到map中返回 这儿返回值,根据自己需求自己定义. 这用的是json工具类转json串
Map result = new HashMap<>();
result.put("error", 0);
result.put("url", url);
return JsonUtils.objectToJson(result);
} catch (Exception e) {
e.printStackTrace();
Map result = new HashMap<>();
result.put("error", 1);
result.put("message", "图片上传失败");
return JsonUtils.objectToJson(result);
}
}
}
json工具类,里面使用的是jackson
package fast; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** * 淘淘商城自定义响应结构 */ public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 * <p>Title: pojoToJson</p> * <p>Description: </p> * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */ public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } }