当前位置: 首页 > wzjs >正文

在哪里推广网站深圳公司社保网站

在哪里推广网站,深圳公司社保网站,衡水购物网站制作,sap和国家网站做接口Spring Boot 集成 Dufs 通过 WebDAV 实现文件管理 引言 在现代应用开发中,文件存储和管理是一个常见需求。Dufs 是一个轻量级的文件服务器,支持 WebDAV 协议,可以方便地集成到 Spring Boot 应用中。本文将详细介绍如何使用 WebDAV 协议在 Sp…

Spring Boot 集成 Dufs 通过 WebDAV 实现文件管理

在这里插入图片描述

引言

在现代应用开发中,文件存储和管理是一个常见需求。Dufs 是一个轻量级的文件服务器,支持 WebDAV 协议,可以方便地集成到 Spring Boot 应用中。本文将详细介绍如何使用 WebDAV 协议在 Spring Boot 中集成 Dufs 文件服务器。

1. 准备工作

1.1 添加项目依赖

pom.xml 中添加必要依赖:

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Sardine WebDAV 客户端 --><dependency><groupId>com.github.lookfirst</groupId><artifactId>sardine</artifactId><version>5.10</version></dependency>
</dependencies>

2. 核心实现

2.1 配置类

@Configuration
@ConfigurationProperties(prefix = "dufs.webdav")
@Data
public class DufsWebDavConfig {private String url = "http://localhost:5000";private String username = "admin";private String password = "password";private String basePath = "/";@Beanpublic Sardine sardine() {Sardine sardine = SardineFactory.begin();sardine.setCredentials(username, password);return sardine;}
}

2.2 服务层实现

