实现一个简单的文件下载服务器

前面的文章《使用SpringBoot实现静态网站》,用SpringBoot实现了一个古诗词网。其实,在这个服务器的static目录中放入其他的文件,譬如readme.txt文件,通过浏览器可以直接查看,通过迅雷,也可以直接下载:

但是,把这个功能当成文件下载功能,就太粗糙了。个人认为,即使最简单的文件下载服务器,也至少具备下面两个要点:

(1)通过浏览器输入要下载的资源的URL后,浏览器可以保存附件;

(2)软件工程师可以根据需要,添加控制文件下载权限的代码。

下面,我们基于SpringBoot,使用IDEA开发工具,开发一个简单的文件下载服务器吧。

第1步:使用IDEA创建一个空项目fc_prj,然后在fc_prj项目中添加一个SpringBoot项目file_center,加入Lombok、Spring Web、Spring Data JPA、MySQL Driver四个依赖。操作完成后项目视图如下:

第2步:在mysql中执行下面的SQL语句,建立本项目使用的数据库db_fc:

create database db_fc default character set utf8;

第3步:在db_fc数据库中建立t_user表,用于进行权限控制,为了让程序显得简单,这里t_user表只包含用户名、密码、备注三个字段,建立t_user表的SQL语句如下:

use db_fc;
create table t_user(
user_name varchar(32) primary key not null,
password varchar(32) not null,
comment varchar(64)
)engine=InnoDB default charset=utf8;

第4步:我们在t_user表中插入张三、李四、王五三个用户的信息,SQL语句如下:

insert into t_user(user_name, password, comment) values('zhangsan', 'zhang', '用户张三');
insert into t_user(user_name, password, comment) values('lisa', 'li', '用户李四');
insert into t_user(user_name, password, comment) values('wangwu', 'wang', '用户王五');
commit;

第5步:在db_fc数据库中建立t_file表,用于记录可以下载的文件信息,该表有文件标识符、文件完整路径两个字段,建立t_file表的SQL语句如下:

use db_fc;
create table t_file(
file_id varchar(32) primary key not null,
file_path varchar(512) not null
)engine=InnoDB default charset=utf8;

第6步:我们向t_file表中插入一些可以下载的文件信息,SQL语句如下:

insert into t_file(file_id, file_path) values('flower', '/root/files/flower.jpg');
insert into t_file(file_id, file_path) values('hello.txt', '/root/files/hello.txt');
commit;

第7步:新建entity包;

第8步:在entity包中建立UserEntity类,一个UserEntity实例对应t_user表的一条记录。UserEntity的代码如下:

package com.flying.file_center.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Table(name="t_user")
@Entity
public class UserEntity {
@Id
private String userName;
private String password;
private String comment;
}

第9步:在entity包中建立FileEntity类,一个FileEntity实例对应t_file表的一条记录。FileEntity的代码如下:

package com.flying.file_center.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Table(name="t_file")
@Entity
public class FileEntity {
@Id
private String fileId;
private String filePath;
}

第10步:新建repository包;

第11步:在repository包中建立UserRepository接口,用于操作t_user表,代码如下:

package com.flying.file_center.repository;
import com.flying.file_center.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository, JpaSpecificationExecutor {
List queryUserEntitiesByUserNameAndPassword(String userName, String password);
}

第12步:在repository包中建立FileRepository接口,用于操作t_file表,代码如下:

package com.flying.file_center.repository;
import com.flying.file_center.entity.FileEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface FileRepository extends JpaRepository, JpaSpecificationExecutor {
List queryFileEntitiesByFileId(String fileId);
}

第13步:新建controller包和service包:

第14步:在service包中建立FileService类,用于实现处理HTTP下载请求,代码如下:

