一、FTP服务器简介
FTP是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文件协议”。
用于Internet上的控制文件的双向传输。同时,它也是一个应用程序。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。
在FTP的使用当中,用户经常遇到两个概念:“下载”(Download)和“上传”(Upload)。“下载”文件就是从远程计算机上拷贝文件到自己的计算机上,“上传”文件就是将文件从自己的计算机拷贝到远程计算机上。用Internet语言来说,用户可通过客户机程序向(从)远程客户机上传(下载)文件。
image.png
二、什么是VSFTPD
VSFTPD是“very secure FTP deamon”的缩写,安全性是它的一个最大特带你,vsftpd是一个UNIX类操作系统上运行的服务器的名称,它可以运行在Linux、BSD、Solaris、HP-UNIX等系统上面,是一个完全免费的、开放源码的ftp服务器软件,支持很多其他的FTP服务器所不支持的特征。
image.png
三、项目中图片服务器
1.单体架构中的图片管理
在传统的单体项目架构中,可以在web项目中添加一个文件夹,来存放上传的图片,例如在工程的根目录的webapp文件夹下创建一个images文件夹保存已上传的图片。
优点:
- 使用方便,便于管理
缺点:
- 如果是分布式环境中图片引用会出现问题。
- 图片的下载会给服务器增加额外的压力。
2.传统图片管理方式在分布式环境中的问题:
注意:负载均衡服务器中采用轮询策略
image.png
3.分布式环境的图片管理
image.png
四、安装VSFTP
1.安装vsftpd组件
yum -y install vsftpd
安装完后,有/etc/vsftpd/vsftpd.conf文件,是vsftp的配置文件。
2.添加一个Linux用户
此用户就是用来登录ftp服务器用的
useradd ftpuser(用户名)
这样一个用户建完,可以用这个登录。登陆后默认的路径是/home/ftpuser。
3.给用户添加密码
passwd ftpuser(用户名)
输入两次密码后修改密码
4.防火墙开启21端口
4.1 方案一:
因为ftp默认的端口为21,而centos默认是没有开启的,所以要修改iptables文件
vim /etc/sysconfig/iptables
在上面有22 -j ACCEPT 下面另起一行输入跟那行差不多的,只是把22换成21,然后:wq保存。
还要运行下,重启iptables
service iptables restart
4.2 方案二:
关闭linux防火墙
5.修改selinux
外网是可以访问上去了,可是发现没法返回目录(使用ftp的主动模式,被动模式还是无法访问),也上传不了,因为selinux做怪了
修改selinux:
执行以下命令查看状态
[root@bogon ~] getsebool -a | grep ftp
allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
ftp_home_dir --> off
ftpd_connect_db --> off
ftpd_use_passive_mode --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
[root@bogon ~]#
执行上面命令,再返回的结果看到两行都是 off,代表,没有开启外网的访问
[root@bogon ~] setsebool -P allow_ftpd_full_access on
[root@bogon ~] setsebool -P ftp_home_dir on
6.关闭匿名访问
修改/etc/vsftpd/vsftpd.conf文件:
image.png
重启ftp服务
service vsftpd restart
7.设置开机启动vsftpd ftp服务
chkconfig vsftpd on
五、图片上传
1.使用FileZilla上传图片
image.png
2.使用FTP协议访问图片服务器
FTP协议的URL格式:
ftp:username:password@IP/路径/图片名称
在VSFTPD的插件中,不允许这样访问,必须要有登录环节。
3. FTPClient工具
3.1 FTPClient介绍
FTPClient是Apache提供的一个开源的基于Java语言的FTP客户端工具。
FTPClient位于Apache的commons.net项目中。
3.2 FTPClient的使用
3.2.1 添加依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
3.2.2 代码编写
//FTPClient的使用
public static void FTPClientTest() throws IOException {
//创建FTPClient对象
FTPClient ftpClient = new FTPClient();
//连接 使用21端口
ftpClient.connect("192.168.254.128",21);
//给定用户名和密码,连接时完成登录
ftpClient.login("ftpuser","ftpuser");
//操作文件
InputStream is = new FileInputStream("d:/picture/ftpserver.png");
//指定上传文件的路径
ftpClient.changeWorkingDirectory("/home/ftpuser/suibian");
//开启字节流传输(必须)
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
//文件上传
ftpClient.storeFile("aaa.png",is);
is.close();
//退出登录
ftpClient.logout();
}
六、KindEditor简介
KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得的效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。
KindEditor使用JavaScript编写,可以无缝的与Java、.NET、PHP、ASP等程序结合。KindEditor非常适合在CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用,2006年7月首次发布2.0以来,KindEditor依赖出色的用户体验和领先的技术,不断扩大编辑器市场占有率,目前在国内已成为最受欢迎的编辑器之一。
官网:http://kindeditor.net
七、基于KindEditor实现图片上传
1.创建parent项目
1.1 修改pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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.hxx</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<name>parent</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<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-net.version>3.6</commons-net.version>
<commons-fileupload.version>1.3.2</commons-fileupload.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>
<!--commons-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.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>
<pluginManagement>
<!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2.创建kindEditorDemo项目
2.1 添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>parent</artifactId>
<groupId>com.hxx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kindEditorDemo</artifactId>
<packaging>war</packaging>
<name>kindEditorDemo Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- Spring -->
<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>
<!--commons-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<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>
<version>${tomcat.version}</version>
<configuration>
<path>/</path>
<port>8888</port>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.框架整合
3.1 applicationContext-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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--解析资源文件-->
<context:property-placeholder location="resources.properties"/>
<!--扫包-->
<context:component-scan base-package="com.hxx.service"/>
</beans>
3.2 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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--添加注解驱动-->
<mvc:annotation-driven/>
<!--指定Handler-->
<context:component-scan base-package="com.hxx.web.controller"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置文件上传处理器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxInMemorySize" value="1024"/>
<!--单位字节-->
<property name="maxUploadSize" value="1000000"/>
</bean>
</beans>
3.3 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--设置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>
<!--配置前端控制器-->
<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>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.4 resources.properties
FTP_HOST=192.168.254.128
FTP_PORT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=ftpuser
FTP_BASEPATH=/home/ftpuser/
HTTP_BASEPATH=http://192.168.254.128/
4.KindEditor使用方式
4.1 自定义工具类介绍
FtpUtil:FTPClient工具类
IDUtils:生成一些ID的策略的工具类。可以使用它生成图片名称
JsonUtils:对象与json格式转换的工具类
5.实现图片的上传
5.1 代码编写
5.1.1 PicUploadController
/**
* 图片上传
*/
@Controller
@RequestMapping("/pic")
public class PicUploadController {
@Autowired
private PicUploadService picUploadService;
//图片上传
@RequestMapping("/upload")
@ResponseBody
public String fileUpload(MultipartFile fileName){
Map<String, Object> map = picUploadService.fileUpload(fileName);
return JsonUtils.objectToJson(map);
}
}
5.1.2 PicUploadService
public interface PicUploadService {
Map<String, Object> fileUpload(MultipartFile fileName);
}
5.1.3 PicUploadServiceImpl
/**
* 图片上传Service
*/
@Service
public class PicUploadServiceImpl implements PicUploadService {
@Value("${FTP_HOST}")
private String FTP_HOST;
@Value("${FTP_PORT}")
private int FTP_PORT;
@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<>();
Date date = new Date();
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
String filePath = sdf.format(date);
//从文件名中的最后一个“.”的位置向后截取,得到图片的后缀
String newFileName = IDUtils.genImageName() + fileName.getOriginalFilename().substring(fileName.getOriginalFilename().lastIndexOf("."));
boolean flag = FtpUtil.uploadFile(this.FTP_HOST, this.FTP_PORT, this.FTP_USERNAME, this.FTP_PASSWORD, this.FTP_BASEPATH, filePath, newFileName, fileName.getInputStream());
if (flag){
//上传成功
map.put("error",0);
//http://192.168.254.128/filePath/newFileName
map.put("url",this.HTTP_BASEPATH + filePath + newFileName);
}else {
//上传失败
map.put("error",1);
map.put("message","上传失败");
}
} catch (IOException e) {
//上传失败
map.put("error",1);
map.put("message","上传失败");
e.printStackTrace();
}
return map;
}
}
6.KindEditor在Jsp中的使用
6.1 使用步骤
- 在项目中添加kindEditor与jquery的js文件
- 在jsp页面中引入js
- 在jsp中添加textarea标签
- 调用kindEditor的API将KindEditor渲染到textarea
<script>
$(function () {
KindEditor.ready(function (K) {
K.create('#text_id',{
uploadJson:'/pic/upload',
filePostName:'fileName',
dir:'image'
});
})
})
</script>
6.2 KindEditor初始化参数介绍
- uploadJson:指定上传文件的服务器端程序。
- filePostName:指定上传文件表单名称。
- dir:上传图片的类型,可指定为image、flash、media、file
6.3 提交KindEditor中的数据
- 在KindEditor中提交方式需要使用Ajax方式提交,需要使用KindEditor的一个sync()的方法将数据同步到textarea
6.3.1 script页面的编写
<script>
var obj;
$(function () {
KindEditor.ready(function (K) {
obj = K.create('#text_id',{
uploadJson:'/pic/upload',
filePostName:'fileName',
dir:'image'
});
})
});
//给按钮添加点击事件
function btnChecked() {
//将kindEditor中的数据同步到textarea中
obj.sync();
//通过ajax方式提交表单
//serialize():将表单中的数据序列化为key = value & key = value ....的格式
$.post("/content/save",$("#myForm").serialize(),function (result) {
if (result.status == 200) {
alert("提交成功");
}else{
alert("提交失败");
}
});
}
</script>
6.3.2 ContentController
- 方式一:
//内容保存
@RequestMapping("/save")
@ResponseBody
public Object save(String desc){
System.out.println(desc);
Map<String,Object> map = new HashMap<>();
map.put("status",200);
return map;
}
- 方式二:
@RequestMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String save(String desc){
System.out.println(desc);
Map<String,Object> map = new HashMap<>();
map.put("status",200);
return JsonUtils.objectToJson(map);
}









网友评论