@Service
@RequiredArgsConstructor
@Slf4j
public class DufsWebDavService {private final Sardine sardine;private final DufsWebDavConfig config;/*** 自定义 WebDAV 异常*/public static class DufsWebDavException extends RuntimeException {public DufsWebDavException(String message) {super(message);}public DufsWebDavException(String message, Throwable cause) {super(message, cause);}}/*** 构建完整的 WebDAV 路径*/private String buildFullPath(String path) {return config.getUrl() + config.getBasePath() + (path.startsWith("/") ? path : "/" + path);}/*** 上传文件*/public String uploadFile(String path, InputStream inputStream) throws IOException {String fullPath = buildFullPath(path);sardine.put(fullPath, inputStream);return fullPath;}/*** 下载文件实现(方案1)* ByteArrayResource(适合小文件)*/public Resource downloadFileByte(String path) {String fullPath = buildFullPath(path);try {InputStream is = sardine.get(fullPath);byte[] bytes = IOUtils.toByteArray(is); // 使用 Apache Commons IOreturn new ByteArrayResource(bytes) {@Overridepublic String getFilename() {return path.substring(path.lastIndexOf('/') + 1);}};} catch (IOException e) {throw new DufsWebDavException("Failed to download file: " + path, e);}}/*** 下载文件实现(方案2)* StreamingResponseBody(适合大文件)*/public StreamingResponseBody downloadFileStreaming(String path) {String fullPath = buildFullPath(path);return outputStream -> {try (InputStream is = sardine.get(fullPath)) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}};}/*** 下载文件实现(方案3)* 自定义可重复读取的 Resource(推荐)*/public Resource downloadFile(String path) {String fullPath = buildFullPath(path);try {// 测试文件是否存在if (!sardine.exists(fullPath)) {throw new DufsWebDavException("File not found: " + path);}return new AbstractResource() {@Overridepublic String getDescription() {return "WebDAV resource [" + fullPath + "]";}@Overridepublic InputStream getInputStream() throws IOException {// 每次调用都获取新的流return sardine.get(fullPath);}@Overridepublic String getFilename() {return path.substring(path.lastIndexOf('/') + 1);}};} catch (IOException e) {throw new DufsWebDavException("Failed to download file: " + path, e);}}/*** 列出目录下的文件信息*/public List<WebDavFileInfo> listDirectory(String path) {String fullPath = buildFullPath(path);try {List<DavResource> resources = sardine.list(fullPath);return resources.stream().filter(res -> !res.getHref().toString().equals(fullPath + "/")).map(res -> new WebDavFileInfo(res.getHref().getPath(), res.isDirectory(), res.getContentLength(), res.getModified())).collect(Collectors.toList());} catch (IOException e) {throw new DufsWebDavException("Failed to list directory: " + path, e);}}/*** 创建目录*/public void createDirectory(String path) {String fullPath = buildFullPath(path);try {sardine.createDirectory(fullPath);} catch (IOException e) {throw new DufsWebDavException("Failed to create directory: " + path, e);}}/*** 删除文件/目录*/public void delete(String path) {String fullPath = buildFullPath(path);try {sardine.delete(fullPath);} catch (IOException e) {throw new DufsWebDavException("Failed to delete: " + path, e);}}/*** 检查文件/目录是否存在*/public boolean exists(String path) {String fullPath = buildFullPath(path);try {sardine.exists(fullPath);return true;} catch (IOException e) {return false;}}/*** 锁定文件*/public String lockFile(String path) {String fullPath = buildFullPath(path);try {return sardine.lock(fullPath);} catch (IOException e) {throw new DufsWebDavException("Failed to lock file: " + path, e);}}/*** 解锁文件*/public void unlockFile(String path, String lockToken) {String fullPath = buildFullPath(path);try {sardine.unlock(fullPath, lockToken);} catch (IOException e) {throw new DufsWebDavException("Failed to unlock file: " + path, e);}}/*** 文件信息DTO*/@Data@AllArgsConstructorpublic static class WebDavFileInfo implements java.io.Serializable {private String name;private boolean directory;private Long size;private Date lastModified;}
}

2.3 控制器层

@RestController
@RequestMapping("/api/webdav")
@RequiredArgsConstructor
public class WebDavController {private final DufsWebDavService webDavService;@PostMapping("/upload")public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file,@RequestParam(value = "path", defaultValue = "") String path) {try {String filePath = path.isEmpty() ? file.getOriginalFilename(): path + "/" + file.getOriginalFilename();String uploadPath = webDavService.uploadFile(filePath, file.getInputStream());return ResponseEntity.ok().body(uploadPath);} catch (IOException e) {throw new DufsWebDavService.DufsWebDavException("File upload failed", e);}}@GetMapping("/download")public ResponseEntity<Resource> downloadFile(@RequestParam String path) {Resource resource = webDavService.downloadFileByte(path);return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=\"" + resource.getFilename() + "\"").body(resource);}@GetMapping("/downloadFileStreaming")public ResponseEntity<StreamingResponseBody> downloadFileStreaming(@RequestParam String path) {StreamingResponseBody responseBody = webDavService.downloadFileStreaming(path);return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + path + "\"").body(responseBody);}@GetMapping("/list")public ResponseEntity<List<DufsWebDavService.WebDavFileInfo>> listDirectory(@RequestParam(required = false) String path) {return ResponseEntity.ok(webDavService.listDirectory(path == null ? "" : path));}@PostMapping("/directory")public ResponseEntity<?> createDirectory(@RequestParam String path) {webDavService.createDirectory(path);return ResponseEntity.status(HttpStatus.CREATED).build();}@DeleteMappingpublic ResponseEntity<?> delete(@RequestParam String path) {webDavService.delete(path);return ResponseEntity.noContent().build();}@GetMapping("/exists")public ResponseEntity<Boolean> exists(@RequestParam String path) {return ResponseEntity.ok(webDavService.exists(path));}

3. 高级功能

3.1 大文件分块上传

public void chunkedUpload(String path, InputStream inputStream, long size) {String fullPath = buildFullPath(path);try {sardine.enableChunkedUpload();Map<String, String> headers = new HashMap<>();headers.put("Content-Length", String.valueOf(size));sardine.put(fullPath, inputStream, headers);} catch (IOException e) {throw new RuntimeException("Chunked upload failed", e);}
}

3.2 异步操作

@Async
public CompletableFuture<String> asyncUpload(String path, MultipartFile file) {try {uploadFile(path, file.getInputStream());return CompletableFuture.completedFuture("Upload success");} catch (IOException e) {CompletableFuture<String> future = new CompletableFuture<>();future.completeExceptionally(e);return future;}
}

4. 性能优化

  1. 连接池配置

    @Bean
    public Sardine sardine() {Sardine sardine = SardineFactory.begin(username, password);sardine.setConnectionTimeout(5000);sardine.setReadTimeout(10000);return sardine;
    }
    
  2. 流式下载大文件

    @GetMapping("/download-large")
    public ResponseEntity<StreamingResponseBody> downloadLargeFile(@RequestParam String path) {return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + path + "\"").body(outputStream -> {try (InputStream is = sardine.get(buildFullPath(path))) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}});
    }
    

5. 常见问题解决

