SpringBoot+SpringSecurity+Maven管理多模块茶园项目

SpringBoot+SpringSecurity+Maven管理多模块茶园项目

一、测试注意事项

1、多项目测试时要注意在不同测试环境中测试

 多模块项目测试时,需要在测试类中添加@SpringBootTest(classes = ConsultingReceptionApplicationTests.class)注解,否则测试可能会报错。

 报错的原因是因为Spring Boot在测试环境中找到了多个@SpringBootConfiguration注解的类。@SpringBootConfiguration是一个特殊的@Configuration,它被用来标记Spring Boot应用程序的主配置类。在一个应用程序中,这个注解应该只出现一次。

 在本项目中,IotPerceptionPlatformApplicationShareCommonApplication这两个类都被标记为了@SpringBootConfiguration,这就导致了冲突。

解决思路:

办法一:你需要确定哪一个类是你的主配置类,并且只在这个类上使用@SpringBootConfiguration。其他的类,如果它们是配置类,你可以使用@Configuration来替代@SpringBootConfiguration

场景一:如果你的share_common模块是一个库模块,而不是一个独立的Spring Boot应用,那么你应该移除ShareCommonApplication类,或者至少移除它的@SpringBootApplication@SpringBootConfiguration注解。这样,它就不会被视为一个独立的Spring Boot应用了。

场景二:如果share_commoniot_perception_platform都是独立的Spring Boot应用,那么你应该将它们分开测试,不要在同一个测试环境中同时运行。如果share_commoniot_perception_platform都是独立的Spring Boot应用,那么你应该分别为它们创建各自的测试环境。这意味着你需要为每个应用创建单独的测试类,并在这些测试类中只加载对应应用的配置

 例如,如果你有一个名为IotPerceptionPlatformTests的测试类,你应该只在这个类中加载IotPerceptionPlatformApplication的配置。你可以通过@SpringBootTest注解的classes属性来实现这一点:

@SpringBootTest(classes = IotPerceptionPlatformApplication.class)
class IotPerceptionPlatformTests {
    // your tests here
}

 同样,你也应该为share_common应用创建一个单独的测试类,比如ShareCommonTests,并在这个类中只加载ShareCommonApplication的配置:

@SpringBootTest(classes = ShareCommonApplication.class)
class ShareCommonTests {
    // your tests here
}

 这样,每个测试类都会在各自的Spring应用上下文中运行,避免了配置类的冲突。

二、上传文件模块的设计

1、上传文件到本地

 将上传的图片保存到本地的某个文件夹下,返回存放路径,这样在数据库中不存储图片数据,而是图片路径。

/**
 * 新增图片
 * @param
 * @return
 */
@ResponseBody
@PostMapping("addAgricultural2")
public String addAgricultural2(@RequestParam("title") String title,
                               @RequestParam("type") String type,
                               @RequestParam("photo") MultipartFile photo,
                               @RequestParam("content") String content){
        String photoPath = storeFile(photo);
        Agricultural article = new Agricultural();
        article.setTitle(title);
        article.setType(type);
        article.setImgUrl(photoPath);
        article.setContent(content);
        agriculturalService.addAgricultural(article);
        return "success";
    }

// 上传文件的核心方法
private String storeFile(MultipartFile file){
        String filename = StringUtils.cleanPath(file.getOriginalFilename());
        try {
            File uploadDirFile = new File(uploadDir);
            if (!uploadDirFile.exists()) {
                uploadDirFile.mkdirs();
            }
            Path targetLocation = Paths.get(uploadDirFile.getAbsolutePath()).resolve(filename);
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, targetLocation, StandardCopyOption.REPLACE_EXISTING);
            }
            return targetLocation.toString();
        } catch (IOException e) {
            throw new RuntimeException("Failed to store file " + filename, e);
        }
    }

 其中,uploadDir是一个存储文件的地址,你可以在pom配置文件中设置这个路径,并在当前类中做如下声明:

@Value("${file.upload-dir}")
private String uploadDir;

 配置文件如下:

# 上传文件配置
file:
  upload-dir: C:/tea_admin_file/

2、上传文件到另一个FTP服务器