package com.flying.file_center.service;
import com.flying.file_center.entity.FileEntity;
import com.flying.file_center.entity.UserEntity;
import com.flying.file_center.repository.FileRepository;
import com.flying.file_center.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.List;
@Service
public class FileService {
@Autowired
private FileRepository fileRepository;
@Autowired
private UserRepository userRepository;
public void download(String userName, String password, String fileId, HttpServletResponse httpServletResponse){
List userEntityList = userRepository.queryUserEntitiesByUserNameAndPassword(userName, password);
if (userEntityList.size() == 0){
httpServletResponse.setStatus(401);
return;
}
List fileEntityList = fileRepository.queryFileEntitiesByFileId(fileId);
if (fileEntityList.size() == 0){
httpServletResponse.setStatus(404);
return;
}

File file = new File(fileEntityList.get(0).getFilePath());
if (file.exists()) {
httpServletResponse.setContentType("application/force-download");
httpServletResponse.addHeader("Content-Disposition",
"attachment;fileName=" + fileEntityList.get(0).getFileId());
byte[] bytesBuffer = new byte[1024];
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
) {
OutputStream outputStream = httpServletResponse.getOutputStream();
int i = bis.read(bytesBuffer);
while (i != -1) {
outputStream.write(bytesBuffer, 0, i);
i = bis.read(bytesBuffer);
}
} catch (Exception e) {
e.printStackTrace();
}
}else{
httpServletResponse.setStatus(404);
}
}
}

第15步:在controller包中建立FileController类,用于接收来自浏览器或其他客户端的HTTP下载请求,代码如下:

package com.flying.file_center.controller;
import com.flying.file_center.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
@Slf4j
public class FileController {
@Autowired
private HttpServletResponse httpServletResponse;

@Autowired
private FileService fileService;
@GetMapping("/download/{userName}/{password}/{fileId}")
public void download(@PathVariable(value="userName") String userName,
@PathVariable(value="password") String password,
@PathVariable(value="fileId") String fileId){
fileService.download(userName, password, fileId, httpServletResponse);
}
}

第16步:修改application.properties文件,加入服务器的配置信息,这里只配置服务器使用的端口和数据库连接信息,application.properties文件的内容如下:

server.port=9201
spring.datasource.url=jdbc:mysql://127.0.0.1/db_fc?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5

第17步:修改pom.xml文件,加入编译和打包的信息,修改后的pom.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

4.0.0

org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE
 

com.flying
file_center
1.0.1
file_center
Demo project for Spring Boot

1.8



org.springframework.boot
spring-boot-starter-data-jpa


org.springframework.boot
spring-boot-starter-web


mysql
mysql-connector-java
runtime


org.projectlombok
lombok
true


org.springframework.boot
spring-boot-starter-test
test


org.junit.vintage
junit-vintage-engine





fc



org.apache.maven.plugins
maven-jar-plugin



*.properties
*.txt
*.xml



true

fc_lib/

false

com.flying.file_center.FileCenterApplication



./resources/


${project.build.directory}




org.apache.maven.plugins
maven-dependency-plugin


copy-dependencies
package

copy-dependencies



${project.build.directory}/fc_lib/







maven-resources-plugin


copy-resources
package

copy-resources




src/main/resources


${project.build.directory}/resources






第18步:在IDEA的Terminal窗口输入mvn clean package -DskipTests命令,完成程序的编译与打包,得到fc.jar和相关的文件:

第19步:将fc.jar文件和依赖的库文件和资源文件拷贝到Linux运行环境:

第20步:在Linux的/root目录中新建files目录,然后向该目录中传入两个文件flower.jpg和hello.txt:

第21步:执行java -jar fc.jar命令,启动文件下载服务器:

第22步:当我们在浏览器中输入http://<服务器IP>:9201/download/zhangsan/zhang/flower时,浏览器会自动下载文件flower.jpg,并且生成的文件名是我们指定的FileId,也就是flower:

第23步:当我们在浏览器中故意输错用户名或密码,例如输入http://<服务器IP>:9201/download/zhangsan/zhang2/flower时,将会得到HTTP 401错误:

第24步:当我们在浏览器中故意输错文件ID,例如输入http://<服务器IP>:9201/download/zhangsan/zhang/flower.jpg时,将会得到HTTP 404错误:

开发完成!

展开阅读全文

页面更新:2024-03-26

标签:服务器   文件   语句   浏览器   两个   代码   操作   简单   项目   用户   信息

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top