一、VSFTPD介绍:
1.什么是FTP服务器?
FTP 是 File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。
用于 Internet 上的控制文件的双向传输。同时,它也是一个应用程序(Application)。 基于不同的操作系统有不同的 FTP 应用程序,而所有这些应用程序都遵守同一种协议以传 输文件。
- FTP的作用:
示例在 FTP 的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)。
"下载"文件就是从远程主机拷贝文件至自己的计算机上;
"上传"文件就是将文件从自己的计 算机中拷贝至远程主机上。用 Internet 语言来说,用户可通过客户机程序向(从)远程主机 上传(下载)文件。
2.什么是VSFTPD?
vsftpd 是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点。vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linux、BSD、Solaris、HP-UNIX 等系统上面,是一个完全免费的、开放源代码的 ftp 服务器软件,支持很多其他的 FTP 服务器所不支持的特征。
3.单体框架中的图片管理:
单体框架存储图片的架构图在传统的单体架构项目中,可以在 web 项目中添加一个文件夹,来存放上传的图片。 例如在工程的根目录 WebRoot 下创建一个 images 文件夹用于保存已上传的图片。
优点:使用方便,便于管理 。
缺点:
(1)如果是分布式环境中图片引用会出现问题。
(2)图片的下载会给服务器增加额外的压力 。
遇到的问题
4.分布式环境的图片管理:
分布式环境二、安装vsftpd
1.安装vsftpd组件:
在Linux环境中;使用"yum -y install vsftpd"命令;
安装完后,有/etc/vsftpd/vsftpd.conf 文件,是 vsftp 的配置文件。
2.添加Linux用户:
该用户就是用来登录 ftp 服务器用的。
"useradd ftpuser" 命令;这样一个用户建完,可以用这个登录;登录后默认的路径为 /home/ftpuser。
- 给用户添加密码:
"passwd ftpuser" 命令修改密码;输入两次密码后修改密码(修改中的密码,是不可见的,输入后回车)。
3.防火墙开启21端口:
(1)ftp 默认的端口为 21,而 centos 默认是没有开启的,所以要修改 iptables 文件 "vim /etc/sysconfig/iptables" ,在行上面有 22 -j ACCEPT 下面另起一行输入跟那行差不多的,只是把 22 换成 21,然后: wq 保存。 重启防火墙 "service iptables restart" 命令。
(2)方式二:直接关闭防火墙 "service iptables stop"命令。
4.修改selinux:
on外网是可以访问上去了,可是发现没法返回目录(使用 ftp 的主动模式,被动模式还是无法 访问),也上传不了,因为 selinux 作怪了。
开启外网的访问:
[root@bogon ~]# setsebool -P allow_ftpd_full_access on(回车)
[root@bogon ~]# setsebool -P ftp_home_dir on(回车)。
执行以下命令查看状态:
[root@bogon ~]# getsebool -a | grep ftp (回车)。
4.关闭匿名访问:
vsfpd.conf修改/etc/vsftpd/vsftpd.conf 文件;然后重启ftp服务"service vsftpd restart ";
可以设置开机启动vsftpd ftp服务:"chkconfig vsftpd on "(可以不使用)。
三、使用FTP上传图片
1.使用 FileZilla 上传图片:
上传工具2.使用 FTP 协议访问图片服务器
FTP访问路径:ftp://username:userpassword@IP/路径/图片名称 ;
在 VSFTPD 的插件中。不允许这样访问。必须要有登录环节。
3.使用FTPClient工具实现图片上传:
FTPClient 是 Apache 提供的一个开源的基于 JAVA 语言的 FTP 客户端工具。 FTPClient 位于 Apache 的 commons-net 项目中。
3.1创建项目:
目录 测试- 测试代码:
package com.zlw;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
public class Test {
public static void main(String[] args) throws SocketException, IOException {
// Test test = new Test();
// test.FTPClientTest();
//调用FTP工具类
FileInputStream fs = new FileInputStream("d:/test2.jpg");
FtpUtil.uploadFile("192.168.226.129", 21, "ftpuser", "ftpuser", "/home/ftpuser/test", "2019/11/01", "test3.jpg",fs );
}
/**
* 自定义FTP
* @throws SocketException
* @throws IOException
*/
public void FTPClientTest() throws SocketException, IOException {
//创建FTPClient对象
FTPClient ftp = new FTPClient();
//链接端口使用的21
ftp.connect("192.168.226.129",21);
//给定用户名和密码,链接时完成登录
ftp.login("ftpuser", "ftpuser");
//操作上传文件
FileInputStream fs = new FileInputStream("d:/test2.jpg");
//指定上传文件的保存录目
ftp.changeWorkingDirectory("/home/ftpuser/test");
//开启字节流传输
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
//文件上传
ftp.storeFile("aa.jpg", fs);
//退出登录
ftp.logout();
}
}
- FTPClient 的工具类:
package com.zlw;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
/**
* ftp上传下载工具类
*/
public class FtpUtil {
/**
* Description: 向FTP服务器上传文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if (!ftp.changeWorkingDirectory(basePath+filePath)) {
//如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir)) continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if (!ftp.storeFile(filename, input)) {
return result;
}
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
/**
* Description: 从FTP服务器下载文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
String fileName, String localPath) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File localFile = new File(localPath + "/" + ff.getName());
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
public static void main(String[] args) {
try {
FileInputStream in=new FileInputStream(new File("D:\\1.jpg"));
boolean flag = uploadFile("192.168.10.128", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images","/2015/01/21", "gaigeming.jpg", in);
System.out.println(flag);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
四、基于KindEditor实现图片上传:
1.KindEditor介绍:
KindEditor 是一套开源的 HTML 可视化编辑器,主要用于让用户在网站上获得所见即 所得编辑效果,兼容 IE、Firefox、Chrome、Safari、Opera 等主流浏览器。 KindEditor 使用 JavaScript 编写,可以无缝的于 Java、.NET、PHP、ASP 等程序接合。
KindEditor 非常适合在 CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用, 2006 年 7 月首次发布 2.0 以来,KindEditor 依靠出色的用户体验和领先的技术不断扩大编 辑器市场占有率,目前在国内已经成为最受欢迎的编辑器之一。
官方网址:网址链接;
2.创建项目:
2.1创建parent项目:
- 修改POM文件:
官方网址:网址链接
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zlw</groupId>
<artifactId>02parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 对依赖的jar包的版本统一进行定义 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<druid.version>1.0.9</druid.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<tomcat.version>2.2</tomcat.version>
<jsp-api.version>2.0</jsp-api.version>
<zkClient-version>0.10</zkClient-version>
<dubbo-version>2.5.4</dubbo-version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-net.version>3.3</commons-net.version>
<jackson.version>2.4.2</jackson.version>
</properties>
<!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
<dependencyManagement>
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo-version}</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkClient-version}</version>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- Jackson Json 处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
<pluginManagement>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2.2创建 kindEditorDemo项目(继承parent):
项目- 修改POM文件:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zlw</groupId>
<artifactId>02parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.zlw</groupId>
<artifactId>kindEditorDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- JSP 相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
<!-- Jackson Json 处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 配置 Tomcat 插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.项目框架整合:
3.1web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 上下文参数,告诉spring配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置springmvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.2springmvc.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描@Controller -->
<context:component-scan base-package="com.zlw.controller"></context:component-scan>
<!-- 注册两个新对象 主要是为了来处理springmvc 中的其他 anntation 如:@requestmapping -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置静态资源映射 -->
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
<!-- 文件上传处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxInMemorySize" value="1024"></property>
<property name="maxUploadSize" value="1000000"></property>
</bean>
</beans>
3.3applicationContext-service.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:resource.properties"/>
<!-- 扫描bean对象 -->
<context:component-scan base-package="com.zlw.service"/>
</beans>
3.4resource.properties:
FTP_HOST=192.168.226.129
FTP_POST=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=ftpuser
FTP_BASEPATH=/home/ftpuser/
HTTP_BASEPATH=http://192.168.226.129
4.KindEditor使用方式:
4.1自定义工具类:
- FtpUtil(FTPClient 工具类 ):
package com.zlw.commons;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
/**
* ftp上传下载工具类
*/
public class FtpUtil {
/**
* Description: 向FTP服务器上传文件
*
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
// 切换到上传目录
if (!ftp.changeWorkingDirectory(basePath + filePath)) {
// 如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
// 设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 上传文件
if (!ftp.storeFile(filename, input)) {
return result;
}
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
/**
* Description: 从FTP服务器下载文件
*
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
String fileName, String localPath) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File localFile = new File(localPath + "/" + ff.getName());
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
public static void main(String[] args) {
try {
FileInputStream in = new FileInputStream(new File("D:\\1.jpg"));
boolean flag = uploadFile("192.168.10.128", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images",
"/2015/01/21", "gaigeming.jpg", in);
System.out.println(flag);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
- IDUtils:
生成一切 ID 的策略的工具类。可以使用他生成图片名称 。
package com.zlw.commons;
import java.util.Random;
import java.util.UUID;
/**
* 各种id生成策略
* @version 1.0
*/
public class IDUtils {
/**
* 图片名生成
*/
public static String genImageName() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上三位随机数
Random random = new Random();
int end3 = random.nextInt(999);
//如果不足三位前面补0
String str = millis + String.format("%03d", end3);
return str;
}
/**
* 商品id生成
*/
public static long genItemId() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上两位随机数
Random random = new Random();
int end2 = random.nextInt(99);
//如果不足两位前面补0
String str = millis + String.format("%02d", end2);
long id = new Long(str);
return id;
}
}
- JsonUtils:
对象与 json 格式转换的工具类。
package com.zlw.commons;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* JSON转换工具类
*/
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;
}
}
4.2JSP中使用KindEditor:
- 使用步骤:
(1)在项目中添加 KindEditor 与 Jquery 的 js 文件 ;
(2) 在 JSP 页面中通过 script 标签引入 js ;
(3) 在 JSP 中添加 textarea 标签 ;
(4)调用 KindEditor 的 API 将 KindEditor 渲染到 textarea ;
- JSP:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="/js/kindeditor/kindeditor.js"></script>
<script type="text/javascript" src="/js/kindeditor/lang/zh_CN.js"></script>
<script type="text/javascript" src="/js/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function() {
var obj;
KindEditor.ready(function(K) {
obj = K.create('#text_id', {
uploadJson : '/upload/file',
filePostName : 'fileName',
dri : "image"
})
});
//添加事件
$("#but").click(function(){
//将KindEditor中的数据同步到textare
obj.sync();
//通过 ajax 方式提交表单 serialize()作用:将表单中的数据序列化为 key=value&key=value.....
$.post("/content/save",$("#myForm").serialize(),function(data){
if(data.status ==200){
alert("提交成功!");
}else{
alert("提交失败!");
}
})
});
})
</script>
</head>
<body>
<form id="myForm">
<textarea rows="20" cols="20" name="desc" id="text_id"></textarea>
<input type="button" value="提交" id="but"/>
</form>
</body>
</html>
4.3KindEditor 初始化参数介绍:
(1)uploadJson:指定上传文件的服务器端程序 ;
(2)FilePostName:指定上传文件 form 名称;
(3)dir:指定上传文件类型 ;
5.实现图片上传:
- Service:
package com.zlw.service.impl;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zlw.commons.FtpUtil;
import com.zlw.commons.IDUtils;
/**
* 图片上传
*/
import com.zlw.service.UploadService;
@Service
public class UploadServiceImpl implements UploadService {
@Value("${FTP_HOST}")
private String FTP_HOST;
@Value("${FTP_POST}")
private int FTP_POST;
@Value("${FTP_USERNAME}")
private String FTP_USERNAME;
@Value("${FTP_PASSWORD}")
private String FTP_PASSWORD;
@Value("${FTP_BASEPATH}")
private String FTP_BASEPATH;
@Value("${HTTP_BASEPATH}")
private String HTTP_BASEPATH;
@Override
public Map<String, Object> fileUpload(MultipartFile fileName) {
Map<String, Object> map = new HashMap<String, Object>();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/mm/dd/");
String path = sdf.format(date);
String newFileName = IDUtils.genImageName()
+ fileName.getOriginalFilename().substring(fileName.getOriginalFilename().lastIndexOf("."));
try {
boolean flag = FtpUtil.uploadFile(FTP_HOST, FTP_POST, FTP_USERNAME, FTP_PASSWORD, FTP_BASEPATH, path,
newFileName, fileName.getInputStream());
if(flag) {
map.put("error", 0);
map.put("url", this.HTTP_BASEPATH+path+newFileName);
}else {
map.put("error", 1);
map.put("message", "上传失败!");
}
} catch (IOException e) {
map.put("error", 1);
map.put("message", "上传失败!");
e.printStackTrace();
}
return map;
}
}
- PageController:
package com.zlw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PageController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page) {
return page;
}
}
- UploadController:
package com.zlw.controller;
import java.util.HashMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/content")
public class ContentController {
@RequestMapping("/save")
@ResponseBody
public Object saveContent(String desc) {
System.out.println(desc);
HashMap<String, Object> map = new HashMap<>();
map.put("status", 200);
return map;
}
}
6. 提交 KindEditor 中的数据 :
在 KindEditor 中提交方式需要使用 Ajax 方式提交。需要使用 KindEditor 的一个 sync()的方法将数据同步到textarea。
- ContentController:
package com.zlw.controller;
import java.util.HashMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/content")
public class ContentController {
@RequestMapping("/save")
@ResponseBody
public Object saveContent(String desc) {
System.out.println(desc);
HashMap<String, Object> map = new HashMap<>();
map.put("status", 200);
return map;
}
}
-
实现效果:
image.png
网友评论