之前已经了解了类目的添加以及重命名,内容的添加以及重命名等,但是没有完成的功能为类目的删除和内容的删除,我们首先需要分析一下我们的业务逻辑:
首先对于内容的删除我们应该使用内容展示中的删除按钮来进行删除,但是当我们需要删除某一个类别时,同时也需要将其目录下的内容一起删除,所以,但我们删除某一个类目时,不仅删除了类目本身,而且还删除了其对应的内容,同时还需要注意的是,我们也要同时删除我们的NGINX图片服务器上相对应的图片,要不然这些图片就一直在服务器上,当删除其对应的链接之后就不会再被访问,成为占用储存的垃圾,所以我们在删除内容的同也希望将图片服务器的图片进行删除。
内容删除:
首先我们来实现内容删除功能,其包括两部分,删除对应数据库中tb_content表中的内容,同时还需要删除对应的nginx服务器上的图片,所以我们先了解一下删除的请求是如何传递的。首先查看content.jsp页面:
可以看到我们需要请求服务的路径,以及前端传递的参数,我们可以发现id为一个数组,传递的id的数量可能不只有一个,所以我们可以将其安装json数据进行传递,传递之后再将其分割,得到每一个id。返回值为:NewstylesResult。
Dao层:
其还是操作的tb_content表格,所以我们可以使用逆向工程生成的代码。
Service层:
@Override public NewstylesResult deleteContentById(String ids){ String a[] =ids.split(","); if(a.length != 0){ for(int i=0;i<a.length;i++){ TbContent tbContent = contentMapper.selectByPrimaryKey(Long.parseLong(ids)); try { pictureService.deleteFilesPic(tbContent.getPic()); pictureService.deleteFilesPic(tbContent.getPic2()); } catch (Exception e) { e.printStackTrace(); } contentMapper.deleteByPrimaryKey(Long.parseLong(ids)); } }else{ return NewstylesResult.build(500,"Misserror"); } return NewstylesResult.ok(); }
可以看到,使用一个String数组来接受参数,同时将其转换为long型整数,便于根据id主键进行查询,同时,在这里进行了删除对应图片的操作:
pictureService.deleteFilesPic(tbContent.getPic()); pictureService.deleteFilesPic(tbContent.getPic2());
可以看到,其属于pictureService实现类中的方法,我们需要在图片服务的业务逻辑中增加这个方法,需要的参数为一个url路径,也即数据库对应字段中的nginx图片服务器请求的路径。在图片删除成功后再去删除这个字段,下面为在PictureServiceImpl中的实现方法:
@Override public boolean deleteFilesPic(String fileUrl) { String[] parmas = pathAndFileName(fileUrl); boolean result = false; if(null != parmas){ result = FtpUtil.deleteFiles(FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD,FTP_BASE_PATH, parmas); } return false; }
可以看到使用了一个pathAndFileName方法,这个方法是用来进行切分url路径的,因为我们的之前生成图片url的策略产生的url样式是固定的,为年月日和随机码,所以我们使用一个方法实现对参数的获取,其中参数4,5,6,7索引的位置的值分别为年月日的分别的文件夹和文件名.jpg:
private String[] pathAndFileName(String url){ //判断是否为空进行处理 if(!url.isEmpty()){ String[] temp = url.split("/"); String[] param = {temp[4],temp[5],temp[6],temp[7]}; return param; } return null; }
在deleteFilePic方法中,同时调用了FtpUtils中的deleteFiles方法,先前我们是没有定义删除的方法的,所以我们在这里重新改动一下FtpUtils类,添加deleteFiles方法,修改之后不要忘了重新install一下common工程(默认FtpUtils类放置在common工程中):
/** * * @param 主机地址 * @param port从端口 * @param username 用户名 * @param password 密码 * @param filePathAndName 文件名 * @return */ public static boolean deleteFiles(String host, int port,String username, String password,String ftpIaseImagePath,String[] filePathAndName){ 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; } String deleteFilepa = null; StringBuffer buffer = new StringBuffer(ftpIaseImagePath); int paraLlength = filePathAndName.length; for(int i = 0; i<paraLlength-1; i++ ){ buffer = buffer.append("/" + filePathAndName[i] ); } deleteFilepa = buffer.toString(); deleteFilesByFtp(ftp,deleteFilepa,filePathAndName[paraLlength-1]); ftp.logout(); result = true; } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return result; } private static int deleteFilesByFtp(FTPClient ftp,String dirPath,String filename) throws Exception{ ftp.changeWorkingDirectory(dirPath); ftp.enterLocalPassiveMode(); FTPFile[] fsL = ftp.listFiles(); int count = fsL.length; if(count >= 1){ for (FTPFile ff : fsL) { if (ff.getName().equals(filename)) { ftp.dele(filename); return count -1; } } } return count; }
在deleteFiles方法中我们抽取公共的操作部分形成了一个新的方法,deleteFileByFtp方法,这个方法进行删除操作并返回删除后的目录底下的文件的数据量。这样,对应图片服务器上的图片也就可以删除了。
同时不要忘了配置一个配置文件,然后将其内容进行获取:
properties文件:
#FTP的选相关配置 #FTP的ip地址 FTP_ADDRESS=192.168.59.128 FTP_PORT=21 FTP_USERNAME=ftpuser FTP_PASSWORD=************** FTP_BASE_PATH=/home/ftpuser/ww/images #图片服务器的相关配置 #服务器的基础的url配置 IMAGE_BASE_URL=http://192.168.59.128/images
内容获取的方式,在ServiceImpl类中使用@Value注解获取对应的值:
@Value("${FTP_ADDRESS}") private String FTP_ADDRESS; @Value("${FTP_PORT}") private Integer FTP_PORT; @Value("${FTP_USERNAME}") private String FTP_USERNAME; @Value("${FTP_PASSWORD}") private String FTP_PASSWORD; @Value("${FTP_BASE_PATH}") private String FTP_BASE_PATH; @Value("${IMAGE_BASE_URL}") private String IMAGE_BASE_URL;
Controller层:
/** * 删除功能 * @param ids 前端传递的参数,包含选择的id值 * @return 返回状态码 */ @RequestMapping(value = "/content/delete") @ResponseBody public NewstylesResult deleteContentById(String ids){ NewstylesResult result = contentService.deleteContentById(ids); return result; }
这样我们测试一下(需要启动Nginx图片服务器):
大广告中有四个内容:
之后查看下我们的首页,对于首页内容的展示请参考前边相应的大广告位展示的内容。
可以看到,我们有四个广告,同时页面的图片能够显示出来。
开始删除相应的内容,删除了广告3:
刷新后首页变成了3个广告。
原来有四个广告,每个广告有两个图片,我们在看一下nginx 服务器上的对应的图片的数量:
可以看到,只有六个图片了。广告位3个位置的图片能够正常显示,说明这个删除结果符合我们的预期,所以,内容删除的工作就完成了,不过不足的是,当我们某个文件夹下面的文件清空时,此文件夹不会被删除,需要有维护人员进行删除。