基于SpringBoot从零构建博客网站 - 设计可扩展上传模块和开发修改头像密码功能

上传模块在web开发中是很常见的功能也是很重要的功能,在web应用中需要上传的可以是图片、pdf、压缩包等其它类型的文件,同时对于图片可能需要回显,对于其它文件要能够支持下载等。在守望博客系统中对于上传模块进行统一管理,同时对于上传不同的类型文件,留有自定义实现机制的接口,也即可扩展。

基于上传模块机制,就可以实现修改头像功能了。同时顺带将修改密码的功能也一起实现,这个修改密码的功能相对就很简单了。

1、可扩展上传模块

统一上传模块的体现就是上传所有类型的文件,都是调用统一的一个接口,即上传接口唯一;同时对于具体上传的类型文件,如有特殊处理的可以自定义实现处理方法。

对于上传的文件能够有自定义的实现机制,则需要一个上传文件的处理接口,即:IUploadHandler,内容如下:

/** * 上传文件处理接口类 * * @author lzj * @since 1.0 * @date [2019-07-09] */ public interface IUploadHandler { /** * 上传文件处理方法 * 文件上传成功,返回文件的相关信息 * 文件上传失败, 返回null * * @param file * @param distType * @param userId * @return * @throws Exception */ public Object upload(MultipartFile file, String distType, String userId) throws Exception; /** * 下载文件 * * @param fileId * @param response * @throws Exception */ public void download(String fileId, HttpServletResponse response) throws Exception; /** * 根据条件列出文件信息 * * @param distType * @param userId * @return * @throws Exception */ public Object list(String distType, String userId) throws Exception; }

目前本版本中暂定有3个方法,即:

upload方法,用于处理自定义上传文件方式;

download方法,用于处理自定义下载的方式;

list方法,用于处理自定义列出文件列表的方式。

这里以上传头像图片为例,则上传头像的实现类UploadAvatarHandler,内容如下:

/** * 上传头像处理类 * * @author lzj * @since 1.0 * @date [2019-07-09] */ @Slf4j @Component("_avatar") public class UploadAvatarHandler implements IUploadHandler { @Autowired private IUserService userService; @Resource(name = "configCache") private ICache<Config> configCache; @Override public Object upload(MultipartFile file, String distType, String userId) throws Exception { Map<String, Object> result = new HashMap<String, Object>(); try { // 获取图片的大小 long fileSize = file.getSize(); // 图片大小不能超过2M, 2M = 2 * 1024 * 1024B = 2097152B if (fileSize > 2097152L) { throw new TipException("您上传的图片超过2M"); } Config config = configCache.get(Config.CONFIG_IMG_AVATAR_PATH); // 保存头像的根目录 String basePath = config.getConfigValue(); if (!basePath.endsWith("http://www.likecs.com/")) { basePath += "http://www.likecs.com/"; } // 根据当前时间构建yyyyMM的文件夹,建立到月的文件夹 String dateDirName = DateUtil.date2Str(new Date(), DateUtil.YEAR_MONTH_FORMAT); basePath += dateDirName; File imageDir = new File(basePath); if (!imageDir.exists()) { imageDir.mkdirs(); } String fileNewName = IdGenarator.guid() + ".jpg"; FileUtil.copy(file.getInputStream(), new FileOutputStream(new File(imageDir, fileNewName))); // 获取用户信息 User user = userService.getById(userId); user.setPicture(dateDirName + "http://www.likecs.com/" + fileNewName); // 更新信息 userService.updateById(user); result.put("success", true); result.put("msg", "上传头像成功"); } catch (TipException e) { result.put("success", false); result.put("msg", e.getMessage()); } catch (Exception e) { log.error("上传头像失败", e); result.put("success", false); result.put("msg", "上传头像失败"); } return result; } @Override public void download(String fileId, HttpServletResponse response) throws Exception { } @Override public Object list(String distType, String userId) throws Exception { return null; }

这里有2个注意点,即这个@Component("_avatar"),这个类的名称最好自定义命名,最好以处理这种文件的类型为名,例如此处的是处理头像的,所以就是avatar,但是为了防止重名,所以前缀加上了下划线。

另外一个需要注意的就是,并不是所有的方法都需要实现,例如此处就没有实现download和list方法,因为头像图片不是通过流的方式回显的,而是直接通过映射到具体的图片,同时也是不需要列出头像的功能。

前面说过所有上传文件,都是调用统一的一个接口,也即是UploadController,内容如下:

/** * 处理文件上传下载控制器类 * * @author lzj * @date [2019-07-09] * @since 1.0 */ @Slf4j @Controller public class UploadController { @Autowired private ApplicationContext context; // 用于存储处理上传文件对象 private Map<String, IUploadHandler> uploadHandlers; /** * 初始化操作 * * @throws Exception */ @PostConstruct public void init() throws Exception { uploadHandlers = context.getBeansOfType(IUploadHandler.class); } /** * 上传文件 * * @param file * @param request * @param session * @return */ @RequestMapping(value = "/upload", method = RequestMethod.POST) @ResponseBody public Object upload(@RequestParam(value = "_uploadFile", required = false) MultipartFile file, HttpServletRequest request, HttpSession session) { Object result = null; try { // 接收参数 // 获取上传文件类型,参数名为_fileType String _distType = request.getParameter("_distType"); // 获取用户信息 User user = (User) session.getAttribute(Const.SESSION_USER); result = uploadHandlers.get(_distType).upload(file, _distType, user.getUserId()); } catch (Exception e) { log.error("上传文件失败", e); } return result; } }

这里需要注意init方法,该方法会将IUploadHandler接口的实现类都扫描出来,同时以类名为key,实例为value返回。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdgwz.html