相关技术文章:https://zhuanlan.zhihu.com/p/411646279

 如果你想将文件保存到另一个服务器,你需要使用一种方法来将文件传输到那个服务器。这可能涉及到网络编程,例如使用FTP(文件传输协议)或SFTP(SSH文件传输协议)等。

 这个问题的解决方案超出了简单的代码修改的范围,因为你需要在两台服务器之间建立一种文件传输机制。这可能需要你在目标服务器上运行一个FTP或SFTP服务器,然后在你的Spring Boot应用中使用一个FTP或SFTP客户端库来上传文件。

 本项目使用FTP。

 那么你需要确保你的项目已经正确地引入了Apache Commons Net库。你可以通过以下步骤来添加这个库:

 1、如果你的项目是Maven项目,你可以在你的pom.xml文件中添加以下依赖:

xmlCopy code<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.8.0</version> <!-- 请使用最新的版本 -->
</dependency>

 2、这是一个使用Apache Commons Net库的FTP客户端示例:

FTPClient ftpClient = new FTPClient();
try {
    ftpClient.connect("your.server.ip", 21);
    ftpClient.login("username", "password");
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

    String remoteFile = "/tea_admin_file/" + filename;
    InputStream inputStream = file.getInputStream();
    boolean done = ftpClient.storeFile(remoteFile, inputStream);
    inputStream.close();
    if (done) {
        System.out.println("The file is uploaded successfully.");
    }
} catch (IOException ex) {
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
} finally {
    try {
        if (ftpClient.isConnected()) {
            ftpClient.logout();
            ftpClient.disconnect();
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

 请注意,你需要将"your.server.ip"、"username"和"password"替换为你的FTP服务器的实际IP地址和登录凭据。此外,你可能需要根据你的FTP服务器的配置调整端口号(在这个例子中是21)。

 这只是一个基本的示例,你可能需要根据你的具体需求进行调整。例如,你可能需要处理连接失败的情况,或者在上传文件后验证文件是否已成功上传。

 请注意,FTP协议不加密传输的数据,如果你需要传输敏感数据或者在公共网络上传输数据,你应该使用SFTP或其他安全的文件传输协议。

(1)在目标服务器上运行一个FTP或SFTP服务器

 在目标服务器上运行FTP服务器的步骤会根据你的操作系统和选择的FTP服务器软件有所不同。以下是在Windows和Linux上设置FTP服务器的一般步骤:

  1. Windows:
    • 你可以使用Windows内置的IIS(Internet Information Services)来设置FTP服务器。以下是设置步骤:
      • 打开“控制面板” -> “程序” -> “打开或关闭Windows功能”。
      • 在弹出的窗口中,找到并展开“Internet Information Services”。
      • 展开“FTP服务器”,然后选中“FTP服务”。
      • 点击“确定”开始安装FTP服务。
      • 安装完成后,打开IIS管理器,然后在左侧的连接面板中,右键点击你的计算机名,选择“添加FTP站点”来创建一个新的FTP站点。
      • 按照向导的提示设置FTP站点的名称、路径、绑定和SSL设置、身份验证和授权等。
  2. Linux:
    • 在Linux上,有许多可用的FTP服务器软件,如vsftpd、ProFTPD和Pure-FTPd等。以下是使用vsftpd设置FTP服务器的步骤:
      • 首先,你需要安装vsftpd。在基于Debian的系统上,可以使用sudo apt-get install vsftpd命令来安装。在基于RPM的系统上,可以使用sudo yum install vsftpd命令来安装。
      • 安装完成后,打开vsftpd的配置文件(通常位于/etc/vsftpd/vsftpd.conf)进行编辑。
      • 在配置文件中,你可以设置如匿名访问、本地用户访问、chroot环境、传输速度限制等各种选项。
      • 编辑完成后,保存并关闭配置文件,然后重启vsftpd服务以应用新的配置。你可以使用sudo systemctl restart vsftpd命令来重启服务。

 请注意,FTP协议不加密传输的数据,如果你需要传输敏感数据或者在公共网络上传输数据,你应该使用SFTP或其他安全的文件传输协议。此外,你还需要在防火墙中打开FTP服务所使用的端口(默认为21),并确保你的网络设置允许FTP连接。

 在设置FTP服务器时,你应该始终考虑到安全性。至少,你应该禁用匿名访问,并为每个FTP用户设置强密码。你还应该限制每个用户可以访问的目录,并定期检查和更新你的FTP服务器软件以获取最新的安全更新。

设置FTP站点的信息

 在Windows的IIS中设置FTP站点的步骤如下:

  1. FTP站点名称:在创建FTP站点的向导中,你会看到一个名为“FTP站点名称”的字段,你可以在这里输入你的FTP站点的名称。
  2. 内容目录:在“内容目录”部分,你需要提供FTP站点的本地路径。这是FTP用户将访问的目录。
  3. 绑定和SSL:在“绑定和SSL设置”部分,你需要设置FTP站点的IP地址和端口(默认为21)。你还可以选择是否启用SSL。如果你选择启用SSL,你需要提供一个SSL证书。
  4. 身份验证:在“身份验证”部分,你可以选择允许哪些类型的用户访问你的FTP站点。你可以选择“匿名”(任何人都可以访问),“基本”(需要用户名和密码),或者两者都选。
  5. 授权:在“授权”部分,你可以设置哪些用户或用户组可以访问FTP站点,以及他们的权限(如读取、写入等)。

 完成以上设置后,点击“完成”按钮创建FTP站点。创建完成后,你可以在IIS管理器中看到你的FTP站点,并可以对其进行管理。

 请注意,以上步骤可能会根据你的Windows版本和IIS版本有所不同。你应该参考你的系统和IIS的具体文档来进行设置。

配置防火墙:只允许FTP服务器端的端口通过防火墙

在Windows服务器上,你可以通过以下步骤来在防火墙中打开FTP服务所使用的端口:

  1. 打开"控制面板"。你可以通过在开始菜单中搜索"控制面板"来打开它。
  2. 在控制面板中,点击"系统和安全"。
  3. 在"系统和安全"页面,点击"Windows Defender防火墙"。
  4. 在"Windows Defender防火墙"页面,点击左侧的"高级设置"。
  5. 在"Windows Defender防火墙高级设置"窗口,点击左侧的"入站规则"。
  6. 在右侧的操作区域,点击"新建规则..."。
  7. 在"新建入站规则"向导中,选择"端口",然后点击"下一步"。
  8. 输入你需要打开的端口号(FTP默认端口为21),然后点击"下一步"。
  9. 选择"允许连接",然后点击"下一步"。
  10. 保持默认设置(即在所有配置文件中启用此规则),然后点击"下一步"。
  11. 输入一个名称和描述(例如,"FTP"),然后点击"完成"。

这样,FTP服务所使用的端口就在防火墙中打开了。

另外,你还需要确保你的网络设置允许FTP连接。这通常涉及到你的路由器或者云服务提供商的设置。你可能需要在路由器或者云服务提供商的控制面板中,将FTP端口(默认为21)转发到你的服务器的IP地址。具体的步骤会根据你的路由器或者云服务提供商的具体模型和设置有所不同。

关于某些问题的解决技术文章

打开ftp服务器上的文件夹发生错误 请检查是否有权向访问该文件夹

https://blog.csdn.net/qq_36279445/article/details/115672101

如果还是没解决,那就把防火墙关了,就解决了。

3、其他问题

文件过大会报错

 因为Spring Boot默认的文件上传大小限制。默认情况下,Spring Boot限制上传文件的大小为10MB。你可以通过在你的application.propertiesapplication.yml文件中设置以下属性来提高这个限制:

# For Spring Boot 2.x
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB

# For Spring Boot 1.x
spring.http.multipart.max-file-size=100MB
spring.http.multipart.max-request-size=100MB

 这里的100MB是示例值,你可以根据你的需求设置合适的值。这些属性的值可以是字节(B)、千字节(KB)、兆字节(MB)或吉字节(GB),例如128KB12MB1GB

 注意:这些设置只会影响Spring MVC处理的文件上传,如果你使用Tomcat作为你的服务器,你可能还需要在application.propertiesapplication.yml文件中设置以下属性:

server.tomcat.max-http-post-size=100MB
server.tomcat.max-swallow-size=100MB

这些设置将会提高Tomcat服务器接受的POST请求的最大大小。

在你修改了这些设置后,你需要重启你的应用程序来使这些设置生效。

4、其他功能

(1)文件重命名后存到FTP服务器

你可以在你的storeFile2方法中修改文件名。例如,你可以在上传文件之前添加一个时间戳到文件名,这样每个上传的文件都会有一个唯一的文件名。这是一个示例:

private String storeFile2(MultipartFile file){
    String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());
    String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
    String filename = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + extension;

    // ... 其他代码不变 ...

    String remoteFile = "/tea_admin_file/" + filename;
    InputStream inputStream = file.getInputStream();
    boolean done = ftpClient.storeFile(remoteFile, inputStream);

    // ... 其他代码不变 ...

    return filename;
}

 在这个示例中,我首先获取了原始文件名的扩展名,然后创建了一个新的文件名,这个文件名是当前的时间(格式为yyyyMMddHHmmss)加上原始文件名的扩展名。然后我使用这个新的文件名来上传文件。

 这样,每个上传的文件都会有一个唯一的文件名,即使原始文件名相同,上传的文件也不会被覆盖。

(2)下载文件

你可以使用FTPClientretrieveFile方法来下载文件。以下是一个基本的示例:

private void downloadFile(String filename, HttpServletResponse response){
    FTPClient ftpClient = new FTPClient();
    try {
        ftpClient.connect("192.168.10.61", 21);
        ftpClient.login("jinzunyue", "111");
        ftpClient.enterLocalPassiveMode();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

        String remoteFile = "/tea_admin_file/" + filename;
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        boolean success = ftpClient.retrieveFile(remoteFile, outputStream);
        outputStream.close();

        if (success) {
            System.out.println("File #1 has been downloaded successfully.");
        }
    } catch (IOException ex) {
        System.out.println("Error: " + ex.getMessage());
        ex.printStackTrace();
    } finally {
        try {
            if (ftpClient.isConnected()) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

 在这个示例中,我首先设置了HTTP响应的内容类型为application/octet-stream,这意味着我们将发送一个二进制文件。然后,我设置了Content-Disposition头,这将告诉浏览器这是一个需要下载的文件,并提供了文件的名称。

 然后,我创建了一个输出流,这个输出流将写入HTTP响应的内容。我使用FTPClientretrieveFile方法将文件下载到这个输出流中。最后,我关闭了输出流。

 如果文件下载成功,我将在控制台打印一条消息。如果在下载文件时发生错误,我将打印错误消息和堆栈跟踪。

 请注意,这个示例假设你有一个HttpServletResponse对象,你可以在你的控制器方法中获取这个对象。如果你的方法没有HttpServletResponse参数,你可能需要修改你的方法以接收这个参数。

(3)nginx代理加载图片

nginx配合FTP,返回前端可加载的图片

 你的代码已经将文件上传到了FTP服务器上,这部分不需要改变。你需要做的是在你的Nginx服务器上配置一个代理,将请求转发到FTP服务器上的文件。

1、首先,你需要在你的Nginx服务器上安装和配置Nginx。你可以在Nginx的官方网站上找到安装和配置的详细指南。

2、然后,你需要在Nginx的配置文件中添加一个新的location块,将请求转发到FTP服务器上的文件。这个location块应该类似于以下的形式:

location /images/ {
    alias /path/to/your/ftp/directory/;
    autoindex on;
}

 在这个配置中,/images/是你的前端应用程序将用来访问图片的URL路径,/path/to/your/ftp/directory/是你的FTP服务器上存储图片的目录。

3、保存你的Nginx配置文件,然后重启Nginx服务。

 现在,你的前端应用程序应该可以通过URL http://your-nginx-server.com/images/your-image.jpg 来访问FTP服务器上的图片了。

 注意:这个配置假设你的Nginx服务器可以直接访问FTP服务器上的文件系统。如果不是这样,你可能需要在Nginx服务器上挂载FTP服务器的文件系统,或者使用其他的方法来让Nginx服务器能够访问FTP服务器上的文件。这可能需要更复杂的配置,并且超出了这个问题的范围。

 你可以使用Nginx作为反向代理服务器,将前端的请求转发到FTP服务器。这样,前端只需要知道Nginx服务器的地址,就可以获取到FTP服务器上的图片。

 以下是一个基本的Nginx配置示例,它将所有来自/images/路径的请求转发到FTP服务器:

server {
    listen 80;
    server_name your-server-name;

    location /images/ {
        proxy_pass ftp://192.168.10.61:21/tea_admin_file/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

 在这个配置中,proxy_pass指令告诉Nginx将请求转发到FTP服务器。proxy_set_header指令设置了转发请求的HTTP头。

 请注意,你需要将your-server-name替换为你的Nginx服务器的名称或IP地址,将192.168.10.6121替换为你的FTP服务器的IP地址和端口,将/tea_admin_file/替换为你的FTP服务器上的图片目录。

 然后,你可以在前端使用如下的URL来获取图片:

http://your-server-name/images/your-image.jpg

 在这个URL中,your-server-name是你的Nginx服务器的名称或IP地址,/images/是你在Nginx配置中设置的路径,your-image.jpg是你要获取的图片的名称。

 请注意,FTP协议并不是为HTTP代理设计的,因此这种方法可能会有一些限制。例如,FTP协议不支持部分内容请求,这可能会影响到大文件的下载和视频的流式传输。如果可能,你可能会考虑使用HTTP或HTTPS协议来提供你的图片。

(4)关于nginx代理时FTP的身份验证

 FTP服务器的身份验证可能会使事情变得更复杂。Nginx本身并不支持直接代理到需要身份验证的FTP服务器。你可能需要一个可以处理FTP身份验证的中间件。

 一种可能的解决方案是使用一个可以处理FTP身份验证的反向代理服务器,如Squid,然后将Nginx配置为将请求转发到Squid。然而,这可能需要更复杂的配置,并可能超出了你的需求范围。

 另一种可能的解决方案是将FTP服务器上的文件同步到一个HTTP或HTTPS服务器上,然后使用Nginx代理到该HTTP/HTTPS服务器。这可以通过使用如rsync或lftp等工具来定期从FTP服务器下载文件来实现。

 最后,如果你控制FTP服务器,并且对谁可以访问这些文件没有严格的安全要求,你可能会考虑配置FTP服务器允许匿名访问。这样,你就可以直接使用Nginx代理到FTP服务器,而无需处理身份验证。然而,这可能会使你的文件对任何知道URL的人都可访问,这可能不是你想要的。

 总的来说,我建议你考虑将文件存储在一个设计用于Web访问的服务器上,如HTTP或HTTPS服务器,而不是FTP服务器。这将使得代理和身份验证等问题更容易处理。

(5)使用SMB上传文件到Nginx服务器

 在Windows环境下,你可以使用SMB(Server Message Block)协议来共享文件。SMB是一种网络文件共享协议,允许计算机之间通过网络共享文件和打印机。

 以下是配置步骤:

  1. 在你的Nginx服务器上,选择你想要共享的文件夹,右键点击选择"Properties"(属性)。
  2. 在弹出的窗口中,选择"Sharing"(共享)标签,然后点击"Advanced Sharing..."(高级共享)。
  3. 在新的窗口中,勾选"Share this folder"(共享此文件夹),然后点击"Permissions"(权限)。
  4. 在权限窗口中,你可以设置哪些用户或用户组可以访问这个共享文件夹。如果你想让所有人都可以访问,你可以添加"Everyone"(所有人)用户组,并给予它"Full Control"(完全控制)权限。
  5. 点击"OK"确认设置,然后关闭所有窗口。

 现在,你的Nginx服务器上的文件夹已经被共享出去了,你的Spring Boot应用所在的服务器可以通过网络路径访问这个文件夹。

 在Spring Boot应用中,你可以像访问本地文件夹一样访问这个网络文件夹。例如,如果你的Nginx服务器的IP地址是192.168.10.61,你共享的文件夹名是"tea_admin_file",那么你可以通过"\192.168.10.61\tea_admin_file"这个路径来访问这个文件夹。

 注意,如果你的Spring Boot应用所在的服务器和Nginx服务器不在同一个局域网内,你可能需要在你的网络设备(如路由器)上设置端口转发,以便Spring Boot应用能够访问到Nginx服务器。此外,由于网络文件共享可能会带来安全风险,你应该确保你的网络设置是安全的,例如使用VPN或其他安全措施保护你的网络通信。

 如果你在浏览器中输入192.168.10.61\http,浏览器会将其解析为URL,而不是文件系统路径。在这种情况下,你需要使用HTTP协议(即http://)而不是文件系统路径。

 如果你的Nginx服务器配置正确,并且正在运行,你应该可以通过在浏览器中输入http://192.168.10.61/来访问Nginx服务器的主页。如果你的文件存储在Nginx服务器的D:\Temp\http目录下,你需要在Nginx的配置文件中设置一个location,将URL路径映射到这个目录。例如:

server {
    listen 80;
    server_name 192.168.10.61;

    location / {
        root D:/Temp/http;
    }
}

 这样,当你访问http://192.168.10.61/filename时,Nginx会在D:\Temp\http目录下查找filename文件。

 然后,你可以在Spring Boot应用中使用Java的java.net.URLjava.nio.file.Files类,将文件上传到这个URL。例如:

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileUploadExample {

    public static void main(String[] args) {
        // 本地文件路径
        Path localFilePath = Paths.get("C:/path/to/local/file.txt");

        // Nginx服务器的URL
        String remoteUrl = "http://192.168.10.61/";

        // 在URL中创建一个与本地文件同名的文件路径
        String remoteFilePath = remoteUrl + localFilePath.getFileName();

        try {
            // 创建一个指向远程文件的URL对象
            URL url = new URL(remoteFilePath);

            // 打开一个到URL的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // 设置连接为输出模式
            conn.setDoOutput(true);

            // 设置请求方法为PUT
            conn.setRequestMethod("PUT");

            // 获取连接的输出流
            OutputStream out = conn.getOutputStream();

            // 将本地文件的内容写入输出流,即上传到远程服务器
            Files.copy(localFilePath, out);

            // 关闭输出流
            out.close();

            // 获取并打印服务器的响应码
            int responseCode = conn.getResponseCode();
            System.out.println("Server responded with: " + responseCode);

        } catch (IOException e) {
            System.out.println("Failed to upload file: " + e.getMessage());
        }
    }
}

 注意,这个示例假设你的Nginx服务器配置为接受PUT请求来上传文件。这通常需要额外的模块,例如WebDAV模块,并且可能需要额外的安全配置。如果你的服务器不支持PUT请求,你可能需要使用其他方法来上传文件,例如FTP或SFTP。

(6)用户上传的内容包含文字和图片

 如果你的内容中包含图片,那么你可能需要使用一种富文本编辑器,如CKEditor或TinyMCE。这些编辑器允许用户在文本中插入图片,并生成HTML代码,你可以将这个HTML代码保存到数据库中。

 当你需要显示这个内容时,你只需要将这个HTML代码插入到你的页面中。这样,图片就会在文本中正确地显示出来。

以下是一个简单的例子:

Model

@Entity
public class Content {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;

    @Lob
    private String htmlContent; // 用于存储HTML代码

    // getters and setters
}

Controller

@Controller
public class ContentController {
    @Autowired
    private ContentRepository contentRepository;

    @PostMapping("/content")
    public String addContent(@RequestParam("htmlContent") String htmlContent) {
        Content content = new Content();
        content.setHtmlContent(htmlContent);
        contentRepository.save(content);
        return "redirect:/content";
    }
}

View

<!-- 引入CKEditor或TinyMCE的JavaScript库 -->
<script src="https://cdn.ckeditor.com/4.14.0/standard/ckeditor.js"></script>

<form method="post" action="/content">
    <textarea name="htmlContent" id="editor"></textarea>
    <input type="submit" value="Add Content">
</form>

<script>
    // 初始化富文本编辑器
    CKEDITOR.replace('editor');
</script>

 请注意,这只是一个基本的例子,你可能需要根据你的具体需求进行调整。例如,你可能需要配置富文本编辑器,以允许用户上传图片到你的服务器,或者使用一些特定的样式和格式。

(7)删除图片

 在你的代码中,你使用了FTPClient来上传文件。如果你想删除文件,你可以使用FTPClient的deleteFile(String pathname)方法。这个方法接受一个字符串参数,这个参数是你想删除的文件的路径名。如果文件成功删除,这个方法会返回true,否则返回false

 下面是一个示例代码,展示了如何使用FTPClient来删除文件:

public static boolean deleteFile(String filename) {
    FTPClient ftpClient = new FTPClient();
    try {
        ftpClient.connect("192.168.10.61", 21);
        ftpClient.login("jinzunyue", "111");
        ftpClient.enterLocalPassiveMode();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

        String remoteFile = "/tea_admin_file/" + filename;
        boolean done = ftpClient.deleteFile(remoteFile);
        if (!done) {
            System.out.println("The file deletion failed.");
            System.out.println("Server reply: " + ftpClient.getReplyString());
        } else {
            System.out.println("The file is deleted successfully.");
        }
        return done;
    } catch (IOException ex) {
        System.out.println("Error: " + ex.getMessage());
        ex.printStackTrace();
        return false;
    } finally {
        try {
            if (ftpClient.isConnected()) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

你可以调用这个方法来删除文件,例如:

deleteFile("myFile.txt");

这将删除FTP服务器上的/tea_admin_file/myFile.txt文件。

 请注意,这个方法只会删除FTP服务器上的文件,不会删除任何在你的Spring Boot应用服务器上的文件。如果你也在你的Spring Boot应用服务器上存储了文件的副本,你需要使用Java的File类来删除那些文件。

(8)从图片URL中获取图片名

图片URL是如下格式"http://192.168.10.61:8089/images/"+filename;''

如果你只想获取文件名,你可以使用Java的java.net.URL类来解析URL并获取文件名。下面是一个示例:

import java.net.URL;

public static String getFilenameFromUrl(String url) {
    try {
        URL urlObj = new URL(url);
        String path = urlObj.getPath();
        return path.substring(path.lastIndexOf('/') + 1);
    } catch (Exception e) {
        System.out.println("Error: " + e.getMessage());
        e.printStackTrace();
        return null;
    }
}

你可以使用这个方法来从URL中获取文件名,例如:

String filename = getFilenameFromUrl("http://192.168.10.61:8089/images/myFile.txt");

这将返回myFile.txt

然后,你可以使用这个文件名来删除FTP服务器上的文件。例如:

deleteFile(filename);

这将删除FTP服务器上的/tea_admin_file/myFile.txt文件。

(9)删除json格式传过来的图片URL

看起来你正在尝试将一个JSON字符串作为URL解析,这就是为什么你会看到java.net.MalformedURLException: no protocol错误。

在你的代码中,你需要确保你正在传递的是一个有效的URL字符串,而不是一个包含URL的JSON字符串。你需要先从JSON字符串中提取出URL,然后再传递给getFilenameFromUrl方法。

如果你的URL是在JSON字符串中,你可能需要使用一个JSON解析库,如Jackson或Gson,来解析JSON并获取URL。例如:

import com.fasterxml.jackson.databind.ObjectMapper;

// ...

String json = "{ \"photo\":\"http://192.168.10.61:8089/images/20230609161001.jpg\" }";

ObjectMapper mapper = new ObjectMapper();
Map<String, String> map = mapper.readValue(json, Map.class);

String url = map.get("photo");
String filename = getFilenameFromUrl(url);

这样,你就可以从JSON字符串中提取出URL,并从URL中获取文件名了。

(10)删除Json格式传过来的图片数组

 你可以将你的方法参数类型改为Map<String, List<String>>,这样你就可以直接从Map中获取你的数组了。这是一个例子:

@ResponseBody
@PostMapping("deletePhotos")
public Object deletePhotos(@RequestBody Map<String, List<String>> payload) throws JsonProcessingException {
    List<String> photos = payload.get("photos");
    for (String photo : photos) {
        String filename = FileUtils.getFilenameFromUrl(photo);
        if(!FileUtils.deleteFile(filename)){
            return "删除失败,失败的文件名:" + filename;
        }
    }
    return "全部删除成功";
}

 在这个例子中,payload是一个Map,它的键是字符串,值是字符串列表。你可以使用payload.get("photos")来获取photos数组。这个方法期望接收的请求体应该是一个包含photos数组的JSON对象,如下所示:

jsonCopy code{
    "photos": [
        "http://example.com/image1.jpg",
        "http://example.com/image2.jpg"
    ]
}

这样,你就不需要创建一个新的类来表示请求体了。

posted @ 2023-06-20 19:15  钱有学  阅读(202)  评论(0)    收藏  举报