5.1 InputStream 重复读取问题

使用 ByteArrayResource 或缓存文件内容解决:

public Resource downloadFile(String path) {return new ByteArrayResource(getFileBytes(path)) {@Overridepublic String getFilename() {return path.substring(path.lastIndexOf('/') + 1);}};
}

5.2 异步方法返回错误

Java 8 兼容的失败 Future 创建方式:

@Async
public CompletableFuture<String> asyncOperation() {try {// 业务逻辑return CompletableFuture.completedFuture("success");} catch (Exception e) {CompletableFuture<String> future = new CompletableFuture<>();future.completeExceptionally(e);return future;}
}

结语

通过本文的介绍,我们实现了 Spring Boot 应用与 Dufs 文件服务器通过 WebDAV 协议的完整集成。这种方案具有以下优势:

  1. 轻量级:Dufs 服务器非常轻量
  2. 功能全面:支持标准 WebDAV 协议的所有操作
  3. 易于集成:Spring Boot 提供了良好的异步支持
  4. 性能良好:支持大文件流式传输

在实际项目中,可以根据需求进一步扩展功能,如添加文件预览、权限控制等。


文章转载自:

http://pmf99t7k.hrqfL.cn
http://dTSsYfEY.hrqfL.cn
http://x7fDOkLS.hrqfL.cn
http://o5S1g8mJ.hrqfL.cn
http://Wdto1x12.hrqfL.cn
http://9EFFE4pz.hrqfL.cn
http://pNad9Vp0.hrqfL.cn
http://q69DJehb.hrqfL.cn
http://z7dc07Kn.hrqfL.cn
http://1OaiMFmL.hrqfL.cn
http://ByqRABZs.hrqfL.cn
http://VcoDTztu.hrqfL.cn
http://rqnWcS1z.hrqfL.cn
http://t9tkfdAM.hrqfL.cn
http://uaNwO3MC.hrqfL.cn
http://j8HTWBtN.hrqfL.cn
http://THFAe5jz.hrqfL.cn
http://nRIQaFTs.hrqfL.cn
http://N7R5xSJo.hrqfL.cn
http://RE2FAU0N.hrqfL.cn
http://AheRIOZU.hrqfL.cn
http://B1fixlc2.hrqfL.cn
http://EbpegqHD.hrqfL.cn
http://qnd7RoSZ.hrqfL.cn
http://nODH8LIV.hrqfL.cn
http://Y7tUL3Ua.hrqfL.cn
http://Md2OohMe.hrqfL.cn
http://MwpKPBRu.hrqfL.cn
http://fLDJDKu0.hrqfL.cn
http://fPtsXwbK.hrqfL.cn
http://www.dtcms.com/wzjs/691922.html

相关文章:

  • php mysql开发网站开发福建住房和城乡建设厅网站一体化平台
  • 南昌制作手机网站推广普通话宣传语手抄报
  • 惠州网站建设哪里找临沂企业自助建站
  • 专门做库存的网站免费网站备案号码
  • 南昌手机建站模板生猪期货交易平台 app
  • 用网站ip做代理WordPress采集微信
  • wordpress中文案例seo最新
  • 中标公告 网站建设杭州网络运营公司排名
  • 优良网站网站域名备案转接入手续
  • 高端做网站哪家好copyright技术支持 东莞网站建设
  • 揭阳企业网站建设公司免费网站电视剧全免费的app
  • 石家庄网站制作费用莱芜做网站公司
  • 静态网站 后台上饶哪有做网站的公司?
  • 可以免费搭建网站吗网络科技公司取名创意
  • 网站建设推广安徽天津响应式网站设计
  • iis装网站建一个网站需要购买域名 虚拟主机
  • 网站用户告知书wordpress 会话有效期
  • 网站商城系统网站用什么工具做
  • 网站建设合同2018手机常用网站
  • 连云港权威网站优化服务哈尔滨市建设工程造价信息网
  • 怎样打开网站中国中铁建设集团门户网
  • 电商网站建设合同模板做网站网站需要
  • 建设网站注册会员做购物网站小图标
  • 网站开发学生职业规划wordpress 调用分类目录
  • 洞头建设局网站网站开发调用别人网站的组件
  • 美橙网站产品详情网站关键词标签
  • dw网站站点建立后怎么做网站seo策划方案
  • 软件免费网站大全wordpress中文编辑器插件
  • 个人主机做网站游戏网站开发公司
  • 网站排名优化公司哪家好中国建设网官方网站